[AArch64][RegAlloc] Reserve LR reservation reserve W30 subreg (#173725)

This change fixes the reservation of LR by `-mlr-for-calls-only`, also
reserving its sub-register W30. Otherwise, the register allocator could
allocate W30. Adding a regression test for general sub-register
reservation, including LR.
This commit is contained in:
Tomer Shafir 2026-01-06 22:29:00 +02:00 committed by GitHub
parent 8b907a3a20
commit 68141cb2fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 86 additions and 5 deletions

View File

@ -547,7 +547,9 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
// it's liveness. We use the NoVRegs property instead of IsSSA because
// IsSSA is removed before VirtRegRewriter runs.
if (!MF.getProperties().hasNoVRegs())
markSuperRegs(Reserved, AArch64::LR);
// Reserve LR (X30) by marking from its subregister W30 because otherwise
// the register allocator could clobber the subregister.
markSuperRegs(Reserved, AArch64::W30);
}
assert(checkAllSuperRegsMarked(Reserved));

View File

@ -113,11 +113,13 @@
; Also, fp must always refer to a valid frame record, even if it's not the one
; of the current function, so it shouldn't be used either.
@var = global [30 x i64] zeroinitializer
; Test reserved GPR64 super-registers regalloc on register pressure.
define void @keep_live() {
%val = load volatile [30 x i64], ptr @var
store volatile [30 x i64] %val, ptr @var
@var_i64 = global [30 x i64] zeroinitializer
define void @keep_live_GPR64() {
%val = load volatile [30 x i64], ptr @var_i64
store volatile [30 x i64] %val, ptr @var_i64
; CHECK: ldr x18
; CHECK: str x18
@ -186,3 +188,80 @@ define void @keep_live() {
; CHECK-RESERVE: ret
ret void
}
; Test reserved GPR32 sub-registers regalloc on register pressure.
; They should be reserved together with their GPR64 super-registers.
@var_i32 = global [30 x i32] zeroinitializer
define void @keep_live_GPR32() {
%val = load volatile [30 x i32], ptr @var_i32
store volatile [30 x i32] %val, ptr @var_i32
; CHECK: ldr w18
; CHECK: str w18
; CHECK-RESERVE-NOT: ldr fp
; CHECK-RESERVE-X8-NOT: adrp w8
; CHECK-RESERVE-X8-NOT: ldr w8
; CHECK-RESERVE-X1-NOT: ldr w1,
; CHECK-RESERVE-X2-NOT: ldr w2,
; CHECK-RESERVE-X3-NOT: ldr w3,
; CHECK-RESERVE-X4-NOT: ldr w4,
; CHECK-RESERVE-X5-NOT: ldr w5,
; CHECK-RESERVE-X6-NOT: ldr w6,
; CHECK-RESERVE-X7-NOT: ldr w7,
; CHECK-RESERVE-X9-NOT: ldr w9,
; CHECK-RESERVE-X10-NOT: ldr w10,
; CHECK-RESERVE-X11-NOT: ldr w11,
; CHECK-RESERVE-X12-NOT: ldr w12,
; CHECK-RESERVE-X13-NOT: ldr w13,
; CHECK-RESERVE-X14-NOT: ldr w14,
; CHECK-RESERVE-X15-NOT: ldr w15,
; CHECK-RESERVE-X16-NOT: ldr w16
; CHECK-RESERVE-X17-NOT: ldr w17
; CHECK-RESERVE-X18-NOT: ldr w18
; CHECK-RESERVE-X19-NOT: ldr w19
; CHECK-RESERVE-X20-NOT: ldr w20
; CHECK-RESERVE-X21-NOT: ldr w21
; CHECK-RESERVE-X22-NOT: ldr w22
; CHECK-RESERVE-X23-NOT: ldr w23
; CHECK-RESERVE-X24-NOT: ldr w24
; CHECK-RESERVE-X25-NOT: ldr w25
; CHECK-RESERVE-X26-NOT: ldr w26
; CHECK-RESERVE-X27-NOT: ldr w27
; CHECK-RESERVE-X28-NOT: ldr w28
; CHECK-RESERVE-LR-RA-NOT: ldr w30
; CHECK-RESERVE: Spill
; CHECK-RESERVE-NOT: ldr fp
; CHECK-RESERVE-X1-NOT: ldr w1,
; CHECK-RESERVE-X2-NOT: ldr w2,
; CHECK-RESERVE-X3-NOT: ldr w3,
; CHECK-RESERVE-X4-NOT: ldr w4,
; CHECK-RESERVE-X5-NOT: ldr w5,
; CHECK-RESERVE-X6-NOT: ldr w6,
; CHECK-RESERVE-X7-NOT: ldr w7,
; CHECK-RESERVE-X9-NOT: ldr w9,
; CHECK-RESERVE-X10-NOT: ldr w10,
; CHECK-RESERVE-X11-NOT: ldr w11,
; CHECK-RESERVE-X12-NOT: ldr w12,
; CHECK-RESERVE-X13-NOT: ldr w13,
; CHECK-RESERVE-X14-NOT: ldr w14,
; CHECK-RESERVE-X15-NOT: ldr w15,
; CHECK-RESERVE-X16-NOT: ldr w16
; CHECK-RESERVE-X17-NOT: ldr w17
; CHECK-RESERVE-X18-NOT: ldr w18
; CHECK-RESERVE-X19-NOT: ldr w19
; CHECK-RESERVE-X20-NOT: ldr w20
; CHECK-RESERVE-X21-NOT: ldr w21
; CHECK-RESERVE-X22-NOT: ldr w22
; CHECK-RESERVE-X23-NOT: ldr w23
; CHECK-RESERVE-X24-NOT: ldr w24
; CHECK-RESERVE-X25-NOT: ldr w25
; CHECK-RESERVE-X26-NOT: ldr w26
; CHECK-RESERVE-X27-NOT: ldr w27
; CHECK-RESERVE-X28-NOT: ldr w28
; CHECK-RESERVE-LR-RA-NOT: ldr w30
; CHECK-RESERVE: ret
ret void
}