Be more consistent in the naming convention for the various RET instructions to specify in terms of bitwidth. Helps prevent future scheduler model mismatches like those that were only addressed in D44687. Differential Revision: https://reviews.llvm.org/D113302
153 lines
4.1 KiB
YAML
153 lines
4.1 KiB
YAML
# RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass x86-fixup-bw-insts %s -o - | FileCheck %s
|
|
|
|
--- |
|
|
define void @test1() { ret void }
|
|
define void @test2() { ret void }
|
|
|
|
define i16 @test3(i16* readonly %p) {
|
|
; Keep original IR to show how the situation like this might happen
|
|
; due to preceding CG passes.
|
|
;
|
|
; %0 is used in %if.end BB (before tail-duplication), so its
|
|
; corresponding super-register (EAX) is live-in into that BB (%if.end)
|
|
; and also has an implicit-def EAX flag. Make sure that we still change
|
|
; the movw into movzwl because EAX is not live before the load (which
|
|
; can be seen by the fact that implicit EAX flag is missing).
|
|
entry:
|
|
%tobool = icmp eq i16* %p, null
|
|
br i1 %tobool, label %if.end, label %if.then
|
|
|
|
if.then: ; preds = %entry
|
|
%0 = load i16, i16* %p, align 2
|
|
br label %if.end
|
|
|
|
if.end: ; preds = %if.then, %entry
|
|
%i.0 = phi i16 [ %0, %if.then ], [ 0, %entry ]
|
|
ret i16 %i.0
|
|
}
|
|
|
|
define i16 @test4() {
|
|
entry:
|
|
%t1 = zext i1 undef to i16
|
|
%t2 = or i16 undef, %t1
|
|
ret i16 %t2
|
|
}
|
|
|
|
define void @test5() {ret void}
|
|
|
|
...
|
|
---
|
|
# CHECK-LABEL: name: test1
|
|
name: test1
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
liveins:
|
|
- { reg: '$rax' }
|
|
# Verify that "movw ($rax), $ax" is changed to "movzwl ($rax), $rax".
|
|
#
|
|
# For that to happen, the liveness information after the MOV16rm
|
|
# instruction should be used, not before it because $rax is live
|
|
# before the MOV and is killed by it.
|
|
body: |
|
|
bb.0:
|
|
liveins: $rax
|
|
|
|
$ax = MOV16rm killed $rax, 1, $noreg, 0, $noreg
|
|
; CHECK: $eax = MOVZX32rm16 killed $rax
|
|
|
|
RET64 $ax
|
|
|
|
...
|
|
---
|
|
# CHECK-LABEL: name: test2
|
|
name: test2
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
liveins:
|
|
- { reg: '$rax' }
|
|
# Imp-use of any super-register means the register is live before the MOV
|
|
body: |
|
|
bb.0:
|
|
liveins: $dl, $rbx, $rcx, $r14
|
|
|
|
$cl = MOV8rr killed $dl, implicit killed $rcx, implicit-def $rcx
|
|
; CHECK: $cl = MOV8rr killed $dl, implicit killed $rcx, implicit-def $rcx
|
|
JMP_1 %bb.1
|
|
bb.1:
|
|
liveins: $rcx
|
|
|
|
RET64 $cl
|
|
|
|
...
|
|
---
|
|
# CHECK-LABEL: name: test3
|
|
name: test3
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
liveins:
|
|
- { reg: '$rdi' }
|
|
# After MOV16rm the whole $eax is not *really* live, as can be seen by
|
|
# missing implicit-uses of it in that MOV. Make sure that MOV is
|
|
# transformed into MOVZX.
|
|
# See the comment near the original IR on what preceding decisions can
|
|
# lead to that.
|
|
body: |
|
|
bb.0.entry:
|
|
successors: %bb.1(0x30000000), %bb.2.if.then(0x50000000)
|
|
liveins: $rdi
|
|
|
|
TEST64rr $rdi, $rdi, implicit-def $eflags
|
|
JCC_1 %bb.1, 4, implicit $eflags
|
|
|
|
bb.2.if.then:
|
|
liveins: $rdi
|
|
|
|
$ax = MOV16rm killed $rdi, 1, $noreg, 0, $noreg, implicit-def $eax :: (load (s16) from %ir.p)
|
|
; CHECK: $eax = MOVZX32rm16 killed $rdi, 1, $noreg, 0, $noreg, implicit-def $eax :: (load (s16) from %ir.p)
|
|
$ax = KILL $ax, implicit killed $eax
|
|
RET64 $ax
|
|
|
|
bb.1:
|
|
$eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
|
|
$ax = KILL $ax, implicit killed $eax
|
|
RET64 $ax
|
|
|
|
...
|
|
---
|
|
# CHECK-LABEL: name: test4
|
|
name: test4
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
liveins:
|
|
- { reg: '$r9d' }
|
|
# This code copies r10b into r9b and then uses r9w. We would like to promote
|
|
# the copy to a 32-bit copy, but because r9w is used this is not acceptable.
|
|
body: |
|
|
bb.0.entry:
|
|
liveins: $r9d
|
|
|
|
$r9b = MOV8rr undef $r10b, implicit-def $r9d, implicit killed $r9d, implicit-def $eflags
|
|
; CHECK: $r9b = MOV8rr undef $r10b, implicit-def $r9d, implicit killed $r9d, implicit-def $eflags
|
|
|
|
$ax = OR16rr undef $ax, $r9w, implicit-def $eflags
|
|
RET64 $ax
|
|
|
|
...
|
|
---
|
|
# CHECK-LABEL: name: test5
|
|
name: test5
|
|
alignment: 16
|
|
tracksRegLiveness: true
|
|
liveins:
|
|
- { reg: '$ch', reg: '$bl' }
|
|
body: |
|
|
bb.0:
|
|
liveins: $ch, $bl
|
|
|
|
$cl = MOV8rr $bl, implicit-def $cx, implicit killed $ch, implicit-def $eflags
|
|
; CHECK: $cl = MOV8rr $bl, implicit-def $cx, implicit killed $ch, implicit-def $eflags
|
|
|
|
RET64 $cx
|
|
|
|
...
|