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

Reply via email to