diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index ac345af2b23..62c3769ebe6 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -303,7 +303,9 @@ namespace ISD { INSERT_VECTOR_ELT, /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR - /// identified by the (potentially variable) element number IDX. + /// identified by the (potentially variable) element number IDX. If the + /// return type is an integer type larger than the element type of the + /// vector, the result is extended to the width of the return type. EXTRACT_VECTOR_ELT, /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index e31ea85360e..19456417b77 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1526,7 +1526,11 @@ SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) { StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr); - return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0); + if (Op.getValueType().isVector()) + return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0); + else + return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr, + NULL, 0, Vec.getValueType().getVectorElementType()); } SDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index e6c8b4827fe..958f72d0ce2 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -303,52 +303,10 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) { } SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { - MVT OldVT = N->getValueType(0); - SDValue OldVec = N->getOperand(0); - if (getTypeAction(OldVec.getValueType()) == WidenVector) - OldVec = GetWidenedVector(N->getOperand(0)); - unsigned OldElts = OldVec.getValueType().getVectorNumElements(); DebugLoc dl = N->getDebugLoc(); - - if (OldElts == 1) { - assert(!isTypeLegal(OldVec.getValueType()) && - "Legal one-element vector of a type needing promotion!"); - // It is tempting to follow GetScalarizedVector by a call to - // GetPromotedInteger, but this would be wrong because the - // scalarized value may not yet have been processed. - return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), - GetScalarizedVector(OldVec)); - } - - // Convert to a vector half as long with an element type of twice the width, - // for example <4 x i16> -> <2 x i32>. - assert(!(OldElts & 1) && "Odd length vectors not supported!"); - MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits()); - assert(OldVT.isSimple() && NewVT.isSimple()); - - SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl, - MVT::getVectorVT(NewVT, OldElts / 2), - OldVec); - - // Extract the element at OldIdx / 2 from the new vector. - SDValue OldIdx = N->getOperand(1); - SDValue NewIdx = DAG.getNode(ISD::SRL, dl, OldIdx.getValueType(), OldIdx, - DAG.getConstant(1, TLI.getPointerTy())); - SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, NewIdx); - - // Select the appropriate half of the element: Lo if OldIdx was even, - // Hi if it was odd. - SDValue Lo = Elt; - SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt, - DAG.getConstant(OldVT.getSizeInBits(), - TLI.getPointerTy())); - if (TLI.isBigEndian()) - std::swap(Lo, Hi); - - // Extend to the promoted type. - SDValue Odd = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, OldIdx); - SDValue Res = DAG.getNode(ISD::SELECT, dl, NewVT, Odd, Hi, Lo); - return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), Res); + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NVT, N->getOperand(0), + N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { diff --git a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 652c803e2ec..0b6444612bb 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -331,7 +331,11 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) { /// be scalarized, it must be <1 x ty>, so just return the element, ignoring the /// index. SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { - return GetScalarizedVector(N->getOperand(0)); + SDValue Res = GetScalarizedVector(N->getOperand(0)); + if (Res.getValueType() != N->getValueType(0)) + Res = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), + Res); + return Res; } /// ScalarizeVecOp_STORE - If the value to store is a vector that needs to be @@ -1052,7 +1056,8 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { // Load back the required element. StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); - return DAG.getLoad(EltVT, dl, Store, StackPtr, SV, 0); + return DAG.getExtLoad(ISD::EXTLOAD, dl, N->getValueType(0), Store, StackPtr, + SV, 0, EltVT); } SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { @@ -1904,9 +1909,8 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { SDValue InOp = GetWidenedVector(N->getOperand(0)); - MVT EltVT = InOp.getValueType().getVectorElementType(); return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(), - EltVT, InOp, N->getOperand(1)); + N->getValueType(0), InOp, N->getOperand(1)); } SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 2d154942c75..29f0cb22d9a 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2693,13 +2693,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, // expanding large vector constants. if (N2C && N1.getOpcode() == ISD::BUILD_VECTOR) { SDValue Elt = N1.getOperand(N2C->getZExtValue()); - if (Elt.getValueType() != VT) { + MVT VEltTy = N1.getValueType().getVectorElementType(); + if (Elt.getValueType() != VEltTy) { // If the vector element type is not legal, the BUILD_VECTOR operands // are promoted and implicitly truncated. Make that explicit here. - assert(VT.isInteger() && Elt.getValueType().isInteger() && - VT.bitsLE(Elt.getValueType()) && - "Bad type for BUILD_VECTOR operand"); - Elt = getNode(ISD::TRUNCATE, DL, VT, Elt); + Elt = getNode(ISD::TRUNCATE, DL, VEltTy, Elt); + } + if (VT != VEltTy) { + // If the vector element type is not legal, the EXTRACT_VECTOR_ELT + // result is implicitly extended. + Elt = getNode(ISD::ANY_EXTEND, DL, VT, Elt); } return Elt; } diff --git a/test/CodeGen/X86/2009-07-07-SplitICmp.ll b/test/CodeGen/X86/2009-07-07-SplitICmp.ll new file mode 100644 index 00000000000..9a7b52d1523 --- /dev/null +++ b/test/CodeGen/X86/2009-07-07-SplitICmp.ll @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | llc -march=x86 -disable-mmx + +define void @test2(<2 x i32> %A, <2 x i32> %B, <2 x i32>* %C) nounwind { + %D = icmp sgt <2 x i32> %A, %B + %E = zext <2 x i1> %D to <2 x i32> + store <2 x i32> %E, <2 x i32>* %C + ret void +} diff --git a/test/CodeGen/X86/2009-07-09-ExtractBoolFromVector.ll b/test/CodeGen/X86/2009-07-09-ExtractBoolFromVector.ll new file mode 100644 index 00000000000..62a62a69e37 --- /dev/null +++ b/test/CodeGen/X86/2009-07-09-ExtractBoolFromVector.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -march=x86 +; PR3037 + +define void @entry(<4 x i8>* %dest) { + %1 = xor <4 x i1> zeroinitializer, < i1 true, i1 true, i1 true, i1 true > + %2 = extractelement <4 x i1> %1, i32 3 + %3 = zext i1 %2 to i8 + %4 = insertelement <4 x i8> zeroinitializer, i8 %3, i32 3 + store <4 x i8> %4, <4 x i8>* %dest, align 1 + ret void +}