Skip to content

Commit c63a622

Browse files
[AArch64] Disable red-zone when lowering Q-reg copy through memory. (#94962)
This was pointed out in PR #93940.
1 parent b1fe03f commit c63a622

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -431,8 +431,16 @@ bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
431431
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
432432
uint64_t NumBytes = AFI->getLocalStackSize();
433433

434+
// If neither NEON or SVE are available, a COPY from one Q-reg to
435+
// another requires a spill -> reload sequence. We can do that
436+
// using a pre-decrementing store/post-decrementing load, but
437+
// if we do so, we can't use the Red Zone.
438+
bool LowerQRegCopyThroughMem = Subtarget.hasFPARMv8() &&
439+
!Subtarget.isNeonAvailable() &&
440+
!Subtarget.hasSVE();
441+
434442
return !(MFI.hasCalls() || hasFP(MF) || NumBytes > RedZoneSize ||
435-
getSVEStackSize(MF));
443+
getSVEStackSize(MF) || LowerQRegCopyThroughMem);
436444
}
437445

438446
/// hasFP - Return true if the specified function should have a dedicated frame

llvm/test/CodeGen/AArch64/arm64-redzone.ll

+13
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,16 @@ define i32 @foo(i32 %a, i32 %b) nounwind ssp {
1616
%tmp2 = load i32, ptr %x, align 4
1717
ret i32 %tmp2
1818
}
19+
20+
; We disable red-zone if NEON is available because copies of Q-regs
21+
; require a spill/fill and dynamic allocation. But we only need to do
22+
; this when FP registers are enabled.
23+
define void @bar(fp128 %f) "target-features"="-fp-armv8" {
24+
; CHECK-LABEL: bar:
25+
; CHECK: // %bb.0:
26+
; CHECK-NEXT: stp x0, x1, [sp, #-16]
27+
; CHECK-NEXT: ret
28+
%ptr = alloca fp128
29+
store fp128 %f, ptr %ptr
30+
ret void
31+
}

0 commit comments

Comments
 (0)