Skip to content

Commit

Permalink
[PowerPC] Restore stack ptr from base ptr when available
Browse files Browse the repository at this point in the history
On subtargets that have a red zone, we will copy the stack pointer to the base
pointer in the prologue prior to updating the stack pointer. There are no other
updates to the base pointer after that. This suggests that we should be able to
restore the stack pointer from the base pointer rather than loading it from the
back chain or adding the frame size back to either the stack pointer or the
frame pointer.
This came about because functions that call setjmp need to restore the SP from
the FP because the back chain might have been clobbered
(see https://reviews.llvm.org/D92906). However, if the stack is realigned, the
restored SP might be incorrect (which is what caused the failures in the two
ASan test cases).

This patch was tested quite extensivelly both with sanitizer runtimes and
general code.

Differential revision: https://reviews.llvm.org/D93327
  • Loading branch information
nemanjai committed Dec 22, 2020
1 parent 853770f commit ba1202a
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 16 deletions.
@@ -1,4 +1,3 @@
// UNSUPPORTED: powerpc64
// Tests that __asan_handle_no_return properly unpoisons the signal alternate
// stack.

Expand Down
1 change: 0 additions & 1 deletion compiler-rt/test/asan/TestCases/longjmp.cpp
@@ -1,4 +1,3 @@
// UNSUPPORTED: powerpc64
// RUN: %clangxx_asan -O %s -o %t && %run %t

#include <assert.h>
Expand Down
9 changes: 8 additions & 1 deletion llvm/lib/Target/PowerPC/PPCFrameLowering.cpp
Expand Up @@ -1644,11 +1644,18 @@ void PPCFrameLowering::emitEpilogue(MachineFunction &MF,
// offset by the STDU/STDUX/STWU/STWUX instruction. For targets with red
// zone add this offset back now.

// If the function has a base pointer, the stack pointer has been copied
// to it so we can restore it by copying in the other direction.
if (HasRedZone && HasBP) {
BuildMI(MBB, MBBI, dl, OrInst, RBReg).
addReg(BPReg).
addReg(BPReg);
}
// If this function contained a fastcc call and GuaranteedTailCallOpt is
// enabled (=> hasFastCall()==true) the fastcc call might contain a tail
// call which invalidates the stack pointer value in SP(0). So we use the
// value of R31 in this case. Similar situation exists with setjmp.
if (FI->hasFastCall() || MF.exposesReturnsTwice()) {
else if (FI->hasFastCall() || MF.exposesReturnsTwice()) {
assert(HasFP && "Expecting a valid frame pointer.");
if (!HasRedZone)
RBReg = FPReg;
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/PowerPC/aix-base-pointer.ll
Expand Up @@ -27,7 +27,7 @@ declare void @callee(i32*)
; 32BIT: stwux 1, 1, 0
; 32BIT: addi 3, 1, 64
; 32BIT: bl .callee
; 32BIT: lwz 1, 0(1)
; 32BIT: mr 1, 30
; 32BIT: lwz 30, -16(1)

; 64BIT-LABEL: .caller:
Expand All @@ -38,5 +38,5 @@ declare void @callee(i32*)
; 64BIT: stdux 1, 1, 0
; 64BIT: addi 3, 1, 128
; 64BIT: bl .callee
; 64BIT: ld 1, 0(1)
; 64BIT: mr 1, 30
; 64BIT: ld 30, -24(1)
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/PowerPC/pr46759.ll
Expand Up @@ -61,7 +61,7 @@ define void @foo(i32 %vla_size) #0 {
; CHECK-LE-NEXT: .LBB0_6: # %entry
; CHECK-LE-NEXT: addi r3, r1, 2048
; CHECK-LE-NEXT: lbz r3, 0(r3)
; CHECK-LE-NEXT: ld r1, 0(r1)
; CHECK-LE-NEXT: mr r1, r30
; CHECK-LE-NEXT: ld r31, -8(r1)
; CHECK-LE-NEXT: ld r30, -16(r1)
; CHECK-LE-NEXT: blr
Expand Down
16 changes: 8 additions & 8 deletions llvm/test/CodeGen/PowerPC/stack-clash-prologue.ll
Expand Up @@ -544,7 +544,7 @@ define i32 @f8(i64 %i) local_unnamed_addr #0 {
; CHECK-LE-NEXT: li r5, 1
; CHECK-LE-NEXT: stwx r5, r4, r3
; CHECK-LE-NEXT: lwz r3, 64(r1)
; CHECK-LE-NEXT: ld r1, 0(r1)
; CHECK-LE-NEXT: mr r1, r30
; CHECK-LE-NEXT: ld r30, -16(r1)
; CHECK-LE-NEXT: blr
;
Expand All @@ -562,7 +562,7 @@ define i32 @f8(i64 %i) local_unnamed_addr #0 {
; CHECK-BE-NEXT: sldi r3, r3, 2
; CHECK-BE-NEXT: stwx r5, r4, r3
; CHECK-BE-NEXT: lwz r3, 64(r1)
; CHECK-BE-NEXT: ld r1, 0(r1)
; CHECK-BE-NEXT: mr r1, r30
; CHECK-BE-NEXT: ld r30, -16(r1)
; CHECK-BE-NEXT: blr
;
Expand Down Expand Up @@ -631,7 +631,7 @@ define i32 @f9(i64 %i) local_unnamed_addr #0 {
; CHECK-LE-NEXT: li r5, 1
; CHECK-LE-NEXT: stwx r5, r4, r3
; CHECK-LE-NEXT: lwz r3, 2048(r1)
; CHECK-LE-NEXT: ld r1, 0(r1)
; CHECK-LE-NEXT: mr r1, r30
; CHECK-LE-NEXT: ld r30, -16(r1)
; CHECK-LE-NEXT: blr
;
Expand Down Expand Up @@ -669,7 +669,7 @@ define i32 @f9(i64 %i) local_unnamed_addr #0 {
; CHECK-BE-NEXT: sldi r3, r3, 2
; CHECK-BE-NEXT: stwx r5, r4, r3
; CHECK-BE-NEXT: lwz r3, 2048(r1)
; CHECK-BE-NEXT: ld r1, 0(r1)
; CHECK-BE-NEXT: mr r1, r30
; CHECK-BE-NEXT: ld r30, -16(r1)
; CHECK-BE-NEXT: blr
;
Expand Down Expand Up @@ -743,7 +743,7 @@ define i32 @f10(i64 %i) local_unnamed_addr #0 {
; CHECK-LE-NEXT: li r5, 1
; CHECK-LE-NEXT: stwx r5, r4, r3
; CHECK-LE-NEXT: lwz r3, 1024(r1)
; CHECK-LE-NEXT: ld r1, 0(r1)
; CHECK-LE-NEXT: mr r1, r30
; CHECK-LE-NEXT: ld r30, -16(r1)
; CHECK-LE-NEXT: blr
;
Expand Down Expand Up @@ -780,7 +780,7 @@ define i32 @f10(i64 %i) local_unnamed_addr #0 {
; CHECK-BE-NEXT: sldi r3, r3, 2
; CHECK-BE-NEXT: stwx r5, r4, r3
; CHECK-BE-NEXT: lwz r3, 1024(r1)
; CHECK-BE-NEXT: ld r1, 0(r1)
; CHECK-BE-NEXT: mr r1, r30
; CHECK-BE-NEXT: ld r30, -16(r1)
; CHECK-BE-NEXT: blr
;
Expand Down Expand Up @@ -884,7 +884,7 @@ define void @f11(i32 %vla_size, i64 %i) #0 {
; CHECK-LE-NEXT: .LBB11_8:
; CHECK-LE-NEXT: addi r3, r1, -32768
; CHECK-LE-NEXT: lbz r3, 0(r3)
; CHECK-LE-NEXT: ld r1, 0(r1)
; CHECK-LE-NEXT: mr r1, r30
; CHECK-LE-NEXT: ld r31, -8(r1)
; CHECK-LE-NEXT: ld r30, -16(r1)
; CHECK-LE-NEXT: blr
Expand Down Expand Up @@ -954,7 +954,7 @@ define void @f11(i32 %vla_size, i64 %i) #0 {
; CHECK-BE-NEXT: .LBB11_8:
; CHECK-BE-NEXT: addi r3, r1, -32768
; CHECK-BE-NEXT: lbz r3, 0(r3)
; CHECK-BE-NEXT: ld r1, 0(r1)
; CHECK-BE-NEXT: mr r1, r30
; CHECK-BE-NEXT: ld r31, -8(r1)
; CHECK-BE-NEXT: ld r30, -16(r1)
; CHECK-BE-NEXT: blr
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/PowerPC/stack-realign.ll
Expand Up @@ -43,7 +43,7 @@ entry:

; CHECK: std 3, 48(30)

; CHECK: ld 1, 0(1)
; CHECK: mr 1, 30
; CHECK-DAG: ld [[SR:[0-9]+]], 16(1)
; CHECK-DAG: ld 30, -16(1)
; CHECK-DAG: mtlr [[SR]]
Expand All @@ -69,7 +69,7 @@ entry:

; CHECK-FP: std 3, 48(30)

; CHECK-FP: ld 1, 0(1)
; CHECK-FP: mr 1, 30
; CHECK-FP-DAG: ld [[SR:[0-9]+]], 16(1)
; CHECK-FP-DAG: ld 31, -8(1)
; CHECK-FP-DAG: ld 30, -16(1)
Expand Down

0 comments on commit ba1202a

Please sign in to comment.