OSDN Git Service

ARM: use correct offset from base pointer (r6) in call frame regions.
authorTim Northover <tnorthover@apple.com>
Fri, 7 Dec 2018 13:43:55 +0000 (13:43 +0000)
committerTim Northover <tnorthover@apple.com>
Fri, 7 Dec 2018 13:43:55 +0000 (13:43 +0000)
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
test/CodeGen/ARM/alloca-align.ll
test/CodeGen/ARM/nonreserved-callframe-with-basereg.mir [new file with mode: 0644]

index d1e4bce..2417166 100644 (file)
@@ -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;
   }
index 6186d13..3326d36 100644 (file)
@@ -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 (file)
index 0000000..a262594
--- /dev/null
@@ -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
+
+...