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. 72name: foo 73tracksRegLiveness: true 74registers: 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: '' } 88liveins: 89 - { reg: '$edi', virtual-reg: '%4' } 90body: | 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 JCC_1 %bb.3, 4, 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 JCC_1 %bb.5, 4, 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 JCC_1 %bb.1, 12, 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. 153name: bar 154tracksRegLiveness: true 155registers: 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: '' } 170liveins: 171 - { reg: '$edi', virtual-reg: '%4' } 172 - { reg: '$rsi', virtual-reg: '%5' } 173body: | 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 JCC_1 %bb.3, 4, 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 JCC_1 %bb.5, 4, 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 JCC_1 %bb.1, 12, 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