From 053546c31e4752e3d76e1f0915ddd6c8a3280351 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 25 May 2011 02:20:00 +0000 Subject: [PATCH] Fix lowering of DYNAMIC_STACKALLOC nodes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132030 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Mips/MipsISelLowering.cpp | 22 ++++++++++++++++++++-- test/CodeGen/Mips/alloca.ll | 31 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/Mips/alloca.ll diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index cec19173c6f..93e7a23ac47 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -692,6 +692,13 @@ LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const SDValue MipsTargetLowering:: LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const { + unsigned StackAlignment = + getTargetMachine().getFrameLowering()->getStackAlignment(); + assert(StackAlignment >= + cast(Op.getOperand(2).getNode())->getZExtValue() && + "Cannot lower if the alignment of the allocated space is larger than \ + that of the stack."); + SDValue Chain = Op.getOperand(0); SDValue Size = Op.getOperand(1); DebugLoc dl = Op.getDebugLoc(); @@ -705,11 +712,22 @@ LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const // The Sub result contains the new stack start address, so it // must be placed in the stack pointer register. - Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub); + Chain = DAG.getCopyToReg(StackPointer.getValue(1), dl, Mips::SP, Sub, + SDValue()); + SDValue NewSP = DAG.getCopyFromReg(Chain, dl, Mips::SP, MVT::i32, + Chain.getValue(1)); + + // Align the allocated space. + MachineFunction &MF = DAG.getMachineFunction(); + MipsFunctionInfo *MipsFI = MF.getInfo(); + unsigned SPOffset = (MipsFI->getMaxCallFrameSize() + StackAlignment - 1) / + StackAlignment * StackAlignment; + SDValue AllocPtr = DAG.getNode(ISD::ADD, dl, MVT::i32, NewSP, + DAG.getConstant(SPOffset, MVT::i32)); // This node always has two return values: a new stack pointer // value and a chain - SDValue Ops[2] = { Sub, Chain }; + SDValue Ops[2] = { AllocPtr, NewSP.getValue(1) }; return DAG.getMergeValues(Ops, 2, dl); } diff --git a/test/CodeGen/Mips/alloca.ll b/test/CodeGen/Mips/alloca.ll new file mode 100644 index 00000000000..50eeecf991f --- /dev/null +++ b/test/CodeGen/Mips/alloca.ll @@ -0,0 +1,31 @@ +; RUN: llc -march=mipsel -mcpu=4ke < %s | FileCheck %s + +define i32 @twoalloca(i32 %size) nounwind { +entry: +; CHECK: subu $[[T0:[0-9]+]], $sp, $[[SZ:[0-9]+]] +; CHECK: addu $sp, $zero, $[[T0]] +; CHECK: addu $[[SP1:[0-9]+]], $zero, $sp +; CHECK: subu $[[T1:[0-9]+]], $sp, $[[SZ]] +; CHECK: addu $sp, $zero, $[[T1]] +; CHECK: addu $[[SP2:[0-9]+]], $zero, $sp +; CHECK: lw $25, %call16(foo)($gp) +; CHECK: addiu $4, $[[SP1]], 24 +; CHECK: jalr $25 +; CHECK: lw $25, %call16(foo)($gp) +; CHECK: addiu $4, $[[SP2]], 24 +; CHECK: jalr $25 + %tmp1 = alloca i8, i32 %size, align 4 + %add.ptr = getelementptr inbounds i8* %tmp1, i32 5 + store i8 97, i8* %add.ptr, align 1 + %tmp4 = alloca i8, i32 %size, align 4 + call void @foo2(double 1.000000e+00, double 2.000000e+00, i32 3) nounwind + %call = call i32 @foo(i8* %tmp1) nounwind + %call7 = call i32 @foo(i8* %tmp4) nounwind + %add = add nsw i32 %call7, %call + ret i32 %add +} + +declare void @foo2(double, double, i32) + +declare i32 @foo(i8*) + -- 2.11.0