From 6c29bd9088bddb60baa29955a2c202922d3a6e3f Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Tue, 9 Jul 2013 17:02:45 +0000 Subject: DAGCombine tryFoldToZero cannot create illegal types after type legalization When folding sub x, x (and other similar constructs), where x is a vector, the result is a vector of zeros. After type legalization, make sure that the input zero elements have a legal type. This type may be larger than the result's vector element type. This was another bug found by llvm-stress. llvm-svn: 185949 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'llvm/lib/CodeGen/SelectionDAG') diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index fb17c93e2c4..9eb63e2c711 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1613,12 +1613,19 @@ SDValue DAGCombiner::visitADDE(SDNode *N) { // Since it may not be valid to emit a fold to zero for vector initializers // check if we can before folding. static SDValue tryFoldToZero(SDLoc DL, const TargetLowering &TLI, EVT VT, - SelectionDAG &DAG, bool LegalOperations) { + SelectionDAG &DAG, + bool LegalOperations, bool LegalTypes) { if (!VT.isVector()) return DAG.getConstant(0, VT); if (!LegalOperations || TLI.isOperationLegal(ISD::BUILD_VECTOR, VT)) { // Produce a vector of zeros. - SDValue El = DAG.getConstant(0, VT.getVectorElementType()); + EVT ElemTy = VT.getVectorElementType(); + if (LegalTypes && TLI.getTypeAction(*DAG.getContext(), ElemTy) == + TargetLowering::TypePromoteInteger) + ElemTy = TLI.getTypeToTransformTo(*DAG.getContext(), ElemTy); + assert((!LegalTypes || TLI.isTypeLegal(ElemTy)) && + "Type for zero vector elements is not legal"); + SDValue El = DAG.getConstant(0, ElemTy); std::vector Ops(VT.getVectorNumElements(), El); return DAG.getNode(ISD::BUILD_VECTOR, DL, VT, &Ops[0], Ops.size()); @@ -1648,7 +1655,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) { // fold (sub x, x) -> 0 // FIXME: Refactor this and xor and other similar operations together. if (N0 == N1) - return tryFoldToZero(SDLoc(N), TLI, VT, DAG, LegalOperations); + return tryFoldToZero(SDLoc(N), TLI, VT, DAG, LegalOperations, LegalTypes); // fold (sub c1, c2) -> c1-c2 if (N0C && N1C) return DAG.FoldConstantArithmetic(ISD::SUB, VT, N0C, N1C); @@ -3519,7 +3526,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { } // fold (xor x, x) -> 0 if (N0 == N1) - return tryFoldToZero(SDLoc(N), TLI, VT, DAG, LegalOperations); + return tryFoldToZero(SDLoc(N), TLI, VT, DAG, LegalOperations, LegalTypes); // Simplify: xor (op x...), (op y...) -> (op (xor x, y)) if (N0.getOpcode() == N1.getOpcode()) { -- cgit v1.2.3