diff --git a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp index 9eeccc25e1e6a..0f43ccf630974 100644 --- a/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp +++ b/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp @@ -315,9 +315,10 @@ void SystemZFrameLowering:: processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS) const { MachineFrameInfo &MFFrame = MF.getFrameInfo(); + bool BackChain = MF.getFunction().hasFnAttribute("backchain"); - if (!usePackedStack(MF)) - // Always create the full incoming register save area. + if (!usePackedStack(MF) || BackChain) + // Create the incoming register save area. getOrCreateFramePointerSaveIndex(MF); // Get the size of our stack frame to be allocated ... diff --git a/llvm/test/CodeGen/SystemZ/frame-25.ll b/llvm/test/CodeGen/SystemZ/frame-25.ll new file mode 100644 index 0000000000000..64c175bd4ecaa --- /dev/null +++ b/llvm/test/CodeGen/SystemZ/frame-25.ll @@ -0,0 +1,24 @@ +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s +; +; Test that space is allocated for the incoming back chain also in cases +; where no GPRs are saved / restored. + +define void @fun0() #0 { +; CHECK-LABEL: fun0: +; CHECK: lgr %r1, %r15 +; CHECK-NEXT: aghi %r15, -24 +; CHECK-NEXT: stg %r1, 152(%r15) +; CHECK-NEXT: #APP +; CHECK-NEXT: stcke 160(%r15) +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: aghi %r15, 24 +; CHECK-NEXT: br %r14 + +entry: + %b = alloca [16 x i8], align 1 + %0 = getelementptr inbounds [16 x i8], [16 x i8]* %b, i64 0, i64 0 + call void asm "stcke $0", "=*Q"([16 x i8]* nonnull %b) #2 + ret void +} + +attributes #0 = { nounwind "packed-stack" "backchain" "use-soft-float"="true" }