Index: lib/Target/SystemZ/SystemZISelDAGToDAG.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -554,6 +554,10 @@ expandDisp(AM, true, SDValue(), cast(Addr)->getSExtValue())) ; + // Also see if it's a bare ADJDYNALLOC. + else if (Addr.getOpcode() == SystemZISD::ADJDYNALLOC && + expandAdjDynAlloc(AM, true, SDValue())) + ; else // Otherwise try expanding each component. while (expandAddress(AM, true) || Index: lib/Target/SystemZ/SystemZISelLowering.h =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.h +++ lib/Target/SystemZ/SystemZISelLowering.h @@ -487,6 +487,7 @@ SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const; SDValue lowerVACOPY(SDValue Op, SelectionDAG &DAG) const; SDValue lowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; + SDValue lowerGET_DYNAMIC_AREA_OFFSET(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; SDValue lowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; SDValue lowerSDIVREM(SDValue Op, SelectionDAG &DAG) const; Index: lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- lib/Target/SystemZ/SystemZISelLowering.cpp +++ lib/Target/SystemZ/SystemZISelLowering.cpp @@ -253,6 +253,7 @@ // We need to handle dynamic allocations specially because of the // 160-byte area at the bottom of the stack. setOperationAction(ISD::DYNAMIC_STACKALLOC, PtrVT, Custom); + setOperationAction(ISD::GET_DYNAMIC_AREA_OFFSET, PtrVT, Custom); // Use custom expanders so that we can force the function to use // a frame pointer. @@ -2889,6 +2890,13 @@ return DAG.getMergeValues(Ops, DL); } +SDValue SystemZTargetLowering::lowerGET_DYNAMIC_AREA_OFFSET( + SDValue Op, SelectionDAG &DAG) const { + SDLoc DL(Op); + + return DAG.getNode(SystemZISD::ADJDYNALLOC, DL, MVT::i64); +} + SDValue SystemZTargetLowering::lowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const { EVT VT = Op.getValueType(); @@ -4458,6 +4466,8 @@ return lowerVACOPY(Op, DAG); case ISD::DYNAMIC_STACKALLOC: return lowerDYNAMIC_STACKALLOC(Op, DAG); + case ISD::GET_DYNAMIC_AREA_OFFSET: + return lowerGET_DYNAMIC_AREA_OFFSET(Op, DAG); case ISD::SMUL_LOHI: return lowerSMUL_LOHI(Op, DAG); case ISD::UMUL_LOHI: Index: test/CodeGen/SystemZ/dyn-alloca-offset.ll =================================================================== --- /dev/null +++ test/CodeGen/SystemZ/dyn-alloca-offset.ll @@ -0,0 +1,42 @@ +; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s + +declare i64 @llvm.get.dynamic.area.offset.i64() + +declare void @use(i64) + +define void @f1() { +; CHECK-LABEL: f1 +; CHECK: la %r2, 160 +; CHECK: brasl %r14, use +; CHECK: br %r14 + %tmp = alloca i64, align 32 + %dynamic_area_offset = call i64 @llvm.get.dynamic.area.offset.i64() + call void @use(i64 %dynamic_area_offset) + ret void +} + +define void @f2(i64 %arg) { +; CHECK-LABEL: f2 +; CHECK: la %r2, 160(%r2) +; CHECK: brasl %r14, use +; CHECK: br %r14 + %tmp = alloca i64, align 32 + %dynamic_area_offset = call i64 @llvm.get.dynamic.area.offset.i64() + %param = add i64 %dynamic_area_offset, %arg + call void @use(i64 %param) + ret void +} + +declare void @eatsalot(i64, i64, i64, i64, i64, i64) + +define void @f3() { +; CHECK-LABEL: f3 +; CHECK: la %r2, 168 +; CHECK: brasl %r14, use +; CHECK: br %r14 + %tmp = alloca i64, align 32 + call void @eatsalot(i64 0, i64 0, i64 0, i64 0, i64 0, i64 0) + %dynamic_area_offset = call i64 @llvm.get.dynamic.area.offset.i64() + call void @use(i64 %dynamic_area_offset) + ret void +}