mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
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
This commit is contained in:
parent
8ddf6531b8
commit
9db817fd0c
@ -6770,6 +6770,7 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) {
|
|||||||
SDValue InVec = N->getOperand(0);
|
SDValue InVec = N->getOperand(0);
|
||||||
SDValue InVal = N->getOperand(1);
|
SDValue InVal = N->getOperand(1);
|
||||||
SDValue EltNo = N->getOperand(2);
|
SDValue EltNo = N->getOperand(2);
|
||||||
|
DebugLoc dl = N->getDebugLoc();
|
||||||
|
|
||||||
// If the inserted element is an UNDEF, just use the input vector.
|
// If the inserted element is an UNDEF, just use the input vector.
|
||||||
if (InVal.getOpcode() == ISD::UNDEF)
|
if (InVal.getOpcode() == ISD::UNDEF)
|
||||||
@ -6781,32 +6782,40 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) {
|
|||||||
if (LegalOperations && !TLI.isOperationLegal(ISD::BUILD_VECTOR, VT))
|
if (LegalOperations && !TLI.isOperationLegal(ISD::BUILD_VECTOR, VT))
|
||||||
return SDValue();
|
return SDValue();
|
||||||
|
|
||||||
// If the invec is a BUILD_VECTOR and if EltNo is a constant, build a new
|
// Check that we know which element is being inserted
|
||||||
// vector with the inserted element.
|
if (!isa<ConstantSDNode>(EltNo))
|
||||||
if (InVec.getOpcode() == ISD::BUILD_VECTOR && isa<ConstantSDNode>(EltNo)) {
|
return SDValue();
|
||||||
unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
|
unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
|
||||||
SmallVector<SDValue, 8> Ops(InVec.getNode()->op_begin(),
|
|
||||||
InVec.getNode()->op_end());
|
|
||||||
if (Elt < Ops.size())
|
|
||||||
Ops[Elt] = InVal;
|
|
||||||
return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
|
|
||||||
VT, &Ops[0], Ops.size());
|
|
||||||
}
|
|
||||||
// If the invec is an UNDEF and if EltNo is a constant, create a new
|
|
||||||
// BUILD_VECTOR with undef elements and the inserted element.
|
|
||||||
if (InVec.getOpcode() == ISD::UNDEF &&
|
|
||||||
isa<ConstantSDNode>(EltNo)) {
|
|
||||||
EVT EltVT = VT.getVectorElementType();
|
|
||||||
unsigned NElts = VT.getVectorNumElements();
|
|
||||||
SmallVector<SDValue, 8> Ops(NElts, DAG.getUNDEF(EltVT));
|
|
||||||
|
|
||||||
unsigned Elt = cast<ConstantSDNode>(EltNo)->getZExtValue();
|
// Check that the operand is a BUILD_VECTOR (or UNDEF, which can essentially
|
||||||
if (Elt < Ops.size())
|
// be converted to a BUILD_VECTOR). Fill in the Ops vector with the
|
||||||
Ops[Elt] = InVal;
|
// vector elements.
|
||||||
return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
|
SmallVector<SDValue, 8> Ops;
|
||||||
VT, &Ops[0], Ops.size());
|
if (InVec.getOpcode() == ISD::BUILD_VECTOR) {
|
||||||
|
Ops.append(InVec.getNode()->op_begin(),
|
||||||
|
InVec.getNode()->op_end());
|
||||||
|
} else if (InVec.getOpcode() == ISD::UNDEF) {
|
||||||
|
unsigned NElts = VT.getVectorNumElements();
|
||||||
|
Ops.append(NElts, DAG.getUNDEF(InVal.getValueType()));
|
||||||
|
} else {
|
||||||
|
return SDValue();
|
||||||
}
|
}
|
||||||
return SDValue();
|
|
||||||
|
// Insert the element
|
||||||
|
if (Elt < Ops.size()) {
|
||||||
|
// All the operands of BUILD_VECTOR must have the same type;
|
||||||
|
// we enforce that here.
|
||||||
|
EVT OpVT = Ops[0].getValueType();
|
||||||
|
if (InVal.getValueType() != OpVT)
|
||||||
|
InVal = OpVT.bitsGT(InVal.getValueType()) ?
|
||||||
|
DAG.getNode(ISD::ANY_EXTEND, dl, OpVT, InVal) :
|
||||||
|
DAG.getNode(ISD::TRUNCATE, dl, OpVT, InVal);
|
||||||
|
Ops[Elt] = InVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the new vector
|
||||||
|
return DAG.getNode(ISD::BUILD_VECTOR, dl,
|
||||||
|
VT, &Ops[0], Ops.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
|
SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) {
|
||||||
|
@ -771,11 +771,14 @@ static void VerifyNodeCommon(SDNode *N) {
|
|||||||
assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() &&
|
assert(N->getNumOperands() == N->getValueType(0).getVectorNumElements() &&
|
||||||
"Wrong number of operands!");
|
"Wrong number of operands!");
|
||||||
EVT EltVT = N->getValueType(0).getVectorElementType();
|
EVT EltVT = N->getValueType(0).getVectorElementType();
|
||||||
for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
|
for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
|
||||||
assert((I->getValueType() == EltVT ||
|
assert((I->getValueType() == EltVT ||
|
||||||
(EltVT.isInteger() && I->getValueType().isInteger() &&
|
(EltVT.isInteger() && I->getValueType().isInteger() &&
|
||||||
EltVT.bitsLE(I->getValueType()))) &&
|
EltVT.bitsLE(I->getValueType()))) &&
|
||||||
"Wrong operand type!");
|
"Wrong operand type!");
|
||||||
|
assert(I->getValueType() == N->getOperand(0).getValueType() &&
|
||||||
|
"Operands must all have the same type");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
test/CodeGen/ARM/2011-09-09-OddVectorDivision.ll
Normal file
23
test/CodeGen/ARM/2011-09-09-OddVectorDivision.ll
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
; RUN: llc -mtriple=armv7-- %s -mattr=-neon
|
||||||
|
|
||||||
|
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"
|
||||||
|
target triple = "armv7-none-linux-gnueabi"
|
||||||
|
|
||||||
|
@x1 = common global <3 x i16> zeroinitializer
|
||||||
|
@y1 = common global <3 x i16> zeroinitializer
|
||||||
|
@z1 = common global <3 x i16> zeroinitializer
|
||||||
|
@x2 = common global <4 x i16> zeroinitializer
|
||||||
|
@y2 = common global <4 x i16> zeroinitializer
|
||||||
|
@z2 = common global <4 x i16> zeroinitializer
|
||||||
|
|
||||||
|
define void @f() {
|
||||||
|
%1 = load <3 x i16>* @x1
|
||||||
|
%2 = load <3 x i16>* @y1
|
||||||
|
%3 = sdiv <3 x i16> %1, %2
|
||||||
|
store <3 x i16> %3, <3 x i16>* @z1
|
||||||
|
%4 = load <4 x i16>* @x2
|
||||||
|
%5 = load <4 x i16>* @y2
|
||||||
|
%6 = sdiv <4 x i16> %4, %5
|
||||||
|
store <4 x i16> %6, <4 x i16>* @z2
|
||||||
|
ret void
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user