| # 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 |