reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
# 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

    RETQ $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

    RETQ $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 2 from %ir.p)
    ; CHECK: $eax = MOVZX32rm16 killed $rdi, 1, $noreg, 0, $noreg, implicit-def $eax :: (load 2 from %ir.p)
    $ax = KILL $ax, implicit killed $eax
    RETQ $ax

  bb.1:
    $eax = XOR32rr undef $eax, undef $eax, implicit-def dead $eflags
    $ax = KILL $ax, implicit killed $eax
    RETQ $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
    RETQ $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

    RETQ $cx

...