Files
clang-p2996/llvm/test/CodeGen/PowerPC/pr46759.ll
Nemanja Ivanovic ba1202a1e4 [PowerPC] Restore stack ptr from base ptr when available
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
2020-12-22 05:44:03 -06:00

76 lines
2.5 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -ppc-asm-full-reg-names -verify-machineinstrs \
; RUN: -mtriple=powerpc64le-linux-gnu < %s | FileCheck \
; RUN: -check-prefix=CHECK-LE %s
define void @foo(i32 %vla_size) #0 {
; CHECK-LE-LABEL: foo:
; CHECK-LE: # %bb.0: # %entry
; CHECK-LE-NEXT: std r31, -8(r1)
; CHECK-LE-NEXT: std r30, -16(r1)
; CHECK-LE-NEXT: mr r30, r1
; CHECK-LE-NEXT: .cfi_def_cfa r30, 0
; CHECK-LE-NEXT: clrldi r0, r30, 53
; CHECK-LE-NEXT: subc r12, r30, r0
; CHECK-LE-NEXT: clrldi r0, r0, 52
; CHECK-LE-NEXT: cmpdi r0, 0
; CHECK-LE-NEXT: beq cr0, .LBB0_2
; CHECK-LE-NEXT: # %bb.1: # %entry
; CHECK-LE-NEXT: neg r0, r0
; CHECK-LE-NEXT: stdux r30, r1, r0
; CHECK-LE-NEXT: .LBB0_2: # %entry
; CHECK-LE-NEXT: li r0, -4096
; CHECK-LE-NEXT: cmpd r1, r12
; CHECK-LE-NEXT: beq cr0, .LBB0_4
; CHECK-LE-NEXT: .LBB0_3: # %entry
; CHECK-LE-NEXT: #
; CHECK-LE-NEXT: stdux r30, r1, r0
; CHECK-LE-NEXT: cmpd r1, r12
; CHECK-LE-NEXT: bne cr0, .LBB0_3
; CHECK-LE-NEXT: .LBB0_4: # %entry
; CHECK-LE-NEXT: mr r12, r30
; CHECK-LE-NEXT: stdu r12, -2048(r1)
; CHECK-LE-NEXT: stdu r12, -4096(r1)
; CHECK-LE-NEXT: .cfi_def_cfa_register r1
; CHECK-LE-NEXT: .cfi_def_cfa_register r30
; CHECK-LE-NEXT: .cfi_offset r31, -8
; CHECK-LE-NEXT: .cfi_offset r30, -16
; CHECK-LE-NEXT: clrldi r3, r3, 32
; CHECK-LE-NEXT: li r5, -2048
; CHECK-LE-NEXT: mr r31, r1
; CHECK-LE-NEXT: addi r3, r3, 15
; CHECK-LE-NEXT: rldicl r3, r3, 60, 4
; CHECK-LE-NEXT: rldicl r3, r3, 4, 31
; CHECK-LE-NEXT: neg r4, r3
; CHECK-LE-NEXT: ld r3, 0(r1)
; CHECK-LE-NEXT: and r5, r4, r5
; CHECK-LE-NEXT: mr r4, r5
; CHECK-LE-NEXT: li r5, -4096
; CHECK-LE-NEXT: divd r6, r4, r5
; CHECK-LE-NEXT: mulld r5, r6, r5
; CHECK-LE-NEXT: sub r5, r4, r5
; CHECK-LE-NEXT: add r4, r1, r4
; CHECK-LE-NEXT: stdux r3, r1, r5
; CHECK-LE-NEXT: cmpd r1, r4
; CHECK-LE-NEXT: beq cr0, .LBB0_6
; CHECK-LE-NEXT: .LBB0_5: # %entry
; CHECK-LE-NEXT: #
; CHECK-LE-NEXT: stdu r3, -4096(r1)
; CHECK-LE-NEXT: cmpd r1, r4
; CHECK-LE-NEXT: bne cr0, .LBB0_5
; CHECK-LE-NEXT: .LBB0_6: # %entry
; CHECK-LE-NEXT: addi r3, r1, 2048
; CHECK-LE-NEXT: lbz r3, 0(r3)
; CHECK-LE-NEXT: mr r1, r30
; CHECK-LE-NEXT: ld r31, -8(r1)
; CHECK-LE-NEXT: ld r30, -16(r1)
; CHECK-LE-NEXT: blr
entry:
%0 = zext i32 %vla_size to i64
%vla = alloca i8, i64 %0, align 2048
%1 = load volatile i8, i8* %vla, align 2048
ret void
}
attributes #0 = { "probe-stack"="inline-asm" }