[llvm] [DAG] Fold any-extend(and(trunc(x), C)) -> and(x, C) (PR #200052)
Aayush Shrivastava via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 04:01:49 PDT 2026
================
@@ -15910,16 +15910,36 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) {
// Fold (zext (and (trunc x), cst)) -> (and x, cst),
// if either of the casts is not free.
+ // Also handles (zext (and (bitcast (extract_subvector vNi1, 0)) cst))
+ // by treating the bitcast+extract as equivalent to a truncate of the
+ // wider bitcast, e.g. on AVX512DQ where v8i1 extract replaces truncate.
if (N0.getOpcode() == ISD::AND &&
- N0.getOperand(0).getOpcode() == ISD::TRUNCATE &&
- N0.getOperand(1).getOpcode() == ISD::Constant &&
- (!TLI.isTruncateFree(N0.getOperand(0).getOperand(0), N0.getValueType()) ||
- !TLI.isZExtFree(N0.getValueType(), VT))) {
- SDValue X = N0.getOperand(0).getOperand(0);
- X = DAG.getAnyExtOrTrunc(X, SDLoc(X), VT);
- APInt Mask = N0.getConstantOperandAPInt(1).zext(VT.getSizeInBits());
- return DAG.getNode(ISD::AND, DL, VT,
- X, DAG.getConstant(Mask, DL, VT));
+ N0.getOperand(1).getOpcode() == ISD::Constant) {
+ SDValue AndSrc = N0.getOperand(0);
+ SDValue X;
+ if (AndSrc.getOpcode() == ISD::TRUNCATE) {
+ X = AndSrc.getOperand(0);
+ } else if (AndSrc.getOpcode() == ISD::BITCAST &&
+ AndSrc.getOperand(0).getOpcode() == ISD::EXTRACT_SUBVECTOR &&
+ AndSrc.getOperand(0).getConstantOperandVal(1) == 0) {
+ // (bitcast (extract_subvector vNi1, 0) -> iK) is equivalent to
+ // (truncate (bitcast vNi1 -> iN) -> iK); use the wider vNi1 as X.
+ SDValue Src = AndSrc.getOperand(0).getOperand(0);
+ EVT SrcVT = Src.getValueType();
+ if (SrcVT.isVector() && !SrcVT.isScalableVT() &&
+ SrcVT.getVectorElementType() == MVT::i1) {
----------------
iamaayushrivastava wrote:
Done, used `isFixedLengthVectorOf(MVT::i1)` in both places.
https://github.com/llvm/llvm-project/pull/200052
More information about the llvm-commits
mailing list