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 | d568f6dce2ef3ea9d8e770c19f855f19e6e68d20 (patch) | |
| tree | aa287f721eb4c492a90ecfd932177e33f2f46b6e /llvm | |
| parent | f1bf3176c6932e418fc145667a01502cda3ed81e (diff) | |
| download | bcm5719-llvm-d568f6dce2ef3ea9d8e770c19f855f19e6e68d20.tar.gz bcm5719-llvm-d568f6dce2ef3ea9d8e770c19f855f19e6e68d20.zip | |
Proper lower 'small' results
llvm-svn: 75962
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZISelLowering.cpp | 23 | ||||
| -rw-r--r-- | llvm/lib/Target/SystemZ/SystemZInstrInfo.td | 2 | ||||
| -rw-r--r-- | llvm/test/CodeGen/SystemZ/2009-05-29-InvalidRetResult.ll | 12 |
3 files changed, 33 insertions, 4 deletions
diff --git a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp b/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp index 415ab724dce..87ea5c3ddaa 100644 --- a/llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ b/llvm/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/llvm/lib/Target/SystemZ/SystemZInstrInfo.td b/llvm/lib/Target/SystemZ/SystemZInstrInfo.td index 34152fe32b3..d1d9d2d670c 100644 --- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/llvm/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/llvm/test/CodeGen/SystemZ/2009-05-29-InvalidRetResult.ll b/llvm/test/CodeGen/SystemZ/2009-05-29-InvalidRetResult.ll new file mode 100644 index 00000000000..6bae51d9511 --- /dev/null +++ b/llvm/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(...) |

