diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2009-07-16 13:58:24 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2009-07-16 13:58:24 +0000 |
commit | 22836d1b31e553ef3b60cede659889365aaf672a (patch) | |
tree | 6a889f8362b8d276a8b45270eb50286155926620 | |
parent | eb68f1c661e4699013017a42d7ec785841d8805f (diff) |
Proper lower 'small' results
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75962 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/SystemZ/SystemZISelLowering.cpp | 23 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZInstrInfo.td | 2 | ||||
-rw-r--r-- | test/CodeGen/SystemZ/2009-05-29-InvalidRetResult.ll | 12 |
3 files changed, 33 insertions, 4 deletions
diff --git a/lib/Target/SystemZ/SystemZISelLowering.cpp b/lib/Target/SystemZ/SystemZISelLowering.cpp index 415ab724dc..87ea5c3dda 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 34152fe32b..d1d9d2d670 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 0000000000..6bae51d951 --- /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 ; <i32> [#uses=0] + unreachable +} + +declare i32 @random(...) |