aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp51
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)));
+ }
}
}