Fix a DAGCombiner crash when folding binary vector operations with constant

BUILD_VECTOR operands where the element type is not legal.  I had previously
changed this code to insert TRUNCATE operations, but that was just wrong.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122102 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bob Wilson 2010-12-17 23:06:49 +00:00
parent 4c6b3d35bb
commit d727343a40
2 changed files with 23 additions and 16 deletions

View File

@ -6643,10 +6643,9 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
// things. Simplifying them may result in a loss of legality.
if (LegalOperations) return SDValue();
EVT VT = N->getValueType(0);
assert(VT.isVector() && "SimplifyVBinOp only works on vectors!");
assert(N->getValueType(0).isVector() &&
"SimplifyVBinOp only works on vectors!");
EVT EltType = VT.getVectorElementType();
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
SDValue Shuffle = XformToShuffleWithZero(N);
@ -6679,14 +6678,10 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
break;
}
// If the vector element type is not legal, the BUILD_VECTOR operands
// are promoted and implicitly truncated. Make that explicit here.
if (LHSOp.getValueType() != EltType)
LHSOp = DAG.getNode(ISD::TRUNCATE, LHS.getDebugLoc(), EltType, LHSOp);
if (RHSOp.getValueType() != EltType)
RHSOp = DAG.getNode(ISD::TRUNCATE, RHS.getDebugLoc(), EltType, RHSOp);
SDValue FoldOp = DAG.getNode(N->getOpcode(), LHS.getDebugLoc(), EltType,
EVT VT = LHSOp.getValueType();
assert(RHSOp.getValueType() == VT &&
"SimplifyVBinOp with different BUILD_VECTOR element types");
SDValue FoldOp = DAG.getNode(N->getOpcode(), LHS.getDebugLoc(), VT,
LHSOp, RHSOp);
if (FoldOp.getOpcode() != ISD::UNDEF &&
FoldOp.getOpcode() != ISD::Constant &&
@ -6696,11 +6691,9 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) {
AddToWorkList(FoldOp.getNode());
}
if (Ops.size() == LHS.getNumOperands()) {
EVT VT = LHS.getValueType();
return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT,
&Ops[0], Ops.size());
}
if (Ops.size() == LHS.getNumOperands())
return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),
LHS.getValueType(), &Ops[0], Ops.size());
}
return SDValue();

View File

@ -61,3 +61,17 @@ define void @lshrIllegalType(<8 x i32>* %A) nounwind {
ret void
}
; Test folding a binary vector operation with constant BUILD_VECTOR
; operands with i16 elements.
define void @test_i16_constant_fold() nounwind optsize {
entry:
%0 = sext <4 x i1> zeroinitializer to <4 x i16>
%1 = add <4 x i16> %0, zeroinitializer
%2 = shufflevector <4 x i16> %1, <4 x i16> undef, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7>
%3 = add <8 x i16> %2, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%4 = trunc <8 x i16> %3 to <8 x i8>
tail call void @llvm.arm.neon.vst1.v8i8(i8* undef, <8 x i8> %4, i32 1)
unreachable
}
declare void @llvm.arm.neon.vst1.v8i8(i8*, <8 x i8>, i32) nounwind