Home | History | Annotate | Download | only in X86
      1 # RUN: llc -mtriple=x86_64-- -run-pass=peephole-opt -o - %s | FileCheck %s
      2 
      3 --- |
      4   define i32 @foo(i32 %a) {
      5   bb0:
      6     br label %bb1
      7 
      8   bb1:                                              ; preds = %bb7, %bb0
      9     %vreg0 = phi i32 [ 0, %bb0 ], [ %vreg3, %bb7 ]
     10     %cond0 = icmp eq i32 %a, 0
     11     br i1 %cond0, label %bb4, label %bb3
     12 
     13   bb3:                                              ; preds = %bb1
     14     br label %bb4
     15 
     16   bb4:                                              ; preds = %bb1, %bb3
     17     %vreg5 = phi i32 [ 2, %bb3 ], [ 1, %bb1 ]
     18     %cond1 = icmp eq i32 %vreg5, 0
     19     br i1 %cond1, label %bb7, label %bb6
     20 
     21   bb6:                                              ; preds = %bb4
     22     br label %bb7
     23 
     24   bb7:                                              ; preds = %bb4, %bb6
     25     %vreg1 = phi i32 [ 2, %bb6 ], [ 1, %bb4 ]
     26     %vreg2 = add i32 %vreg5, %vreg0
     27     %vreg3 = add i32 %vreg1, %vreg2
     28     %cond2 = icmp slt i32 %vreg3, 10
     29     br i1 %cond2, label %bb1, label %bb8
     30 
     31   bb8:                                              ; preds = %bb7
     32     ret i32 0
     33   }
     34 
     35   define i32 @bar(i32 %a, i32* %p) {
     36   bb0:
     37     br label %bb1
     38 
     39   bb1:                                              ; preds = %bb7, %bb0
     40     %vreg0 = phi i32 [ 0, %bb0 ], [ %vreg3, %bb7 ]
     41     %cond0 = icmp eq i32 %a, 0
     42     br i1 %cond0, label %bb4, label %bb3
     43 
     44   bb3:                                              ; preds = %bb1
     45     br label %bb4
     46 
     47   bb4:                                              ; preds = %bb1, %bb3
     48     %vreg5 = phi i32 [ 2, %bb3 ], [ 1, %bb1 ]
     49     %cond1 = icmp eq i32 %vreg5, 0
     50     br i1 %cond1, label %bb7, label %bb6
     51 
     52   bb6:                                              ; preds = %bb4
     53     br label %bb7
     54 
     55   bb7:                                              ; preds = %bb4, %bb6
     56     %vreg1 = phi i32 [ 2, %bb6 ], [ 1, %bb4 ]
     57     %vreg2 = add i32 %vreg5, %vreg0
     58     store i32 %vreg0, i32* %p
     59     %vreg3 = add i32 %vreg1, %vreg2
     60     %cond2 = icmp slt i32 %vreg3, 10
     61     br i1 %cond2, label %bb1, label %bb8
     62 
     63   bb8:                                              ; preds = %bb7
     64     ret i32 0
     65   }
     66 
     67 ...
     68 ---
     69 # There is a recurrence formulated around %0, %10, and %3. Check that operands
     70 # are commuted for ADD instructions in bb.5.bb7 so that the values involved in
     71 # the recurrence are tied. This will remove redundant copy instruction.
     72 name:            foo
     73 tracksRegLiveness: true
     74 registers:
     75   - { id: 0, class: gr32, preferred-register: '' }
     76   - { id: 1, class: gr32, preferred-register: '' }
     77   - { id: 2, class: gr32, preferred-register: '' }
     78   - { id: 3, class: gr32, preferred-register: '' }
     79   - { id: 4, class: gr32, preferred-register: '' }
     80   - { id: 5, class: gr32, preferred-register: '' }
     81   - { id: 6, class: gr32, preferred-register: '' }
     82   - { id: 7, class: gr32, preferred-register: '' }
     83   - { id: 8, class: gr32, preferred-register: '' }
     84   - { id: 9, class: gr32, preferred-register: '' }
     85   - { id: 10, class: gr32, preferred-register: '' }
     86   - { id: 11, class: gr32, preferred-register: '' }
     87   - { id: 12, class: gr32, preferred-register: '' }
     88 liveins:
     89   - { reg: '$edi', virtual-reg: '%4' }
     90 body:             |
     91   bb.0.bb0:
     92     successors: %bb.1(0x80000000)
     93     liveins: $edi
     94 
     95     %4 = COPY $edi
     96     %5 = MOV32r0 implicit-def dead $eflags
     97 
     98   bb.1.bb1:
     99     successors: %bb.3(0x30000000), %bb.2(0x50000000)
    100 
    101     ; CHECK: %0:gr32 = PHI %5, %bb.0, %3, %bb.5
    102     %0 = PHI %5, %bb.0, %3, %bb.5
    103     %6 = MOV32ri 1
    104     TEST32rr %4, %4, implicit-def $eflags
    105     JE_1 %bb.3, implicit $eflags
    106     JMP_1 %bb.2
    107 
    108   bb.2.bb3:
    109     successors: %bb.3(0x80000000)
    110 
    111     %7 = MOV32ri 2
    112 
    113   bb.3.bb4:
    114     successors: %bb.5(0x30000000), %bb.4(0x50000000)
    115 
    116     %1 = PHI %6, %bb.1, %7, %bb.2
    117     TEST32rr %1, %1, implicit-def $eflags
    118     JE_1 %bb.5, implicit $eflags
    119     JMP_1 %bb.4
    120 
    121   bb.4.bb6:
    122     successors: %bb.5(0x80000000)
    123 
    124     %9 = MOV32ri 2
    125 
    126   bb.5.bb7:
    127     successors: %bb.1(0x7c000000), %bb.6(0x04000000)
    128 
    129     %2 = PHI %6, %bb.3, %9, %bb.4
    130     %10 = ADD32rr %1, %0, implicit-def dead $eflags
    131     ; CHECK: %10:gr32 = ADD32rr
    132     ; CHECK-SAME: %0,
    133     ; CHECK-SAME: %1,
    134     %3 = ADD32rr %2, killed %10, implicit-def dead $eflags
    135     ; CHECK: %3:gr32 = ADD32rr
    136     ; CHECK-SAME: %10,
    137     ; CHECK-SAME: %2,
    138     %11 = SUB32ri8 %3, 10, implicit-def $eflags
    139     JL_1 %bb.1, implicit $eflags
    140     JMP_1 %bb.6
    141 
    142   bb.6.bb8:
    143     %12 = MOV32r0 implicit-def dead $eflags
    144     $eax = COPY %12
    145     RET 0, $eax
    146 
    147 ...
    148 ---
    149 # Here a recurrence is formulated around %0, %11, and %3, but operands should
    150 # not be commuted because %0 has a use outside of recurrence. This is to
    151 # prevent the case of commuting operands ties the values with overlapping live
    152 # ranges.
    153 name:            bar
    154 tracksRegLiveness: true
    155 registers:
    156   - { id: 0, class: gr32, preferred-register: '' }
    157   - { id: 1, class: gr32, preferred-register: '' }
    158   - { id: 2, class: gr32, preferred-register: '' }
    159   - { id: 3, class: gr32, preferred-register: '' }
    160   - { id: 4, class: gr32, preferred-register: '' }
    161   - { id: 5, class: gr64, preferred-register: '' }
    162   - { id: 6, class: gr32, preferred-register: '' }
    163   - { id: 7, class: gr32, preferred-register: '' }
    164   - { id: 8, class: gr32, preferred-register: '' }
    165   - { id: 9, class: gr32, preferred-register: '' }
    166   - { id: 10, class: gr32, preferred-register: '' }
    167   - { id: 11, class: gr32, preferred-register: '' }
    168   - { id: 12, class: gr32, preferred-register: '' }
    169   - { id: 13, class: gr32, preferred-register: '' }
    170 liveins:
    171   - { reg: '$edi', virtual-reg: '%4' }
    172   - { reg: '$rsi', virtual-reg: '%5' }
    173 body:             |
    174   bb.0.bb0:
    175     successors: %bb.1(0x80000000)
    176     liveins: $edi, $rsi
    177 
    178     %5 = COPY $rsi
    179     %4 = COPY $edi
    180     %6 = MOV32r0 implicit-def dead $eflags
    181 
    182   bb.1.bb1:
    183     successors: %bb.3(0x30000000), %bb.2(0x50000000)
    184 
    185     %0 = PHI %6, %bb.0, %3, %bb.5
    186     ; CHECK: %0:gr32 = PHI %6, %bb.0, %3, %bb.5
    187     %7 = MOV32ri 1
    188     TEST32rr %4, %4, implicit-def $eflags
    189     JE_1 %bb.3, implicit $eflags
    190     JMP_1 %bb.2
    191 
    192   bb.2.bb3:
    193     successors: %bb.3(0x80000000)
    194 
    195     %8 = MOV32ri 2
    196 
    197   bb.3.bb4:
    198     successors: %bb.5(0x30000000), %bb.4(0x50000000)
    199 
    200     %1 = PHI %7, %bb.1, %8, %bb.2
    201     TEST32rr %1, %1, implicit-def $eflags
    202     JE_1 %bb.5, implicit $eflags
    203     JMP_1 %bb.4
    204 
    205   bb.4.bb6:
    206     successors: %bb.5(0x80000000)
    207 
    208     %10 = MOV32ri 2
    209 
    210   bb.5.bb7:
    211     successors: %bb.1(0x7c000000), %bb.6(0x04000000)
    212 
    213     %2 = PHI %7, %bb.3, %10, %bb.4
    214     %11 = ADD32rr %1, %0, implicit-def dead $eflags
    215     ; CHECK: %11:gr32 = ADD32rr
    216     ; CHECK-SAME: %1,
    217     ; CHECK-SAME: %0,
    218     MOV32mr %5, 1, $noreg, 0, $noreg, %0 :: (store 4 into %ir.p)
    219     %3 = ADD32rr %2, killed %11, implicit-def dead $eflags
    220     ; CHECK: %3:gr32 = ADD32rr
    221     ; CHECK-SAME: %2,
    222     ; CHECK-SAME: %11,
    223     %12 = SUB32ri8 %3, 10, implicit-def $eflags
    224     JL_1 %bb.1, implicit $eflags
    225     JMP_1 %bb.6
    226 
    227   bb.6.bb8:
    228     %13 = MOV32r0 implicit-def dead $eflags
    229     $eax = COPY %13
    230     RET 0, $eax
    231 
    232 ...
    233