blob: 095e8a4973ce49a1fd6a07b2476ebd70a05507bd [file] [log] [blame]
# 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
...