From 7ea1ca6229ca228a1a3a0ff453c3530bf4f7a26e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Oct 2008 20:00:42 +0000 Subject: [PATCH] Fix SelectionDAGBuild lowering of Select instructions to handle first-class aggregate values. Also, fix a bug in the Ret handling for empty aggregates. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57925 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../SelectionDAG/SelectionDAGBuild.cpp | 30 ++++++++++++++----- test/CodeGen/X86/pr2924.ll | 24 +++++++++++++++ 2 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 test/CodeGen/X86/pr2924.ll diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index ed9edf10672..d04daeb76b5 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -902,11 +902,13 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) { SmallVector NewValues; NewValues.push_back(getControlRoot()); for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) { - SDValue RetOp = getValue(I.getOperand(i)); - SmallVector ValueVTs; ComputeValueVTs(TLI, I.getOperand(i)->getType(), ValueVTs); - for (unsigned j = 0, f = ValueVTs.size(); j != f; ++j) { + unsigned NumValues = ValueVTs.size(); + if (NumValues == 0) continue; + + SDValue RetOp = getValue(I.getOperand(i)); + for (unsigned j = 0, f = NumValues; j != f; ++j) { MVT VT = ValueVTs[j]; // FIXME: C calling convention requires the return type to be promoted to @@ -2137,11 +2139,23 @@ void SelectionDAGLowering::visitVFCmp(User &I) { } void SelectionDAGLowering::visitSelect(User &I) { - SDValue Cond = getValue(I.getOperand(0)); - SDValue TrueVal = getValue(I.getOperand(1)); - SDValue FalseVal = getValue(I.getOperand(2)); - setValue(&I, DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond, - TrueVal, FalseVal)); + SmallVector ValueVTs; + ComputeValueVTs(TLI, I.getType(), ValueVTs); + unsigned NumValues = ValueVTs.size(); + if (NumValues != 0) { + SmallVector Values(NumValues); + SDValue Cond = getValue(I.getOperand(0)); + SDValue TrueVal = getValue(I.getOperand(1)); + SDValue FalseVal = getValue(I.getOperand(2)); + + for (unsigned i = 0; i != NumValues; ++i) + Values[i] = DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond, + SDValue(TrueVal.getNode(), TrueVal.getResNo() + i), + SDValue(FalseVal.getNode(), FalseVal.getResNo() + i)); + + setValue(&I, DAG.getMergeValues(DAG.getVTList(&ValueVTs[0], NumValues), + &Values[0], NumValues)); + } } diff --git a/test/CodeGen/X86/pr2924.ll b/test/CodeGen/X86/pr2924.ll new file mode 100644 index 00000000000..2cab5631165 --- /dev/null +++ b/test/CodeGen/X86/pr2924.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | llc +; PR2924 + +target datalayout = +"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i686-pc-linux-gnu" + +define x86_stdcallcc { i32, i8* } @_D3std6string7toupperFAaZAa({ i32, i8* } %s) { +entry_std.string.toupper: + %tmp58 = load i32* null + %tmp59 = icmp eq i32 %tmp58, 0 + %r.val = load { i32, i8* }* null, align 8 + %condtmp.0 = select i1 %tmp59, { i32, i8* } undef, { i32, i8* } %r.val + + ret { i32, i8* } %condtmp.0 +} +define { } @empty({ } %s) { +entry_std.string.toupper: + %tmp58 = load i32* null + %tmp59 = icmp eq i32 %tmp58, 0 + %r.val = load { }* null, align 8 + %condtmp.0 = select i1 %tmp59, { } undef, { } %r.val + ret { } %condtmp.0 +}