llvm.org GIT mirror llvm / 9db817f
Make the SelectionDAG verify that all the operands of BUILD_VECTOR have the same type. Teach DAGCombiner::visitINSERT_VECTOR_ELT not to make invalid BUILD_VECTORs. Fixes PR10897. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139407 91177308-0d34-0410-b5e6-96231b3b80d8 Eli Friedman 8 years ago
3 changed file(s) with 61 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
67696769 SDValue InVec = N->getOperand(0);
67706770 SDValue InVal = N->getOperand(1);
67716771 SDValue EltNo = N->getOperand(2);
6772 DebugLoc dl = N->getDebugLoc();
67726773
67736774 // If the inserted element is an UNDEF, just use the input vector.
67746775 if (InVal.getOpcode() == ISD::UNDEF)
67806781 if (LegalOperations && !TLI.isOperationLegal(ISD::BUILD_VECTOR, VT))
67816782 return SDValue();
67826783
6783 // If the invec is a BUILD_VECTOR and if EltNo is a constant, build a new
6784 // vector with the inserted element.
6785 if (InVec.getOpcode() == ISD::BUILD_VECTOR && isa(EltNo)) {
6786 unsigned Elt = cast(EltNo)->getZExtValue();
6787 SmallVector Ops(InVec.getNode()->op_begin(),
6788 InVec.getNode()->op_end());
6789 if (Elt < Ops.size())
6790 Ops[Elt] = InVal;
6791 return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
6792 VT, &Ops[0], Ops.size());
6793 }
6794 // If the invec is an UNDEF and if EltNo is a constant, create a new
6795 // BUILD_VECTOR with undef elements and the inserted element.
6796 if (InVec.getOpcode() == ISD::UNDEF &&
6797 isa(EltNo)) {
6798 EVT EltVT = VT.getVectorElementType();
6784 // Check that we know which element is being inserted
6785 if (!isa(EltNo))
6786 return SDValue();
6787 unsigned Elt = cast(EltNo)->getZExtValue();
6788
6789 // Check that the operand is a BUILD_VECTOR (or UNDEF, which can essentially
6790 // be converted to a BUILD_VECTOR). Fill in the Ops vector with the
6791 // vector elements.
6792 SmallVector Ops;
6793 if (InVec.getOpcode() == ISD::BUILD_VECTOR) {
6794 Ops.append(InVec.getNode()->op_begin(),
6795 InVec.getNode()->op_end());
6796 } else if (InVec.getOpcode() == ISD::UNDEF) {
67996797 unsigned NElts = VT.getVectorNumElements();
6800 SmallVector Ops(NElts, DAG.getUNDEF(EltVT));
6801
6802 unsigned Elt = cast(EltNo)->getZExtValue();
6803 if (Elt < Ops.size())
6804 Ops[Elt] = InVal;
6805 return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
6806 VT, &Ops[0], Ops.size());
6807 }
6808 return SDValue();
6798 Ops.append(NElts, DAG.getUNDEF(InVal.getValueType()));
6799 } else {
6800 return SDValue();
6801 }
6802
6803 // Insert the element
6804 if (Elt < Ops.size()) {
6805 // All the operands of BUILD_VECTOR must have the same type;
6806 // we enforce that here.
6807 EVT OpVT = Ops[0].getValueType();
6808 if (InVal.getValueType() != OpVT)
6809 InVal = OpVT.bitsGT(InVal.getValueType()) ?
6810 DAG.getNode(ISD::ANY_EXTEND, dl, OpVT, InVal) :
6811 DAG.getNode(ISD::TRUNCATE, dl, OpVT, InVal);
6812 Ops[Elt] = InVal;
6813 }
6814
6815 // Return the new vector
6816 return DAG.getNode(ISD::BUILD_VECTOR, dl,
6817 VT, &Ops[0], Ops.size());
68096818 }
68106819
68116820 SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
770770 assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() &&
771771 "Wrong number of operands!");
772772 EVT EltVT = N->getValueType(0).getVectorElementType();
773 for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
773 for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
774774 assert((I->getValueType() == EltVT ||
775775 (EltVT.isInteger() && I->getValueType().isInteger() &&
776776 EltVT.bitsLE(I->getValueType()))) &&
777777 "Wrong operand type!");
778 assert(I->getValueType() == N->getOperand(0).getValueType() &&
779 "Operands must all have the same type");
780 }
778781 break;
779782 }
780783 }
0 ; RUN: llc -mtriple=armv7-- %s -mattr=-neon
1
2 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a0:0:64-n32"
3 target triple = "armv7-none-linux-gnueabi"
4
5 @x1 = common global <3 x i16> zeroinitializer
6 @y1 = common global <3 x i16> zeroinitializer
7 @z1 = common global <3 x i16> zeroinitializer
8 @x2 = common global <4 x i16> zeroinitializer
9 @y2 = common global <4 x i16> zeroinitializer
10 @z2 = common global <4 x i16> zeroinitializer
11
12 define void @f() {
13 %1 = load <3 x i16>* @x1
14 %2 = load <3 x i16>* @y1
15 %3 = sdiv <3 x i16> %1, %2
16 store <3 x i16> %3, <3 x i16>* @z1
17 %4 = load <4 x i16>* @x2
18 %5 = load <4 x i16>* @y2
19 %6 = sdiv <4 x i16> %4, %5
20 store <4 x i16> %6, <4 x i16>* @z2
21 ret void
22 }