NeHuang created this revision. NeHuang added reviewers: nemanjai, stefanp, PowerPC. NeHuang added a project: LLVM. Herald added subscribers: shchenz, kbarton, hiraditya. NeHuang requested review of this revision.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D107646 Files: llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll llvm/test/CodeGen/PowerPC/retaddr_multi_levels.ll
Index: llvm/test/CodeGen/PowerPC/retaddr_multi_levels.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/PowerPC/retaddr_multi_levels.ll @@ -0,0 +1,174 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64le-unknown-linux -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-64B-LE +; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux -mcpu=pwr7 | FileCheck %s -check-prefix=CHECK-64B-BE +; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-aix -mcpu=pwr7 | FileCheck %s -check-prefix=CHECK-64B-AIX +; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-aix -mcpu=pwr7 | FileCheck %s -check-prefix=CHECK-32B-AIX + +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-64B-AIX-LABEL: test0: +; CHECK-64B-AIX: # %bb.0: # %entry +; CHECK-64B-AIX-NEXT: mflr 0 +; CHECK-64B-AIX-NEXT: std 0, 16(1) +; CHECK-64B-AIX-NEXT: stdu 1, -48(1) +; CHECK-64B-AIX-NEXT: ld 3, 64(1) +; CHECK-64B-AIX-NEXT: addi 1, 1, 48 +; CHECK-64B-AIX-NEXT: ld 0, 16(1) +; CHECK-64B-AIX-NEXT: mtlr 0 +; CHECK-64B-AIX-NEXT: blr +; +; CHECK-32B-AIX-LABEL: test0: +; CHECK-32B-AIX: # %bb.0: # %entry +; CHECK-32B-AIX-NEXT: mflr 0 +; CHECK-32B-AIX-NEXT: stw 0, 8(1) +; CHECK-32B-AIX-NEXT: stwu 1, -32(1) +; CHECK-32B-AIX-NEXT: lwz 3, 40(1) +; CHECK-32B-AIX-NEXT: addi 1, 1, 32 +; CHECK-32B-AIX-NEXT: lwz 0, 8(1) +; CHECK-32B-AIX-NEXT: mtlr 0 +; CHECK-32B-AIX-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-64B-AIX-LABEL: test1: +; CHECK-64B-AIX: # %bb.0: # %entry +; CHECK-64B-AIX-NEXT: mflr 0 +; CHECK-64B-AIX-NEXT: std 0, 16(1) +; CHECK-64B-AIX-NEXT: stdu 1, -48(1) +; CHECK-64B-AIX-NEXT: ld 3, 0(1) +; CHECK-64B-AIX-NEXT: ld 3, 0(3) +; CHECK-64B-AIX-NEXT: ld 3, 16(3) +; CHECK-64B-AIX-NEXT: addi 1, 1, 48 +; CHECK-64B-AIX-NEXT: ld 0, 16(1) +; CHECK-64B-AIX-NEXT: mtlr 0 +; CHECK-64B-AIX-NEXT: blr +; +; CHECK-32B-AIX-LABEL: test1: +; CHECK-32B-AIX: # %bb.0: # %entry +; CHECK-32B-AIX-NEXT: mflr 0 +; CHECK-32B-AIX-NEXT: stw 0, 8(1) +; CHECK-32B-AIX-NEXT: stwu 1, -32(1) +; CHECK-32B-AIX-NEXT: lwz 3, 0(1) +; CHECK-32B-AIX-NEXT: lwz 3, 0(3) +; CHECK-32B-AIX-NEXT: lwz 3, 8(3) +; CHECK-32B-AIX-NEXT: addi 1, 1, 32 +; CHECK-32B-AIX-NEXT: lwz 0, 8(1) +; CHECK-32B-AIX-NEXT: mtlr 0 +; CHECK-32B-AIX-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-64B-AIX-LABEL: test2: +; CHECK-64B-AIX: # %bb.0: # %entry +; CHECK-64B-AIX-NEXT: mflr 0 +; CHECK-64B-AIX-NEXT: std 0, 16(1) +; CHECK-64B-AIX-NEXT: stdu 1, -48(1) +; CHECK-64B-AIX-NEXT: ld 3, 0(1) +; CHECK-64B-AIX-NEXT: ld 3, 0(3) +; CHECK-64B-AIX-NEXT: ld 3, 0(3) +; CHECK-64B-AIX-NEXT: ld 3, 16(3) +; CHECK-64B-AIX-NEXT: addi 1, 1, 48 +; CHECK-64B-AIX-NEXT: ld 0, 16(1) +; CHECK-64B-AIX-NEXT: mtlr 0 +; CHECK-64B-AIX-NEXT: blr +; +; CHECK-32B-AIX-LABEL: test2: +; CHECK-32B-AIX: # %bb.0: # %entry +; CHECK-32B-AIX-NEXT: mflr 0 +; CHECK-32B-AIX-NEXT: stw 0, 8(1) +; CHECK-32B-AIX-NEXT: stwu 1, -32(1) +; CHECK-32B-AIX-NEXT: lwz 3, 0(1) +; CHECK-32B-AIX-NEXT: lwz 3, 0(3) +; CHECK-32B-AIX-NEXT: lwz 3, 0(3) +; CHECK-32B-AIX-NEXT: lwz 3, 8(3) +; CHECK-32B-AIX-NEXT: addi 1, 1, 32 +; CHECK-32B-AIX-NEXT: lwz 0, 8(1) +; CHECK-32B-AIX-NEXT: mtlr 0 +; CHECK-32B-AIX-NEXT: blr +entry: + %0 = tail call i8* @llvm.returnaddress(i32 2); + ret i8* %0 +} Index: llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll =================================================================== --- llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll +++ llvm/test/CodeGen/PowerPC/2010-05-03-retaddr1.ll @@ -1,12 +1,15 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu | FileCheck %s ; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu -regalloc=basic | FileCheck %s declare i8* @llvm.frameaddress(i32) nounwind readnone define i8* @g2() nounwind readnone { +; CHECK-LABEL: g2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: lwz 3, 0(1) +; CHECK-NEXT: blr entry: -; CHECK: g2: -; CHECK: lwz 3, 0(1) %0 = tail call i8* @llvm.frameaddress(i32 1) ; <i8*> [#uses=1] ret i8* %0 } @@ -14,12 +17,19 @@ declare i8* @llvm.returnaddress(i32) nounwind readnone define i8* @g() nounwind readnone { +; CHECK-LABEL: g: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: mflr 0 +; 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 +; CHECK-NEXT: mtlr 0 +; CHECK-NEXT: blr entry: -; CHECK: g: -; CHECK: mflr 0 -; CHECK: stw 0, 4(1) -; CHECK: lwz 3, 4(3) -; CHECK: lwz 0, 20(1) %0 = tail call i8* @llvm.returnaddress(i32 1) ; <i8*> [#uses=1] ret i8* %0 } Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -15960,7 +15960,8 @@ auto PtrVT = getPointerTy(MF.getDataLayout()); if (Depth > 0) { - SDValue FrameAddr = LowerFRAMEADDR(Op, DAG); + 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);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits