summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 6644baf8fa5..adb4986f117 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -32442,6 +32442,45 @@ static SDValue combineAnd(SDNode *N, SelectionDAG &DAG,
}
}
+ // Attempt to combine a scalar bitmask AND with an extracted shuffle.
+ if ((VT.getScalarSizeInBits() % 8) == 0 &&
+ N->getOperand(0).getOpcode() == ISD::EXTRACT_VECTOR_ELT &&
+ isa<ConstantSDNode>(N->getOperand(0).getOperand(1))) {
+ SDValue BitMask = N->getOperand(1);
+ SDValue SrcVec = N->getOperand(0).getOperand(0);
+ EVT SrcVecVT = SrcVec.getValueType();
+
+ // Check that the constant bitmask masks whole bytes.
+ APInt UndefElts;
+ SmallVector<APInt, 64> EltBits;
+ if (VT == SrcVecVT.getScalarType() &&
+ N->getOperand(0)->isOnlyUserOf(SrcVec.getNode()) &&
+ getTargetConstantBitsFromNode(BitMask, 8, UndefElts, EltBits) &&
+ llvm::all_of(EltBits, [](APInt M) {
+ return M.isNullValue() || M.isAllOnesValue();
+ })) {
+ unsigned NumElts = SrcVecVT.getVectorNumElements();
+ unsigned Scale = SrcVecVT.getScalarSizeInBits() / 8;
+ unsigned Idx = N->getOperand(0).getConstantOperandVal(1);
+
+ // Create a root shuffle mask from the byte mask and the extracted index.
+ SmallVector<int, 16> ShuffleMask(NumElts * Scale, SM_SentinelUndef);
+ for (unsigned i = 0; i != Scale; ++i) {
+ if (UndefElts[i])
+ continue;
+ int VecIdx = Scale * Idx + i;
+ ShuffleMask[VecIdx] =
+ EltBits[i].isNullValue() ? SM_SentinelZero : VecIdx;
+ }
+
+ if (SDValue Shuffle = combineX86ShufflesRecursively(
+ {SrcVec}, 0, SrcVec, ShuffleMask, {}, /*Depth*/ 2,
+ /*HasVarMask*/ false, DAG, DCI, Subtarget))
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(N), VT, Shuffle,
+ N->getOperand(0).getOperand(1));
+ }
+ }
+
return SDValue();
}
OpenPOWER on IntegriCloud