|  | # RUN: llc -mtriple=aarch64--linux-gnu -run-pass=aarch64-copyelim %s -verify-machineinstrs -o - | FileCheck %s | 
|  | --- | 
|  | # Check that bb.0 COPY is seen through to allow the bb.1 COPY of XZR to be removed. | 
|  | # CHECK-LABEL: name: test1 | 
|  | # CHECK-NOT: COPY $xzr | 
|  | name:            test1 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | $x0 = COPY $x1 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Similar to test1, but with reversed COPY. | 
|  | # CHECK-LABEL: name: test2 | 
|  | # CHECK-NOT: COPY $xzr | 
|  | name:            test2 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | $x1 = COPY $x0 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Similar to test1, but with a clobber that prevents removal of the XZR COPY. | 
|  | # CHECK-LABEL: name: test3 | 
|  | # CHECK: COPY $xzr | 
|  | name:            test3 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1, $x2 | 
|  |  | 
|  | $x0 = COPY $x1 | 
|  | $x1 = LDRXui $x1, 0 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Similar to test2, but with a clobber that prevents removal of the XZR COPY. | 
|  | # CHECK-LABEL: name: test4 | 
|  | # CHECK: COPY $xzr | 
|  | name:            test4 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1, $x2 | 
|  |  | 
|  | $x1 = COPY $x0 | 
|  | $x1 = LDRXui $x1, 0 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Similar to test2, but with a clobber that prevents removal of the XZR COPY. | 
|  | # CHECK-LABEL: name: test5 | 
|  | # CHECK: COPY $xzr | 
|  | name:            test5 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1, $x2 | 
|  |  | 
|  | $x1 = COPY $x0 | 
|  | $x0 = LDRXui $x1, 0 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Similar to test1, but with two levels of COPYs. | 
|  | # CHECK-LABEL: name: test6 | 
|  | # CHECK-NOT: COPY $xzr | 
|  | name:            test6 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1, $x2 | 
|  |  | 
|  | $x2 = COPY $x0 | 
|  | $x1 = COPY $x2 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Similar to test1, but with two levels of COPYs and a clobber preventing COPY of XZR removal. | 
|  | # CHECK-LABEL: name: test7 | 
|  | # CHECK: COPY $xzr | 
|  | name:            test7 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1, $x2 | 
|  |  | 
|  | $x2 = COPY $x0 | 
|  | $x0 = LDRXui $x1, 0 | 
|  | $x1 = COPY $x2 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Check that the TargetRegs vector clobber update loop in | 
|  | #  AArch64RedundantCopyElimination::optimizeCopy works correctly. | 
|  | # CHECK-LABEL: name: test8 | 
|  | # CHECK: x0 = COPY $xzr | 
|  | # CHECK: x1 = COPY $xzr | 
|  | name:            test8 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | $x1 = COPY $x0 | 
|  | CBNZX $x1, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x0, $x2 | 
|  |  | 
|  | $x0, $x1 = LDPXi $x2, 0 | 
|  | $x0 = COPY $xzr | 
|  | $x1 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Check that copy isn't removed from a block with multiple predecessors. | 
|  | # CHECK-LABEL: name: test9 | 
|  | # CHECK: x0 = COPY $xzr | 
|  | # CHECK-NEXT: B %bb.3 | 
|  | name:            test9 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | CBNZX $x0, %bb.2 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x0, $x2 | 
|  |  | 
|  | $x0 = COPY $xzr | 
|  | B %bb.3 | 
|  |  | 
|  | bb.2: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = LDRXui $x1, 0 | 
|  |  | 
|  | CBNZX $x1, %bb.1 | 
|  |  | 
|  | bb.3: | 
|  | liveins: $x0 | 
|  |  | 
|  | RET_ReallyLR implicit $x0 | 
|  |  | 
|  | ... | 
|  | # Eliminate redundant MOVi32imm 7 in bb.1 | 
|  | # Note: 32-bit compare/32-bit move imm | 
|  | # Kill marker should be removed from compare. | 
|  | # CHECK-LABEL: name: test10 | 
|  | # CHECK: SUBSWri $w0, 7, 0, implicit-def $nzcv | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi32imm | 
|  | name:            test10 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1 | 
|  |  | 
|  | dead $wzr = SUBSWri killed $w0, 7, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm 7 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Eliminate redundant MOVi32imm 7 in bb.1 | 
|  | # Note: 64-bit compare/32-bit move imm w/implicit def | 
|  | # Kill marker should be removed from compare. | 
|  | # CHECK-LABEL: name: test11 | 
|  | # CHECK: SUBSXri $x0, 7, 0, implicit-def $nzcv | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi32imm | 
|  | name:            test11 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | dead $xzr = SUBSXri killed $x0, 7, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm 7, implicit-def $x0 | 
|  | STRXui killed $x0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Eliminate redundant MOVi32imm 7 in bb.1 | 
|  | # Note: 64-bit compare/32-bit move imm | 
|  | # Kill marker should be removed from compare. | 
|  | # CHECK-LABEL: name: test12 | 
|  | # CHECK: SUBSXri $x0, 7, 0, implicit-def $nzcv | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi32imm | 
|  | name:            test12 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | dead $xzr = SUBSXri killed $x0, 7, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm 7 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Don't eliminate MOVi32imm 7 in bb.1 as we don't necessarily know the upper 32-bits. | 
|  | # Note: 32-bit compare/32-bit move imm w/implicit def | 
|  | # Kill marker should remain on compare. | 
|  | # CHECK-LABEL: name: test13 | 
|  | # CHECK: SUBSWri killed $w0, 7, 0, implicit-def $nzcv | 
|  | # CHECK: bb.1: | 
|  | # CHECK: MOVi32imm | 
|  | name:            test13 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1 | 
|  |  | 
|  | dead $wzr = SUBSWri killed $w0, 7, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm 7, implicit-def $x0 | 
|  | STRXui killed $x0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # We can't eliminate the MOVi32imm because of the clobbering LDRWui. | 
|  | # CHECK-LABEL: name: test14 | 
|  | # CHECK: bb.1: | 
|  | # CHECK: MOVi32imm | 
|  | name:            test14 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1, $x2 | 
|  |  | 
|  | dead $wzr = SUBSWri killed $w0, 7, 0, implicit-def $nzcv | 
|  | $w0 = LDRWui $x1, 0 | 
|  | STRWui killed $w0, killed $x2, 0 | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm 7 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # We can't eliminate the MOVi32imm because of the clobbering LDRWui. | 
|  | # CHECK-LABEL: name: test15 | 
|  | # CHECK: bb.1: | 
|  | # CHECK: MOVi32imm | 
|  | name:            test15 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1, $x2 | 
|  |  | 
|  | dead $wzr = SUBSWri killed $w0, 7, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1, $x2 | 
|  |  | 
|  | $w0 = LDRWui $x1, 0 | 
|  | STRWui killed $w0, killed $x2, 0 | 
|  | $w0 = MOVi32imm 7 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Check that bb.0 COPY is seen through to allow the bb.1 MOVi32imm to be removed. | 
|  | # CHECK-LABEL: name: test16 | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi32imm | 
|  | name:            test16 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1 | 
|  |  | 
|  | dead $wzr = SUBSWri $w0, 7, 0, implicit-def $nzcv | 
|  | $w2 = COPY $w0 | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w2 = MOVi32imm 7 | 
|  | STRWui killed $w2, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Check that bb.1 MOVi32imm is not removed due to self clobbering compare. | 
|  | # CHECK-LABEL: name: test17 | 
|  | # CHECK: bb.1: | 
|  | # CHECK: MOVi32imm | 
|  | name:            test17 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1 | 
|  |  | 
|  | dead $w0 = SUBSWri killed $w0, 7, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm 7 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Make sure the MOVi64imm is not removed.  In one version of this patch the | 
|  | # MOVi64imm immediate was truncated to 32 bits and incorrectly matched because | 
|  | # the low 32 bits of 4252017623040 are all zero. | 
|  | # CHECK-LABEL: name: test18 | 
|  | # CHECK: bb.1: | 
|  | # CHECK: MOVi64imm | 
|  | name:            test18 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | CBNZX killed $x0, %bb.2 | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = MOVi64imm 4252017623040 | 
|  | STRXui killed $x0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Eliminate redundant MOVi32imm -1 in bb.1 | 
|  | # Note: 32-bit compare/32-bit move imm | 
|  | # Kill marker should be removed from compare. | 
|  | # CHECK-LABEL: name: test19 | 
|  | # CHECK: ADDSWri $w0, 1, 0, implicit-def $nzcv | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi32imm | 
|  | name:            test19 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1 | 
|  |  | 
|  | dead $wzr = ADDSWri killed $w0, 1, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm -1 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Eliminate redundant MOVi64imm -1 in bb.1 | 
|  | # Note: 64-bit compare/64-bit move imm | 
|  | # Kill marker should be removed from compare. | 
|  | # CHECK-LABEL: name: test20 | 
|  | # CHECK: ADDSXri $x0, 1, 0, implicit-def $nzcv | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi64imm | 
|  | name:            test20 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | dead $xzr = ADDSXri killed $x0, 1, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = MOVi64imm -1 | 
|  | STRXui killed $x0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Eliminate redundant MOVi32imm -1 in bb.1 | 
|  | # Note: 64-bit compare/32-bit move imm | 
|  | # Kill marker should be removed from compare. | 
|  | # CHECK-LABEL: name: test21 | 
|  | # CHECK: ADDSXri $x0, 1, 0, implicit-def $nzcv | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi32imm | 
|  | name:            test21 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $x0, $x1 | 
|  |  | 
|  | dead $xzr = ADDSXri killed $x0, 1, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm -1 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Don't eliminate MOVi64imm -1 in bb.1 as we don't necessarily know the upper 32-bits. | 
|  | # Note: 32-bit compare/64-bit move imm | 
|  | # CHECK-LABEL: name: test22 | 
|  | # CHECK: bb.1: | 
|  | # CHECK: MOVi64imm | 
|  | name:            test22 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1 | 
|  |  | 
|  | dead $wzr = ADDSWri killed $w0, 1, 0, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $x0 = MOVi64imm -1 | 
|  | STRXui killed $x0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR | 
|  | ... | 
|  | # Eliminate redundant MOVi32imm 4096 in bb.1 when the compare has a shifted immediate. | 
|  | # CHECK-LABEL: name: test23 | 
|  | # CHECK: bb.1: | 
|  | # CHECK-NOT: MOVi32imm | 
|  | name:            test23 | 
|  | tracksRegLiveness: true | 
|  | body:             | | 
|  | bb.0.entry: | 
|  | liveins: $w0, $x1 | 
|  |  | 
|  | dead $wzr = SUBSWri killed $w0, 1, 12, implicit-def $nzcv | 
|  | Bcc 1, %bb.2, implicit killed $nzcv | 
|  | B %bb.1 | 
|  |  | 
|  | bb.1: | 
|  | liveins: $x1 | 
|  |  | 
|  | $w0 = MOVi32imm 4096 | 
|  | STRWui killed $w0, killed $x1, 0 | 
|  |  | 
|  | bb.2: | 
|  | RET_ReallyLR |