1# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py 2# RUN: llc -o - %s -mtriple=x86_64-unknown-linux-gnu --run-pass=peephole-opt | FileCheck %s 3 4# Test that TEST64rr is erased in `test_erased`, and kept in `test_not_erased_when_sf_used` 5# and `test_not_erased_when_eflags_change`. 6 7--- | 8 ; ModuleID = 'tmp.ll' 9 source_filename = "tmp.ll" 10 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 11 12 define i64 @test_erased(ptr %0, i64 %1, i64 %2) { 13 %4 = load i64, ptr %0, align 8 14 %5 = and i64 %4, 3 15 %6 = icmp eq i64 %5, 0 16 %7 = select i1 %6, i64 %1, i64 %5 17 store i64 %7, ptr %0, align 8 18 ret i64 %5 19 } 20 21 define i64 @test_not_erased_when_sf_used(ptr %0, i64 %1, i64 %2, i64 %3) { 22 %5 = load i64, ptr %0, align 8 23 %6 = and i64 %5, 3 24 %7 = icmp slt i64 %6, 0 25 %8 = select i1 %7, i64 %1, i64 %6 26 store i64 %8, ptr %0, align 8 27 ret i64 %5 28 } 29 30 define void @test_not_erased_when_eflags_change(ptr %0, i64 %1, i64 %2, i64 %3, ptr %4) { 31 %6 = load i64, ptr %0, align 8 32 %7 = and i64 %6, 3 33 %8 = xor i64 %3, 5 34 %9 = icmp eq i64 %7, 0 35 %10 = select i1 %9, i64 %1, i64 %7 36 store i64 %10, ptr %0, align 8 37 store i64 %8, ptr %4, align 8 38 ret void 39 } 40 41 define i16 @erase_test16(i16 %0, i16 %1, ptr nocapture %2) { 42 entry: 43 %3 = icmp ne i16 %0, 0 44 %4 = and i16 %1, 123 45 %5 = icmp eq i16 %4, 0 46 %6 = select i1 %3, i1 %5, i1 false 47 br i1 %6, label %if.then, label %if.end 48 49 if.then: ; preds = %entry 50 store i16 %0, ptr %2, align 4 51 br label %if.end 52 53 if.end: ; preds = %if.then, %entry 54 ret i16 0 55 } 56 57 define i16 @erase_test16_bigimm(i16 %0, i32 %1, ptr nocapture %2) { 58 entry: 59 %3 = icmp ne i16 %0, 0 60 %4 = and i32 %1, 123456 61 %trunc = trunc i32 %4 to i16 62 %5 = icmp eq i16 %trunc, 0 63 %6 = select i1 %3, i1 %5, i1 false 64 br i1 %6, label %if.then, label %if.end 65 66 if.then: ; preds = %entry 67 store i32 %4, ptr %2, align 4 68 br label %if.end 69 70 if.end: ; preds = %if.then, %entry 71 ret i16 0 72 } 73 74 define i16 @erase_test16_sf(i16 %0, i16 %1, ptr nocapture %2) { 75 entry: 76 %3 = icmp ne i16 %0, 0 77 %4 = and i16 %1, 1234 78 %5 = icmp slt i16 %4, 0 79 %6 = select i1 %3, i1 %5, i1 false 80 br i1 %6, label %if.then, label %if.end 81 82 if.then: ; preds = %entry 83 store i16 %4, ptr %2, align 4 84 br label %if.end 85 86 if.end: ; preds = %if.then, %entry 87 ret i16 0 88 } 89... 90--- 91name: test_erased 92alignment: 16 93tracksDebugUserValues: false 94registers: 95 - { id: 0, class: gr64, preferred-register: '' } 96 - { id: 1, class: gr64, preferred-register: '' } 97 - { id: 2, class: gr64, preferred-register: '' } 98 - { id: 3, class: gr64, preferred-register: '' } 99 - { id: 4, class: gr32, preferred-register: '' } 100 - { id: 5, class: gr32, preferred-register: '' } 101 - { id: 6, class: gr64, preferred-register: '' } 102 - { id: 7, class: gr64, preferred-register: '' } 103liveins: 104 - { reg: '$rdi', virtual-reg: '%0' } 105 - { reg: '$rsi', virtual-reg: '%1' } 106frameInfo: 107 maxAlignment: 1 108machineFunctionInfo: {} 109body: | 110 bb.0 (%ir-block.3): 111 liveins: $rdi, $rsi 112 113 ; CHECK-LABEL: name: test_erased 114 ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi 115 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi 116 ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY1]], 1, $noreg, 0, $noreg :: (load (s64) from %ir.0) 117 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[MOV64rm]].sub_32bit 118 ; CHECK-NEXT: [[AND32ri8_:%[0-9]+]]:gr32 = AND32ri8 [[COPY2]], 3, implicit-def $eflags 119 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[AND32ri8_]], %subreg.sub_32bit 120 ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[SUBREG_TO_REG]], [[COPY]], 4, implicit $eflags 121 ; CHECK-NEXT: MOV64mr [[COPY1]], 1, $noreg, 0, $noreg, killed [[CMOV64rr]] :: (store (s64) into %ir.0) 122 ; CHECK-NEXT: $rax = COPY [[SUBREG_TO_REG]] 123 ; CHECK-NEXT: RET 0, $rax 124 %1:gr64 = COPY $rsi 125 %0:gr64 = COPY $rdi 126 %3:gr64 = MOV64rm %0, 1, $noreg, 0, $noreg :: (load (s64) from %ir.0) 127 %4:gr32 = COPY %3.sub_32bit 128 %5:gr32 = AND32ri8 %4, 3, implicit-def dead $eflags 129 %6:gr64 = SUBREG_TO_REG 0, killed %5, %subreg.sub_32bit 130 TEST64rr %6, %6, implicit-def $eflags 131 %7:gr64 = CMOV64rr %6, %1, 4, implicit $eflags 132 MOV64mr %0, 1, $noreg, 0, $noreg, killed %7 :: (store (s64) into %ir.0) 133 $rax = COPY %6 134 RET 0, $rax 135 136... 137--- 138name: test_not_erased_when_sf_used 139alignment: 16 140tracksDebugUserValues: false 141registers: 142 - { id: 0, class: gr64, preferred-register: '' } 143 - { id: 1, class: gr64, preferred-register: '' } 144 - { id: 2, class: gr64, preferred-register: '' } 145 - { id: 3, class: gr64, preferred-register: '' } 146 - { id: 4, class: gr64, preferred-register: '' } 147 - { id: 5, class: gr32, preferred-register: '' } 148 - { id: 6, class: gr32, preferred-register: '' } 149 - { id: 7, class: gr64, preferred-register: '' } 150 - { id: 8, class: gr64, preferred-register: '' } 151liveins: 152 - { reg: '$rdi', virtual-reg: '%0' } 153 - { reg: '$rsi', virtual-reg: '%1' } 154frameInfo: 155 maxAlignment: 1 156machineFunctionInfo: {} 157body: | 158 bb.0 (%ir-block.4): 159 liveins: $rdi, $rsi 160 161 ; CHECK-LABEL: name: test_not_erased_when_sf_used 162 ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $rsi 163 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rdi 164 ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY1]], 1, $noreg, 0, $noreg :: (load (s64) from %ir.0) 165 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY [[MOV64rm]].sub_32bit 166 ; CHECK-NEXT: [[AND32ri8_:%[0-9]+]]:gr32 = AND32ri8 [[COPY2]], 3, implicit-def dead $eflags 167 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[AND32ri8_]], %subreg.sub_32bit 168 ; CHECK-NEXT: TEST64rr [[SUBREG_TO_REG]], [[SUBREG_TO_REG]], implicit-def $eflags 169 ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[SUBREG_TO_REG]], [[COPY]], 8, implicit $eflags 170 ; CHECK-NEXT: MOV64mr [[COPY1]], 1, $noreg, 0, $noreg, killed [[CMOV64rr]] :: (store (s64) into %ir.0) 171 ; CHECK-NEXT: $rax = COPY [[MOV64rm]] 172 ; CHECK-NEXT: RET 0, $rax 173 %1:gr64 = COPY $rsi 174 %0:gr64 = COPY $rdi 175 %4:gr64 = MOV64rm %0, 1, $noreg, 0, $noreg :: (load (s64) from %ir.0) 176 %5:gr32 = COPY %4.sub_32bit 177 %6:gr32 = AND32ri8 %5, 3, implicit-def dead $eflags 178 %7:gr64 = SUBREG_TO_REG 0, killed %6, %subreg.sub_32bit 179 TEST64rr %7, %7, implicit-def $eflags 180 %8:gr64 = CMOV64rr %7, %1, 8, implicit $eflags 181 MOV64mr %0, 1, $noreg, 0, $noreg, killed %8 :: (store (s64) into %ir.0) 182 $rax = COPY %4 183 RET 0, $rax 184 185... 186--- 187name: test_not_erased_when_eflags_change 188alignment: 16 189tracksDebugUserValues: false 190registers: 191 - { id: 0, class: gr64, preferred-register: '' } 192 - { id: 1, class: gr64, preferred-register: '' } 193 - { id: 2, class: gr64, preferred-register: '' } 194 - { id: 3, class: gr64, preferred-register: '' } 195 - { id: 4, class: gr64, preferred-register: '' } 196 - { id: 5, class: gr64, preferred-register: '' } 197 - { id: 6, class: gr32, preferred-register: '' } 198 - { id: 7, class: gr32, preferred-register: '' } 199 - { id: 8, class: gr64, preferred-register: '' } 200 - { id: 9, class: gr64, preferred-register: '' } 201 - { id: 10, class: gr64, preferred-register: '' } 202liveins: 203 - { reg: '$rdi', virtual-reg: '%0' } 204 - { reg: '$rsi', virtual-reg: '%1' } 205 - { reg: '$rcx', virtual-reg: '%3' } 206 - { reg: '$r8', virtual-reg: '%4' } 207frameInfo: 208 maxAlignment: 1 209machineFunctionInfo: {} 210body: | 211 bb.0 (%ir-block.5): 212 liveins: $rdi, $rsi, $rcx, $r8 213 214 ; CHECK-LABEL: name: test_not_erased_when_eflags_change 215 ; CHECK: [[COPY:%[0-9]+]]:gr64 = COPY $r8 216 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rcx 217 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr64 = COPY $rsi 218 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr64 = COPY $rdi 219 ; CHECK-NEXT: [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm [[COPY3]], 1, $noreg, 0, $noreg :: (load (s64) from %ir.0) 220 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr32 = COPY [[MOV64rm]].sub_32bit 221 ; CHECK-NEXT: [[AND32ri8_:%[0-9]+]]:gr32 = AND32ri8 [[COPY4]], 3, implicit-def dead $eflags 222 ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[AND32ri8_]], %subreg.sub_32bit 223 ; CHECK-NEXT: [[XOR64ri8_:%[0-9]+]]:gr64 = XOR64ri8 [[COPY1]], 5, implicit-def dead $eflags 224 ; CHECK-NEXT: TEST64rr [[SUBREG_TO_REG]], [[SUBREG_TO_REG]], implicit-def $eflags 225 ; CHECK-NEXT: [[CMOV64rr:%[0-9]+]]:gr64 = CMOV64rr [[SUBREG_TO_REG]], [[COPY2]], 4, implicit $eflags 226 ; CHECK-NEXT: MOV64mr [[COPY3]], 1, $noreg, 0, $noreg, killed [[CMOV64rr]] :: (store (s64) into %ir.0) 227 ; CHECK-NEXT: MOV64mr [[COPY]], 1, $noreg, 0, $noreg, killed [[XOR64ri8_]] :: (store (s64) into %ir.4) 228 ; CHECK-NEXT: RET 0 229 %4:gr64 = COPY $r8 230 %3:gr64 = COPY $rcx 231 %1:gr64 = COPY $rsi 232 %0:gr64 = COPY $rdi 233 %5:gr64 = MOV64rm %0, 1, $noreg, 0, $noreg :: (load (s64) from %ir.0) 234 %6:gr32 = COPY %5.sub_32bit 235 %7:gr32 = AND32ri8 %6, 3, implicit-def dead $eflags 236 %8:gr64 = SUBREG_TO_REG 0, killed %7, %subreg.sub_32bit 237 %9:gr64 = XOR64ri8 %3, 5, implicit-def dead $eflags 238 TEST64rr %8, %8, implicit-def $eflags 239 %10:gr64 = CMOV64rr %8, %1, 4, implicit $eflags 240 MOV64mr %0, 1, $noreg, 0, $noreg, killed %10 :: (store (s64) into %ir.0) 241 MOV64mr %4, 1, $noreg, 0, $noreg, killed %9 :: (store (s64) into %ir.4) 242 RET 0 243 244... 245--- 246name: erase_test16 247alignment: 16 248exposesReturnsTwice: false 249legalized: false 250regBankSelected: false 251selected: false 252failedISel: false 253tracksRegLiveness: true 254hasWinCFI: false 255callsEHReturn: false 256callsUnwindInit: false 257hasEHCatchret: false 258hasEHScopes: false 259hasEHFunclets: false 260isOutlined: false 261debugInstrRef: true 262failsVerification: false 263tracksDebugUserValues: false 264registers: 265 - { id: 0, class: gr32, preferred-register: '' } 266 - { id: 1, class: gr32, preferred-register: '' } 267 - { id: 2, class: gr64, preferred-register: '' } 268 - { id: 3, class: gr16, preferred-register: '' } 269 - { id: 4, class: gr16, preferred-register: '' } 270 - { id: 5, class: gr32, preferred-register: '' } 271 - { id: 6, class: gr32, preferred-register: '' } 272 - { id: 7, class: gr16, preferred-register: '' } 273liveins: 274 - { reg: '$edi', virtual-reg: '%0' } 275 - { reg: '$esi', virtual-reg: '%1' } 276 - { reg: '$rdx', virtual-reg: '%2' } 277frameInfo: 278 isFrameAddressTaken: false 279 isReturnAddressTaken: false 280 hasStackMap: false 281 hasPatchPoint: false 282 stackSize: 0 283 offsetAdjustment: 0 284 maxAlignment: 1 285 adjustsStack: false 286 hasCalls: false 287 stackProtector: '' 288 functionContext: '' 289 maxCallFrameSize: 4294967295 290 cvBytesOfCalleeSavedRegisters: 0 291 hasOpaqueSPAdjustment: false 292 hasVAStart: false 293 hasMustTailInVarArgFunc: false 294 hasTailCall: false 295 localFrameSize: 0 296 savePoint: '' 297 restorePoint: '' 298fixedStack: [] 299stack: [] 300entry_values: [] 301callSites: [] 302debugValueSubstitutions: [] 303constants: [] 304machineFunctionInfo: {} 305body: | 306 ; CHECK-LABEL: name: erase_test16 307 ; CHECK: bb.0.entry: 308 ; CHECK-NEXT: successors: %bb.1(0x60000000), %bb.3(0x20000000) 309 ; CHECK-NEXT: liveins: $edi, $esi, $rdx 310 ; CHECK-NEXT: {{ $}} 311 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdx 312 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esi 313 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY $edi 314 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit 315 ; CHECK-NEXT: TEST16rr [[COPY3]], [[COPY3]], implicit-def $eflags 316 ; CHECK-NEXT: JCC_1 %bb.3, 4, implicit $eflags 317 ; CHECK-NEXT: JMP_1 %bb.1 318 ; CHECK-NEXT: {{ $}} 319 ; CHECK-NEXT: bb.1.entry: 320 ; CHECK-NEXT: successors: %bb.2(0x55555555), %bb.3(0x2aaaaaab) 321 ; CHECK-NEXT: {{ $}} 322 ; CHECK-NEXT: [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY1]], 123, implicit-def $eflags 323 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr16 = COPY [[AND32ri]].sub_16bit 324 ; CHECK-NEXT: JCC_1 %bb.3, 5, implicit $eflags 325 ; CHECK-NEXT: JMP_1 %bb.2 326 ; CHECK-NEXT: {{ $}} 327 ; CHECK-NEXT: bb.2.if.then: 328 ; CHECK-NEXT: successors: %bb.3(0x80000000) 329 ; CHECK-NEXT: {{ $}} 330 ; CHECK-NEXT: MOV16mr [[COPY]], 1, $noreg, 0, $noreg, [[COPY3]] :: (store (s16) into %ir.2, align 4) 331 ; CHECK-NEXT: {{ $}} 332 ; CHECK-NEXT: bb.3.if.end: 333 ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags 334 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gr16 = COPY [[MOV32r0_]].sub_16bit 335 ; CHECK-NEXT: $ax = COPY [[COPY5]] 336 ; CHECK-NEXT: RET 0, $ax 337 bb.0.entry: 338 successors: %bb.3(0x60000000), %bb.2(0x20000000) 339 liveins: $edi, $esi, $rdx 340 341 %2:gr64 = COPY $rdx 342 %1:gr32 = COPY $esi 343 %0:gr32 = COPY $edi 344 %3:gr16 = COPY %0.sub_16bit 345 TEST16rr %3, %3, implicit-def $eflags 346 JCC_1 %bb.2, 4, implicit $eflags 347 JMP_1 %bb.3 348 349 bb.3.entry: 350 successors: %bb.1(0x55555555), %bb.2(0x2aaaaaab) 351 352 %5:gr32 = AND32ri %1, 123, implicit-def dead $eflags 353 %4:gr16 = COPY %5.sub_16bit 354 TEST16rr %4, %4, implicit-def $eflags 355 JCC_1 %bb.2, 5, implicit $eflags 356 JMP_1 %bb.1 357 358 bb.1.if.then: 359 successors: %bb.2(0x80000000) 360 361 MOV16mr %2, 1, $noreg, 0, $noreg, %3 :: (store (s16) into %ir.2, align 4) 362 363 bb.2.if.end: 364 %6:gr32 = MOV32r0 implicit-def dead $eflags 365 %7:gr16 = COPY %6.sub_16bit 366 $ax = COPY %7 367 RET 0, $ax 368 369... 370--- 371name: erase_test16_bigimm 372alignment: 16 373exposesReturnsTwice: false 374legalized: false 375regBankSelected: false 376selected: false 377failedISel: false 378tracksRegLiveness: true 379hasWinCFI: false 380callsEHReturn: false 381callsUnwindInit: false 382hasEHCatchret: false 383hasEHScopes: false 384hasEHFunclets: false 385isOutlined: false 386debugInstrRef: true 387failsVerification: false 388tracksDebugUserValues: false 389registers: 390 - { id: 0, class: gr32, preferred-register: '' } 391 - { id: 1, class: gr32, preferred-register: '' } 392 - { id: 2, class: gr32, preferred-register: '' } 393 - { id: 3, class: gr64, preferred-register: '' } 394 - { id: 4, class: gr16, preferred-register: '' } 395 - { id: 5, class: gr16, preferred-register: '' } 396 - { id: 6, class: gr32, preferred-register: '' } 397 - { id: 7, class: gr16, preferred-register: '' } 398liveins: 399 - { reg: '$edi', virtual-reg: '%1' } 400 - { reg: '$esi', virtual-reg: '%2' } 401 - { reg: '$rdx', virtual-reg: '%3' } 402frameInfo: 403 isFrameAddressTaken: false 404 isReturnAddressTaken: false 405 hasStackMap: false 406 hasPatchPoint: false 407 stackSize: 0 408 offsetAdjustment: 0 409 maxAlignment: 1 410 adjustsStack: false 411 hasCalls: false 412 stackProtector: '' 413 functionContext: '' 414 maxCallFrameSize: 4294967295 415 cvBytesOfCalleeSavedRegisters: 0 416 hasOpaqueSPAdjustment: false 417 hasVAStart: false 418 hasMustTailInVarArgFunc: false 419 hasTailCall: false 420 localFrameSize: 0 421 savePoint: '' 422 restorePoint: '' 423fixedStack: [] 424stack: [] 425entry_values: [] 426callSites: [] 427debugValueSubstitutions: [] 428constants: [] 429machineFunctionInfo: {} 430body: | 431 ; CHECK-LABEL: name: erase_test16_bigimm 432 ; CHECK: bb.0.entry: 433 ; CHECK-NEXT: successors: %bb.1(0x60000000), %bb.3(0x20000000) 434 ; CHECK-NEXT: liveins: $edi, $esi, $rdx 435 ; CHECK-NEXT: {{ $}} 436 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdx 437 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esi 438 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY $edi 439 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit 440 ; CHECK-NEXT: TEST16rr [[COPY3]], [[COPY3]], implicit-def $eflags 441 ; CHECK-NEXT: JCC_1 %bb.3, 4, implicit $eflags 442 ; CHECK-NEXT: JMP_1 %bb.1 443 ; CHECK-NEXT: {{ $}} 444 ; CHECK-NEXT: bb.1.entry: 445 ; CHECK-NEXT: successors: %bb.2(0x55555555), %bb.3(0x2aaaaaab) 446 ; CHECK-NEXT: {{ $}} 447 ; CHECK-NEXT: [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY1]], 123456, implicit-def dead $eflags 448 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr16 = COPY [[AND32ri]].sub_16bit 449 ; CHECK-NEXT: TEST16rr [[COPY4]], [[COPY4]], implicit-def $eflags 450 ; CHECK-NEXT: JCC_1 %bb.3, 5, implicit $eflags 451 ; CHECK-NEXT: JMP_1 %bb.2 452 ; CHECK-NEXT: {{ $}} 453 ; CHECK-NEXT: bb.2.if.then: 454 ; CHECK-NEXT: successors: %bb.3(0x80000000) 455 ; CHECK-NEXT: {{ $}} 456 ; CHECK-NEXT: MOV32mr [[COPY]], 1, $noreg, 0, $noreg, [[AND32ri]] :: (store (s32) into %ir.2) 457 ; CHECK-NEXT: {{ $}} 458 ; CHECK-NEXT: bb.3.if.end: 459 ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags 460 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gr16 = COPY [[MOV32r0_]].sub_16bit 461 ; CHECK-NEXT: $ax = COPY [[COPY5]] 462 ; CHECK-NEXT: RET 0, $ax 463 bb.0.entry: 464 successors: %bb.3(0x60000000), %bb.2(0x20000000) 465 liveins: $edi, $esi, $rdx 466 467 %3:gr64 = COPY $rdx 468 %2:gr32 = COPY $esi 469 %1:gr32 = COPY $edi 470 %5:gr16 = COPY %1.sub_16bit 471 TEST16rr %5, %5, implicit-def $eflags 472 JCC_1 %bb.2, 4, implicit $eflags 473 JMP_1 %bb.3 474 475 bb.3.entry: 476 successors: %bb.1(0x55555555), %bb.2(0x2aaaaaab) 477 478 %0:gr32 = AND32ri %2, 123456, implicit-def dead $eflags 479 %4:gr16 = COPY %0.sub_16bit 480 TEST16rr %4, %4, implicit-def $eflags 481 JCC_1 %bb.2, 5, implicit $eflags 482 JMP_1 %bb.1 483 484 bb.1.if.then: 485 successors: %bb.2(0x80000000) 486 487 MOV32mr %3, 1, $noreg, 0, $noreg, %0 :: (store (s32) into %ir.2) 488 489 bb.2.if.end: 490 %6:gr32 = MOV32r0 implicit-def dead $eflags 491 %7:gr16 = COPY %6.sub_16bit 492 $ax = COPY %7 493 RET 0, $ax 494 495... 496--- 497name: erase_test16_sf 498alignment: 16 499exposesReturnsTwice: false 500legalized: false 501regBankSelected: false 502selected: false 503failedISel: false 504tracksRegLiveness: true 505hasWinCFI: false 506callsEHReturn: false 507callsUnwindInit: false 508hasEHCatchret: false 509hasEHScopes: false 510hasEHFunclets: false 511isOutlined: false 512debugInstrRef: true 513failsVerification: false 514tracksDebugUserValues: false 515registers: 516 - { id: 0, class: gr16, preferred-register: '' } 517 - { id: 1, class: gr32, preferred-register: '' } 518 - { id: 2, class: gr32, preferred-register: '' } 519 - { id: 3, class: gr64, preferred-register: '' } 520 - { id: 4, class: gr16, preferred-register: '' } 521 - { id: 5, class: gr32, preferred-register: '' } 522 - { id: 6, class: gr32, preferred-register: '' } 523 - { id: 7, class: gr16, preferred-register: '' } 524liveins: 525 - { reg: '$edi', virtual-reg: '%1' } 526 - { reg: '$esi', virtual-reg: '%2' } 527 - { reg: '$rdx', virtual-reg: '%3' } 528frameInfo: 529 isFrameAddressTaken: false 530 isReturnAddressTaken: false 531 hasStackMap: false 532 hasPatchPoint: false 533 stackSize: 0 534 offsetAdjustment: 0 535 maxAlignment: 1 536 adjustsStack: false 537 hasCalls: false 538 stackProtector: '' 539 functionContext: '' 540 maxCallFrameSize: 4294967295 541 cvBytesOfCalleeSavedRegisters: 0 542 hasOpaqueSPAdjustment: false 543 hasVAStart: false 544 hasMustTailInVarArgFunc: false 545 hasTailCall: false 546 localFrameSize: 0 547 savePoint: '' 548 restorePoint: '' 549fixedStack: [] 550stack: [] 551entry_values: [] 552callSites: [] 553debugValueSubstitutions: [] 554constants: [] 555machineFunctionInfo: {} 556body: | 557 ; CHECK-LABEL: name: erase_test16_sf 558 ; CHECK: bb.0.entry: 559 ; CHECK-NEXT: successors: %bb.1(0x60000000), %bb.3(0x20000000) 560 ; CHECK-NEXT: liveins: $edi, $esi, $rdx 561 ; CHECK-NEXT: {{ $}} 562 ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr64 = COPY $rdx 563 ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr32 = COPY $esi 564 ; CHECK-NEXT: [[COPY2:%[0-9]+]]:gr32 = COPY $edi 565 ; CHECK-NEXT: [[COPY3:%[0-9]+]]:gr16 = COPY [[COPY2]].sub_16bit 566 ; CHECK-NEXT: TEST16rr [[COPY3]], [[COPY3]], implicit-def $eflags 567 ; CHECK-NEXT: JCC_1 %bb.3, 4, implicit $eflags 568 ; CHECK-NEXT: JMP_1 %bb.1 569 ; CHECK-NEXT: {{ $}} 570 ; CHECK-NEXT: bb.1.entry: 571 ; CHECK-NEXT: successors: %bb.2(0x55555555), %bb.3(0x2aaaaaab) 572 ; CHECK-NEXT: {{ $}} 573 ; CHECK-NEXT: [[AND32ri:%[0-9]+]]:gr32 = AND32ri [[COPY1]], 1234, implicit-def dead $eflags 574 ; CHECK-NEXT: [[COPY4:%[0-9]+]]:gr16 = COPY [[AND32ri]].sub_16bit 575 ; CHECK-NEXT: TEST16rr [[COPY4]], [[COPY4]], implicit-def $eflags 576 ; CHECK-NEXT: JCC_1 %bb.3, 9, implicit $eflags 577 ; CHECK-NEXT: JMP_1 %bb.2 578 ; CHECK-NEXT: {{ $}} 579 ; CHECK-NEXT: bb.2.if.then: 580 ; CHECK-NEXT: successors: %bb.3(0x80000000) 581 ; CHECK-NEXT: {{ $}} 582 ; CHECK-NEXT: MOV16mr [[COPY]], 1, $noreg, 0, $noreg, [[COPY4]] :: (store (s16) into %ir.2, align 4) 583 ; CHECK-NEXT: {{ $}} 584 ; CHECK-NEXT: bb.3.if.end: 585 ; CHECK-NEXT: [[MOV32r0_:%[0-9]+]]:gr32 = MOV32r0 implicit-def dead $eflags 586 ; CHECK-NEXT: [[COPY5:%[0-9]+]]:gr16 = COPY [[MOV32r0_]].sub_16bit 587 ; CHECK-NEXT: $ax = COPY [[COPY5]] 588 ; CHECK-NEXT: RET 0, $ax 589 bb.0.entry: 590 successors: %bb.3(0x60000000), %bb.2(0x20000000) 591 liveins: $edi, $esi, $rdx 592 593 %3:gr64 = COPY $rdx 594 %2:gr32 = COPY $esi 595 %1:gr32 = COPY $edi 596 %4:gr16 = COPY %1.sub_16bit 597 TEST16rr %4, %4, implicit-def $eflags 598 JCC_1 %bb.2, 4, implicit $eflags 599 JMP_1 %bb.3 600 601 bb.3.entry: 602 successors: %bb.1(0x55555555), %bb.2(0x2aaaaaab) 603 604 %5:gr32 = AND32ri %2, 1234, implicit-def dead $eflags 605 %0:gr16 = COPY %5.sub_16bit 606 TEST16rr %0, %0, implicit-def $eflags 607 JCC_1 %bb.2, 9, implicit $eflags 608 JMP_1 %bb.1 609 610 bb.1.if.then: 611 successors: %bb.2(0x80000000) 612 613 MOV16mr %3, 1, $noreg, 0, $noreg, %0 :: (store (s16) into %ir.2, align 4) 614 615 bb.2.if.end: 616 %6:gr32 = MOV32r0 implicit-def dead $eflags 617 %7:gr16 = COPY %6.sub_16bit 618 $ax = COPY %7 619 RET 0, $ax 620 621... 622