[llvm] 99e0066 - [PowerPC] Fix return address computation for "__builtin_return_address"
Victor Huang via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 12 08:15:25 PDT 2021
Author: Victor Huang
Date: 2021-08-12T09:44:49-05:00
New Revision: 99e00663d4cd13b0c296380147ef3f53a2172fbf
URL: https://github.com/llvm/llvm-project/commit/99e00663d4cd13b0c296380147ef3f53a2172fbf
DIFF: https://github.com/llvm/llvm-project/commit/99e00663d4cd13b0c296380147ef3f53a2172fbf.diff
LOG: [PowerPC] Fix return address computation for "__builtin_return_address"
When depth > 0, callee frame address is used to compute the return address of
callee producing improper return address. This patch adds the fix to use caller
frame address to compute the return address of callee.
Reviewed By: nemanjai, #powerpc
Differential revision: https://reviews.llvm.org/D107646
Added:
llvm/test/CodeGen/PowerPC/retaddr_multi_levels.ll
Modified:
llvm/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 37358176f35e6..6d38b39f48238 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -15960,7 +15960,12 @@ SDValue PPCTargetLowering::LowerRETURNADDR(SDValue Op,
auto PtrVT = getPointerTy(MF.getDataLayout());
if (Depth > 0) {
- SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
+ // The link register (return address) is saved in the caller's frame
+ // not the callee's stack frame. So we must get the caller's frame
+ // address and load the return address at the LR offset from there.
+ SDValue FrameAddr =
+ DAG.getLoad(Op.getValueType(), dl, DAG.getEntryNode(),
+ LowerFRAMEADDR(Op, DAG), MachinePointerInfo());
SDValue Offset =
DAG.getConstant(Subtarget.getFrameLowering()->getReturnSaveOffset(), dl,
isPPC64 ? MVT::i64 : MVT::i32);
diff --git a/llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll b/llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll
index 170a82afc77d6..055cd4455866a 100644
--- a/llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll
+++ b/llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll
@@ -23,6 +23,7 @@ define i8* @g() nounwind readnone {
; CHECK-NEXT: stw 0, 4(1)
; CHECK-NEXT: stwu 1, -16(1)
; CHECK-NEXT: lwz 3, 0(1)
+; CHECK-NEXT: lwz 3, 0(3)
; CHECK-NEXT: lwz 3, 4(3)
; CHECK-NEXT: lwz 0, 20(1)
; CHECK-NEXT: addi 1, 1, 16
diff --git a/llvm/test/CodeGen/PowerPC/retaddr_multi_levels.ll b/llvm/test/CodeGen/PowerPC/retaddr_multi_levels.ll
new file mode 100644
index 0000000000000..7e55f05f1df97
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/retaddr_multi_levels.ll
@@ -0,0 +1,140 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux \
+; RUN: -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-64B-LE
+; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux \
+; RUN: -mcpu=pwr7 | FileCheck %s -check-prefix=CHECK-64B-BE
+; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-aix \
+; RUN: -mcpu=pwr7 | FileCheck %s -check-prefix=CHECK-64B-BE
+; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-aix \
+; RUN: -mcpu=pwr7 | FileCheck %s -check-prefix=CHECK-32B-BE
+
+declare i8* @llvm.returnaddress(i32) nounwind readnone
+
+define i8* @test0() nounwind readnone {
+; CHECK-64B-LE-LABEL: test0:
+; CHECK-64B-LE: # %bb.0: # %entry
+; CHECK-64B-LE-NEXT: mflr 0
+; CHECK-64B-LE-NEXT: std 0, 16(1)
+; CHECK-64B-LE-NEXT: stdu 1, -32(1)
+; CHECK-64B-LE-NEXT: ld 3, 48(1)
+; CHECK-64B-LE-NEXT: addi 1, 1, 32
+; CHECK-64B-LE-NEXT: ld 0, 16(1)
+; CHECK-64B-LE-NEXT: mtlr 0
+; CHECK-64B-LE-NEXT: blr
+;
+; CHECK-64B-BE-LABEL: test0:
+; CHECK-64B-BE: # %bb.0: # %entry
+; CHECK-64B-BE-NEXT: mflr 0
+; CHECK-64B-BE-NEXT: std 0, 16(1)
+; CHECK-64B-BE-NEXT: stdu 1, -48(1)
+; CHECK-64B-BE-NEXT: ld 3, 64(1)
+; CHECK-64B-BE-NEXT: addi 1, 1, 48
+; CHECK-64B-BE-NEXT: ld 0, 16(1)
+; CHECK-64B-BE-NEXT: mtlr 0
+; CHECK-64B-BE-NEXT: blr
+;
+; CHECK-32B-BE-LABEL: test0:
+; CHECK-32B-BE: # %bb.0: # %entry
+; CHECK-32B-BE-NEXT: mflr 0
+; CHECK-32B-BE-NEXT: stw 0, 8(1)
+; CHECK-32B-BE-NEXT: stwu 1, -32(1)
+; CHECK-32B-BE-NEXT: lwz 3, 40(1)
+; CHECK-32B-BE-NEXT: addi 1, 1, 32
+; CHECK-32B-BE-NEXT: lwz 0, 8(1)
+; CHECK-32B-BE-NEXT: mtlr 0
+; CHECK-32B-BE-NEXT: blr
+entry:
+ %0 = tail call i8* @llvm.returnaddress(i32 0);
+ ret i8* %0
+}
+
+define i8* @test1() nounwind readnone {
+; CHECK-64B-LE-LABEL: test1:
+; CHECK-64B-LE: # %bb.0: # %entry
+; CHECK-64B-LE-NEXT: mflr 0
+; CHECK-64B-LE-NEXT: std 0, 16(1)
+; CHECK-64B-LE-NEXT: stdu 1, -32(1)
+; CHECK-64B-LE-NEXT: ld 3, 0(1)
+; CHECK-64B-LE-NEXT: ld 3, 0(3)
+; CHECK-64B-LE-NEXT: ld 3, 16(3)
+; CHECK-64B-LE-NEXT: addi 1, 1, 32
+; CHECK-64B-LE-NEXT: ld 0, 16(1)
+; CHECK-64B-LE-NEXT: mtlr 0
+; CHECK-64B-LE-NEXT: blr
+;
+; CHECK-64B-BE-LABEL: test1:
+; CHECK-64B-BE: # %bb.0: # %entry
+; CHECK-64B-BE-NEXT: mflr 0
+; CHECK-64B-BE-NEXT: std 0, 16(1)
+; CHECK-64B-BE-NEXT: stdu 1, -48(1)
+; CHECK-64B-BE-NEXT: ld 3, 0(1)
+; CHECK-64B-BE-NEXT: ld 3, 0(3)
+; CHECK-64B-BE-NEXT: ld 3, 16(3)
+; CHECK-64B-BE-NEXT: addi 1, 1, 48
+; CHECK-64B-BE-NEXT: ld 0, 16(1)
+; CHECK-64B-BE-NEXT: mtlr 0
+; CHECK-64B-BE-NEXT: blr
+;
+; CHECK-32B-BE-LABEL: test1:
+; CHECK-32B-BE: # %bb.0: # %entry
+; CHECK-32B-BE-NEXT: mflr 0
+; CHECK-32B-BE-NEXT: stw 0, 8(1)
+; CHECK-32B-BE-NEXT: stwu 1, -32(1)
+; CHECK-32B-BE-NEXT: lwz 3, 0(1)
+; CHECK-32B-BE-NEXT: lwz 3, 0(3)
+; CHECK-32B-BE-NEXT: lwz 3, 8(3)
+; CHECK-32B-BE-NEXT: addi 1, 1, 32
+; CHECK-32B-BE-NEXT: lwz 0, 8(1)
+; CHECK-32B-BE-NEXT: mtlr 0
+; CHECK-32B-BE-NEXT: blr
+entry:
+ %0 = tail call i8* @llvm.returnaddress(i32 1);
+ ret i8* %0
+}
+
+define i8* @test2() nounwind readnone {
+; CHECK-64B-LE-LABEL: test2:
+; CHECK-64B-LE: # %bb.0: # %entry
+; CHECK-64B-LE-NEXT: mflr 0
+; CHECK-64B-LE-NEXT: std 0, 16(1)
+; CHECK-64B-LE-NEXT: stdu 1, -32(1)
+; CHECK-64B-LE-NEXT: ld 3, 0(1)
+; CHECK-64B-LE-NEXT: ld 3, 0(3)
+; CHECK-64B-LE-NEXT: ld 3, 0(3)
+; CHECK-64B-LE-NEXT: ld 3, 16(3)
+; CHECK-64B-LE-NEXT: addi 1, 1, 32
+; CHECK-64B-LE-NEXT: ld 0, 16(1)
+; CHECK-64B-LE-NEXT: mtlr 0
+; CHECK-64B-LE-NEXT: blr
+;
+; CHECK-64B-BE-LABEL: test2:
+; CHECK-64B-BE: # %bb.0: # %entry
+; CHECK-64B-BE-NEXT: mflr 0
+; CHECK-64B-BE-NEXT: std 0, 16(1)
+; CHECK-64B-BE-NEXT: stdu 1, -48(1)
+; CHECK-64B-BE-NEXT: ld 3, 0(1)
+; CHECK-64B-BE-NEXT: ld 3, 0(3)
+; CHECK-64B-BE-NEXT: ld 3, 0(3)
+; CHECK-64B-BE-NEXT: ld 3, 16(3)
+; CHECK-64B-BE-NEXT: addi 1, 1, 48
+; CHECK-64B-BE-NEXT: ld 0, 16(1)
+; CHECK-64B-BE-NEXT: mtlr 0
+; CHECK-64B-BE-NEXT: blr
+;
+; CHECK-32B-BE-LABEL: test2:
+; CHECK-32B-BE: # %bb.0: # %entry
+; CHECK-32B-BE-NEXT: mflr 0
+; CHECK-32B-BE-NEXT: stw 0, 8(1)
+; CHECK-32B-BE-NEXT: stwu 1, -32(1)
+; CHECK-32B-BE-NEXT: lwz 3, 0(1)
+; CHECK-32B-BE-NEXT: lwz 3, 0(3)
+; CHECK-32B-BE-NEXT: lwz 3, 0(3)
+; CHECK-32B-BE-NEXT: lwz 3, 8(3)
+; CHECK-32B-BE-NEXT: addi 1, 1, 32
+; CHECK-32B-BE-NEXT: lwz 0, 8(1)
+; CHECK-32B-BE-NEXT: mtlr 0
+; CHECK-32B-BE-NEXT: blr
+entry:
+ %0 = tail call i8* @llvm.returnaddress(i32 2);
+ ret i8* %0
+}
More information about the llvm-commits
mailing list