From: Anton Korobeynikov Date: Thu, 16 Jul 2009 13:58:24 +0000 (+0000) Subject: Proper lower 'small' results X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=22836d1b31e553ef3b60cede659889365aaf672a;p=oota-llvm.git Proper lower 'small' results git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75962 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 415ab724dce..87ea5c3ddaa 100644 --- a/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -361,10 +361,27 @@ SystemZTargetLowering::LowerCallResult(SDValue Chain, SDValue InFlag, // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { - Chain = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), - RVLocs[i].getValVT(), InFlag).getValue(1); + CCValAssign &VA = RVLocs[i]; + + Chain = DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), + VA.getLocVT(), InFlag).getValue(1); + SDValue RetValue = Chain.getValue(0); InFlag = Chain.getValue(2); - ResultVals.push_back(Chain.getValue(0)); + + // If this is an 8/16/32-bit value, it is really passed promoted to 64 + // bits. Insert an assert[sz]ext to capture this, then truncate to the + // right size. + if (VA.getLocInfo() == CCValAssign::SExt) + RetValue = DAG.getNode(ISD::AssertSext, dl, VA.getLocVT(), RetValue, + DAG.getValueType(VA.getValVT())); + else if (VA.getLocInfo() == CCValAssign::ZExt) + RetValue = DAG.getNode(ISD::AssertZext, dl, VA.getLocVT(), RetValue, + DAG.getValueType(VA.getValVT())); + + if (VA.getLocInfo() != CCValAssign::Full) + RetValue = DAG.getNode(ISD::TRUNCATE, dl, VA.getValVT(), RetValue); + + ResultVals.push_back(RetValue); } ResultVals.push_back(Chain); diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 34152fe32b3..d1d9d2d670c 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -304,7 +304,7 @@ let isBranch = 1, isTerminator = 1 in { let isCall = 1 in // All calls clobber the non-callee saved registers (except R14 which we // handle separately). Uses for argument registers are added manually. - let Defs = [R0D, R1D, R3D, R4D, R5D] in { + let Defs = [R0D, R1D, R2D, R3D, R4D, R5D] in { def CALLi : Pseudo<(outs), (ins i64imm:$dst, variable_ops), "brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>; def CALLr : Pseudo<(outs), (ins ADDR64:$dst, variable_ops), diff --git a/test/CodeGen/SystemZ/2009-05-29-InvalidRetResult.ll b/test/CodeGen/SystemZ/2009-05-29-InvalidRetResult.ll new file mode 100644 index 00000000000..6bae51d9511 --- /dev/null +++ b/test/CodeGen/SystemZ/2009-05-29-InvalidRetResult.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc + +target datalayout = "E-p:64:64:64-i1:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128" +target triple = "s390x-unknown-linux-gnu" + +define i32 @main() nounwind { +entry: + %call = call i32 (...)* @random() nounwind ; [#uses=0] + unreachable +} + +declare i32 @random(...)