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