[PATCH] D45770: [AArch64] Disable spill slot scavenging when stack realignment required.
Paul Walker via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 18 06:44:19 PDT 2018
paulwalker-arm created this revision.
paulwalker-arm added a reviewer: gberry.
Herald added subscribers: llvm-commits, kristof.beyls, javed.absar, qcolombet, rengolin.
Prevent corruption of the callee-save region by spills whose offset calculation assumes FP-SP is a compile time constant.
Repository:
rL LLVM
https://reviews.llvm.org/D45770
Files:
lib/Target/AArch64/AArch64FrameLowering.cpp
test/CodeGen/AArch64/spill-stack-realignment.mir
Index: test/CodeGen/AArch64/spill-stack-realignment.mir
===================================================================
--- /dev/null
+++ test/CodeGen/AArch64/spill-stack-realignment.mir
@@ -0,0 +1,53 @@
+# RUN: llc -mtriple=aarch64-none-linux-gnu -run-pass=prologepilog %s -o - | FileCheck %s
+
+# Ensure we don't perform stack slot scavenging when the stack pointer must be
+# aligned to something larger than required by the target. Allowing scavenging
+# can result in the callee-save region being corrupted when FP is used to build
+# the callee-save area and SP used to spill into it. This is becuase the value
+# of FP-SP becomes runtime variable after the alignment.
+--- |
+
+ define void @test(float* %p) nounwind {
+ entry:
+ %large_aligned_var = alloca float, align 64
+ %small_aligned_var = alloca float, align 4
+ %s0 = load float, float* %p, align 4
+ store volatile float %s0, float* %large_aligned_var, align 4
+ store volatile float %s0, float* %small_aligned_var, align 4
+ call void asm sideeffect "; inlineasm", "~{x28}"()
+ ret void
+ }
+
+...
+---
+name: test
+tracksRegLiveness: true
+frameInfo:
+ maxAlignment: 64
+# CHECK: stack:
+# CHECK: name: large_aligned_var, type: default, offset: -64, size: 4,
+# CHECK-NEXT: alignment: 64
+# CHECK-NEXT: local-offset: -64
+# CHECK: name: small_aligned_var, type: default, offset: -68, size: 4,
+# CHECK-NEXT: alignment: 4
+# CHECK-NEXT: local-offset: -68
+stack:
+ - { id: 0, name: large_aligned_var, size: 4, alignment: 64, local-offset: -64 }
+ - { id: 1, name: small_aligned_var, size: 4, alignment: 4, local-offset: -68 }
+
+# CHECK: body:
+# CHECK: $sp = ANDXri killed ${{x[0-9]+}}, 7865
+# CHECK: STRSui $s0, $sp, 16
+# CHECK: STRSui killed $s0, $sp, 15
+body: |
+ bb.0.entry:
+ liveins: $x0
+
+ $s0 = LDRSui killed $x0, 0 :: (load 4 from %ir.p)
+ STRSui $s0, %stack.0.large_aligned_var, 0 :: (volatile store 4 into %ir.large_aligned_var, align 64)
+ STRSui killed $s0, %stack.1.small_aligned_var, 0 :: (volatile store 4 into %ir.small_aligned_var)
+ ; Force preserve a CSR to create a hole in the CSR stack region.
+ INLINEASM &"; inlineasm", 1, 12, implicit-def dead early-clobber $x28
+ RET_ReallyLR
+
+...
Index: lib/Target/AArch64/AArch64FrameLowering.cpp
===================================================================
--- lib/Target/AArch64/AArch64FrameLowering.cpp
+++ lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1499,8 +1499,21 @@
AFI->setCalleeSavedStackSize(alignTo(8 * NumRegsSpilled, 16));
}
+// When stack realignment is required the size of the stack frame becomes
+// runtime variable. This manifests itself as a runtime variable gap between the
+// local and callee-save regions. If FP is used to build the callee-save region
+// then FP must be used to access any locals placed within it. This does not
+// happen today causing corruption to callee saves by SP relative stores whose
+// offset is calculated assuming FP-SP is a compile time constant.
+//
+// An option is to force all callee-save region accesses to be relative to the
+// same base (SP or FP) but given the alignment is likely to reduce the benefit
+// of slot scavenging it's simpler to disable the optimisation.
bool AArch64FrameLowering::enableStackSlotScavenging(
const MachineFunction &MF) const {
const AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
- return AFI->hasCalleeSaveStackFreeSpace();
+ const AArch64RegisterInfo *RegInfo = static_cast<const AArch64RegisterInfo *>(
+ MF.getSubtarget().getRegisterInfo());
+ return AFI->hasCalleeSaveStackFreeSpace() &&
+ !RegInfo->needsStackRealignment(MF);
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45770.142928.patch
Type: text/x-patch
Size: 3745 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180418/234e794f/attachment.bin>
More information about the llvm-commits
mailing list