| # RUN: llc -mtriple=aarch64-apple-ios -run-pass=simple-register-coalescing %s -o - | FileCheck %s |
| --- | |
| declare void @f2() |
| |
| define void @func0() { ret void } |
| define void @func1() { ret void } |
| define void @func2() { ret void } |
| ... |
| --- |
| # Check coalescing of COPYs from reserved physregs. |
| # CHECK-LABEL: name: func0 |
| name: func0 |
| body: | |
| bb.0: |
| ; We usually should not coalesce copies from allocatable physregs. |
| ; CHECK: %0:gpr32 = COPY $w7 |
| ; CHECK: STRWui %0, $x1, 0 |
| %0 : gpr32 = COPY $w7 |
| STRWui %0, $x1, 0 |
| |
| ; It is fine to coalesce copies from reserved physregs |
| ; CHECK-NOT: COPY |
| ; CHECK: STRXui $fp, $x1, 0 |
| %1 : gpr64 = COPY $fp |
| STRXui %1, $x1, 0 |
| |
| ; It is not fine to coalesce copies from reserved physregs when they are |
| ; clobbered. |
| ; CHECK: %2:gpr64 = COPY $fp |
| ; CHECK: STRXui %2, $x1, 0 |
| %2 : gpr64 = COPY $fp |
| $fp = SUBXri $fp, 4, 0 |
| STRXui %2, $x1, 0 |
| |
| ; Is is fine to coalesce copies from constant physregs even when they are |
| ; clobbered. |
| ; CHECK-NOT: COPY |
| ; CHECK: STRWui $wzr, $x1 |
| %3 : gpr32 = COPY $wzr |
| dead $wzr = SUBSWri $w1, 0, 0, implicit-def $nzcv |
| STRWui %3, $x1, 0 |
| |
| ; Is is fine to coalesce copies from constant physregs even when they are |
| ; clobbered. |
| ; CHECK-NOT: COPY |
| ; CHECK: STRXui $xzr, $x1 |
| %4 : gpr64 = COPY $xzr |
| dead $wzr = SUBSWri $w1, 0, 0, implicit-def $nzcv |
| STRXui %4, $x1, 0 |
| |
| ; Coalescing COPYs into constant physregs. |
| ; CHECK: $wzr = SUBSWri $w1, 0, 0 |
| %5 : gpr32 = SUBSWri $w1, 0, 0, implicit-def $nzcv |
| $wzr = COPY %5 |
| |
| ; Only coalesce when the source register is reserved as a whole (this is |
| ; a limitation of the current code which cannot update liveness information |
| ; of the non-reserved part). |
| ; CHECK: %6:xseqpairsclass = COPY $x28_fp |
| ; CHECK: HINT 0, implicit %6 |
| %6 : xseqpairsclass = COPY $x28_fp |
| HINT 0, implicit %6 |
| |
| ; It is not fine to coalesce copies from reserved physregs when they are |
| ; clobbered by the regmask on a call. |
| ; CHECK: %7:gpr64 = COPY $x18 |
| ; CHECK: BL @f2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp |
| ; CHECK: STRXui %7, $x1, 0 |
| |
| ; Need a def of x18 so that it's not deduced as "constant". |
| $x18 = COPY $xzr |
| %7 : gpr64 = COPY $x18 |
| BL @f2, csr_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp |
| STRXui %7, $x1, 0 |
| |
| ; This can be coalesced. |
| ; CHECK: $fp = SUBXri $fp, 4, 0 |
| %8 : gpr64sp = SUBXri $fp, 4, 0 |
| $fp = COPY %8 |
| |
| ; Cannot coalesce when there are reads of the physreg. |
| ; CHECK-NOT: $fp = SUBXri $fp, 8, 0 |
| ; CHECK: %9:gpr64sp = SUBXri $fp, 8, 0 |
| ; CHECK: STRXui $fp, $fp, 0 |
| ; CHECK: $fp = COPY %9 |
| %9 : gpr64sp = SUBXri $fp, 8, 0 |
| STRXui $fp, $fp, 0 |
| $fp = COPY %9 |
| ... |
| --- |
| # Check coalescing of COPYs from reserved physregs. |
| # CHECK-LABEL: name: func1 |
| name: func1 |
| body: | |
| bb.0: |
| ; Cannot coalesce physreg because we have reads on other CFG paths (we |
| ; currently abort for any control flow) |
| ; CHECK-NOT: $fp = SUBXri |
| ; CHECK: %0:gpr64sp = SUBXri $fp, 12, 0 |
| ; CHECK: CBZX undef $x0, %bb.1 |
| ; CHECK: B %bb.2 |
| %0 : gpr64sp = SUBXri $fp, 12, 0 |
| CBZX undef $x0, %bb.1 |
| B %bb.2 |
| |
| bb.1: |
| $fp = COPY %0 |
| RET_ReallyLR |
| |
| bb.2: |
| STRXui $fp, $fp, 0 |
| RET_ReallyLR |
| ... |
| --- |
| # CHECK-LABEL: name: func2 |
| name: func2 |
| body: | |
| bb.0: |
| ; We can coalesce copies from physreg to vreg across multiple blocks. |
| ; CHECK-NOT: COPY |
| ; CHECK: CBZX undef $x0, %bb.1 |
| ; CHECK-NEXT: B %bb.2 |
| %0 : gpr64sp = COPY $fp |
| CBZX undef $x0, %bb.1 |
| B %bb.2 |
| |
| bb.1: |
| ; CHECK: STRXui undef $x0, $fp, 0 |
| ; CHECK-NEXT: RET_ReallyLR |
| STRXui undef $x0, %0, 0 |
| RET_ReallyLR |
| |
| bb.2: |
| RET_ReallyLR |
| ... |