diff options
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 8d465b9520de..42a141e8876b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -6360,7 +6360,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { SDValue Extendee = Ext->getOperand(0); unsigned ScalarWidth = Extendee.getValueType().getScalarSizeInBits(); - if (N1C->getAPIntValue().isMask(ScalarWidth)) { + if (N1C->getAPIntValue().isMask(ScalarWidth) && + (!LegalOperations || TLI.isOperationLegal(ISD::ZERO_EXTEND, ExtVT))) { // (and (extract_subvector (zext|anyext|sext v) _) iN_mask) // => (extract_subvector (iN_zeroext v)) SDValue ZeroExtExtendee = @@ -7573,6 +7574,10 @@ SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) { std::swap(LHSMask, RHSMask); } + // Something has gone wrong - we've lost the shl/srl pair - bail. + if (LHSShift.getOpcode() != ISD::SHL || RHSShift.getOpcode() != ISD::SRL) + return SDValue(); + unsigned EltSizeInBits = VT.getScalarSizeInBits(); SDValue LHSShiftArg = LHSShift.getOperand(0); SDValue LHSShiftAmt = LHSShift.getOperand(1); @@ -22729,25 +22734,31 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { SDLoc DL(N); EVT IntVT = VT.changeVectorElementTypeToInteger(); EVT IntSVT = VT.getVectorElementType().changeTypeToInteger(); - IntSVT = TLI.getTypeToTransformTo(*DAG.getContext(), IntSVT); - SDValue ZeroElt = DAG.getConstant(0, DL, IntSVT); - SDValue AllOnesElt = DAG.getAllOnesConstant(DL, IntSVT); - SmallVector<SDValue, 16> AndMask(NumElts, DAG.getUNDEF(IntSVT)); - for (int I = 0; I != (int)NumElts; ++I) - if (0 <= Mask[I]) - AndMask[I] = Mask[I] == I ? AllOnesElt : ZeroElt; - - // See if a clear mask is legal instead of going via - // XformToShuffleWithZero which loses UNDEF mask elements. - if (TLI.isVectorClearMaskLegal(ClearMask, IntVT)) - return DAG.getBitcast( - VT, DAG.getVectorShuffle(IntVT, DL, DAG.getBitcast(IntVT, N0), - DAG.getConstant(0, DL, IntVT), ClearMask)); - - if (TLI.isOperationLegalOrCustom(ISD::AND, IntVT)) - return DAG.getBitcast( - VT, DAG.getNode(ISD::AND, DL, IntVT, DAG.getBitcast(IntVT, N0), - DAG.getBuildVector(IntVT, DL, AndMask))); + // Transform the type to a legal type so that the buildvector constant + // elements are not illegal. Make sure that the result is larger than the + // original type, incase the value is split into two (eg i64->i32). + if (!TLI.isTypeLegal(IntSVT) && LegalTypes) + IntSVT = TLI.getTypeToTransformTo(*DAG.getContext(), IntSVT); + if (IntSVT.getSizeInBits() >= IntVT.getScalarSizeInBits()) { + SDValue ZeroElt = DAG.getConstant(0, DL, IntSVT); + SDValue AllOnesElt = DAG.getAllOnesConstant(DL, IntSVT); + SmallVector<SDValue, 16> AndMask(NumElts, DAG.getUNDEF(IntSVT)); + for (int I = 0; I != (int)NumElts; ++I) + if (0 <= Mask[I]) + AndMask[I] = Mask[I] == I ? AllOnesElt : ZeroElt; + + // See if a clear mask is legal instead of going via + // XformToShuffleWithZero which loses UNDEF mask elements. + if (TLI.isVectorClearMaskLegal(ClearMask, IntVT)) + return DAG.getBitcast( + VT, DAG.getVectorShuffle(IntVT, DL, DAG.getBitcast(IntVT, N0), + DAG.getConstant(0, DL, IntVT), ClearMask)); + + if (TLI.isOperationLegalOrCustom(ISD::AND, IntVT)) + return DAG.getBitcast( + VT, DAG.getNode(ISD::AND, DL, IntVT, DAG.getBitcast(IntVT, N0), + DAG.getBuildVector(IntVT, DL, AndMask))); + } } } |