diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -3278,12 +3278,10 @@ unsigned Depth = cast(Op.getOperand(0))->getZExtValue(); EVT PtrVT = getPointerTy(DAG.getDataLayout()); - // Return null if the back chain is not present. - bool HasBackChain = MF.getFunction().hasFnAttribute("backchain"); - if (TFL->usePackedStack(MF) && !HasBackChain) - return DAG.getConstant(0, DL, PtrVT); - - // By definition, the frame address is the address of the back chain. + // By definition, the frame address is the address of the back chain. (In + // the case of packed stack without backchain, return the address where the + // backchain would have been stored. This will either be an unused space or + // contain a saved register). int BackChainIdx = TFL->getOrCreateFramePointerSaveIndex(MF); SDValue BackChain = DAG.getFrameIndex(BackChainIdx, PtrVT); diff --git a/llvm/test/CodeGen/SystemZ/frameaddr-02.ll b/llvm/test/CodeGen/SystemZ/frameaddr-02.ll --- a/llvm/test/CodeGen/SystemZ/frameaddr-02.ll +++ b/llvm/test/CodeGen/SystemZ/frameaddr-02.ll @@ -33,22 +33,41 @@ define i8* @fp1() #1 { entry: ; CHECK-LABEL: fp1: -; CHECK: lghi %r2, 0 +; CHECK: la %r2, 152(%r15) ; CHECK-NEXT: br %r14 %0 = tail call i8* @llvm.frameaddress(i32 0) ret i8* %0 } +; No saved registers: returning address of unused slot where backcahin would +; have been located. define i8* @fp1f() #1 { entry: ; CHECK-LABEL: fp1f: -; CHECK: aghi %r15, -8 -; CHECK-NEXT: lghi %r2, 0 -; CHECK-NEXT: aghi %r15, 8 +; CHECK: aghi %r15, -16 +; CHECK-NEXT: la %r2, 168(%r15) +; CHECK-NEXT: aghi %r15, 16 ; CHECK-NEXT: br %r14 %0 = alloca i64, align 8 %1 = tail call i8* @llvm.frameaddress(i32 0) ret i8* %1 } +; Saved registers: returning address for first saved GPR. +declare void @foo(i8* %Arg) +define i8* @fp2() #1 { +entry: +; CHECK-LABEL: fp2: +; CHECK: stmg %r14, %r15, 144(%r15) +; CHECK-NEXT: aghi %r15, -16 +; CHECK-NEXT: la %r2, 168(%r15) +; CHECK-NEXT: brasl %r14, foo@PLT +; CHECK-NEXT: la %r2, 168(%r15) +; CHECK-NEXT: lmg %r14, %r15, 160(%r15) +; CHECK-NEXT: br %r14 + %0 = tail call i8* @llvm.frameaddress(i32 0) + call void @foo(i8* %0); + ret i8* %0 +} + declare i8* @llvm.frameaddress(i32) nounwind readnone