From 2ae30c46b80a45df8342ca93799f9f111d23e40b Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Fri, 7 Dec 2018 13:43:55 +0000 Subject: [PATCH] ARM: use correct offset from base pointer (r6) in call frame regions. When we had dynamic call frames (i.e. sp adjustment around each call) we were including that adjustment into offsets calculated based on r6, even though it's only sp that changes. This led to incorrect stack slot accesses. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@348591 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMFrameLowering.cpp | 1 + test/CodeGen/ARM/alloca-align.ll | 3 +- .../ARM/nonreserved-callframe-with-basereg.mir | 54 ++++++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/ARM/nonreserved-callframe-with-basereg.mir diff --git a/lib/Target/ARM/ARMFrameLowering.cpp b/lib/Target/ARM/ARMFrameLowering.cpp index d1e4bce1e0c..2417166ca96 100644 --- a/lib/Target/ARM/ARMFrameLowering.cpp +++ b/lib/Target/ARM/ARMFrameLowering.cpp @@ -911,6 +911,7 @@ ARMFrameLowering::ResolveFrameIndexReference(const MachineFunction &MF, assert(RegInfo->hasBasePointer(MF) && "VLAs and dynamic stack alignment, but missing base pointer!"); FrameReg = RegInfo->getBaseRegister(); + Offset -= SPAdj; } return Offset; } diff --git a/test/CodeGen/ARM/alloca-align.ll b/test/CodeGen/ARM/alloca-align.ll index 6186d137ef7..3326d361c07 100644 --- a/test/CodeGen/ARM/alloca-align.ll +++ b/test/CodeGen/ARM/alloca-align.ll @@ -12,8 +12,7 @@ declare void @bar(i32*, [20000 x i8]* byval) ; And a base pointer getting used. ; CHECK: mov r6, sp ; Which is passed to the call -; CHECK: add [[REG:r[0-9]+|lr]], r6, #19456 -; CHECK: add r0, [[REG]], #536 +; CHECK: mov r0, r6 ; CHECK: bl bar define void @foo([20000 x i8]* %addr) { %tmp = alloca [4 x i32], align 32 diff --git a/test/CodeGen/ARM/nonreserved-callframe-with-basereg.mir b/test/CodeGen/ARM/nonreserved-callframe-with-basereg.mir new file mode 100644 index 00000000000..a262594473f --- /dev/null +++ b/test/CodeGen/ARM/nonreserved-callframe-with-basereg.mir @@ -0,0 +1,54 @@ +# RUN: llc -run-pass=prologepilog %s -o - | FileCheck %s + +# Make sure we use the correct offset for stack accesses using the base pointer +# within call frame blocks. Key points of test: +# + A large SP in ADJCALLSTACKDOWN forces each call to get its own adjustment. +# + An over-aligned stack variable means that we must use r6 rather than fp +# to access this variables. +# +# Under these circumstances, the ADJCALLSTACKDOWN must not apply to r6 offsets. + +--- | + ; ModuleID = 'simple.ll' + source_filename = "simple.ll" + target datalayout = "e-m:o-p:32:32-i64:64-a:0:32-n32-S128" + target triple = "thumbv7k-apple-ios" + + declare void @bar([4 x i32], i32) + + define void @foo(i32 %n) { + ret void + } + +... +--- +name: foo +liveins: + - { reg: '$r0', virtual-reg: '' } +frameInfo: + adjustsStack: true + hasCalls: true + maxCallFrameSize: 2276 +stack: + - { id: 0, name: '', type: spill-slot, offset: 0, alignment: 32, size: 4 } +constants: [] +body: | + bb.0 (%ir-block.0): + liveins: $r0 + + ; CHECK: t2STRi12 killed $r0, $r6, [[OFFSET:[0-9]+]] + t2STRi12 killed $r0, %stack.0, 0, 14, $noreg :: (store 4 into %stack.0) + + ADJCALLSTACKDOWN 2276, 0, 14, $noreg, implicit-def dead $sp, implicit $sp + + ; CHECK: renamable $r0 = t2LDRi12 $r6, [[OFFSET]] + renamable $r0 = t2LDRi12 %stack.0, 0, 14, $noreg, :: (load 4 from %stack.0) + renamable $r1 = IMPLICIT_DEF + renamable $r2 = IMPLICIT_DEF + renamable $r3 = IMPLICIT_DEF + tBL 14, $noreg, @bar, csr_ios, implicit-def dead $lr, implicit $sp, implicit killed $r0, implicit killed $r1, implicit killed $r2, implicit killed $r3, implicit-def $sp + + ADJCALLSTACKUP 2276, 0, 14, $noreg, implicit-def dead $sp, implicit $sp + tBX_RET 14, $noreg + +... -- 2.11.0