Home | History | Annotate | Download | only in X86
      1 # RUN: llc -mtriple=x86_64-unknown-linux-gnu -run-pass x86-fixup-bw-insts %s -o - | FileCheck  %s
      2 
      3 --- |
      4   define void @test1() { ret void }
      5   define void @test2() { ret void }
      6 
      7   define i16 @test3(i16* readonly %p) {
      8   ; Keep original IR to show how the situation like this might happen
      9   ; due to preceding CG passes.
     10   ;
     11   ; %0 is used in %if.end BB (before tail-duplication), so its
     12   ; corresponding super-register (EAX) is live-in into that BB (%if.end)
     13   ; and also has an implicit-def EAX flag. Make sure that we still change
     14   ; the movw into movzwl because EAX is not live before the load (which
     15   ; can be seen by the fact that implicit EAX flag is missing).
     16   entry:
     17     %tobool = icmp eq i16* %p, null
     18     br i1 %tobool, label %if.end, label %if.then
     19 
     20   if.then:                                          ; preds = %entry
     21     %0 = load i16, i16* %p, align 2
     22     br label %if.end
     23 
     24   if.end:                                           ; preds = %if.then, %entry
     25     %i.0 = phi i16 [ %0, %if.then ], [ 0, %entry ]
     26     ret i16 %i.0
     27   }
     28 
     29   define i16 @test4() {
     30   entry:
     31     %t1 = zext i1 undef to i16
     32     %t2 = or i16 undef, %t1
     33     ret i16 %t2
     34   }
     35 
     36   define void @test5() {ret void}
     37 
     38 ...
     39 ---
     40 # CHECK-LABEL: name: test1
     41 name:            test1
     42 alignment:       4
     43 tracksRegLiveness: true
     44 liveins:
     45   - { reg: '$rax' }
     46 # Verify that "movw ($rax), $ax" is changed to "movzwl ($rax), $rax".
     47 #
     48 # For that to happen, the liveness information after the MOV16rm
     49 # instruction should be used, not before it because $rax is live
     50 # before the MOV and is killed by it.
     51 body:             |
     52   bb.0:
     53     liveins: $rax
     54 
     55     $ax = MOV16rm killed $rax, 1, $noreg, 0, $noreg
     56     ; CHECK: $eax = MOVZX32rm16 killed $rax
     57 
     58     RETQ $ax
     59 
     60 ...
     61 ---
     62 # CHECK-LABEL: name: test2
     63 name:            test2
     64 alignment:       4
     65 tracksRegLiveness: true
     66 liveins:
     67   - { reg: '$rax' }
     68 # Imp-use of any super-register means the register is live before the MOV
     69 body:             |
     70   bb.0:
     71     liveins: $dl, $rbx, $rcx, $r14
     72 
     73     $cl = MOV8rr killed $dl, implicit killed $rcx, implicit-def $rcx
     74     ; CHECK: $cl = MOV8rr killed $dl, implicit killed $rcx, implicit-def $rcx
     75     JMP_1 %bb.1
     76   bb.1:
     77     liveins: $rcx
     78 
     79     RETQ $cl
     80 
     81 ...
     82 ---
     83 # CHECK-LABEL: name: test3
     84 name:            test3
     85 alignment:       4
     86 tracksRegLiveness: true
     87 liveins:
     88   - { reg: '$rdi' }
     89 # After MOV16rm the whole $eax is not *really* live, as can be seen by
     90 # missing implicit-uses of it in that MOV. Make sure that MOV is
     91 # transformed into MOVZX.
     92 # See the comment near the original IR on what preceding decisions can
     93 # lead to that.
     94 body:             |
     95   bb.0.entry:
     96     successors: %bb.1(0x30000000), %bb.2.if.then(0x50000000)
     97     liveins: $rdi
     98 
     99     TEST64rr $rdi, $rdi, implicit-def $eflags
    100     JE_1 %bb.1, implicit $eflags
    101 
    102   bb.2.if.then:
    103     liveins: $rdi
    104 
    105     $ax = MOV16rm killed $rdi, 1, $noreg, 0, $noreg, implicit-def $eax :: (load 2 from %ir.p)
    106     ; CHECK: $eax = MOVZX32rm16 killed $rdi, 1, $noreg, 0, $noreg, implicit-def $eax :: (load 2 from %ir.p)
    107     $ax = KILL $ax, implicit killed $eax
    108     RETQ $ax
    109 
    110   bb.1:
    111     $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
    112     $ax = KILL $ax, implicit killed $eax
    113     RETQ $ax
    114 
    115 ...
    116 ---
    117 # CHECK-LABEL: name: test4
    118 name:            test4
    119 alignment:       4
    120 tracksRegLiveness: true
    121 liveins:
    122   - { reg: '$r9d' }
    123 # This code copies r10b into r9b and then uses r9w. We would like to promote
    124 # the copy to a 32-bit copy, but because r9w is used this is not acceptable.
    125 body:             |
    126   bb.0.entry:
    127     liveins: $r9d
    128 
    129     $r9b = MOV8rr undef $r10b, implicit-def $r9d, implicit killed $r9d, implicit-def $eflags
    130     ; CHECK: $r9b = MOV8rr undef $r10b, implicit-def $r9d, implicit killed $r9d, implicit-def $eflags
    131 
    132     $ax = OR16rr undef $ax, $r9w, implicit-def $eflags
    133     RETQ $ax
    134 
    135 ...
    136 ---
    137 # CHECK-LABEL: name: test5
    138 name:            test5
    139 alignment:       4
    140 tracksRegLiveness: true
    141 liveins:
    142   - { reg: '$ch', reg: '$bl' }
    143 body:             |
    144   bb.0:
    145     liveins: $ch, $bl
    146 
    147     $cl = MOV8rr $bl, implicit-def $cx, implicit killed $ch, implicit-def $eflags
    148     ; CHECK: $cl = MOV8rr $bl, implicit-def $cx, implicit killed $ch, implicit-def $eflags
    149 
    150     RETQ $cx
    151 
    152 ...
    153