[llvm] [InstCombine] Extend bitmask mul combine to handle independent operands (PR #142503)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 5 00:23:41 PDT 2025


================
@@ -3659,6 +3665,64 @@ static std::optional<DecomposedBitMaskMul> matchBitmaskMul(Value *V) {
   return std::nullopt;
 }
 
+/// (A & N) * C + (A & M) * C -> (A & (N + M)) & C
+/// This also accepts the equivalent select form of (A & N) * C
+/// expressions i.e. !(A & N) ? 0 : N * C)
+static Value *foldBitmaskMul(Value *Op0, Value *Op1,
+                             InstCombiner::BuilderTy &Builder) {
+  auto Decomp1 = matchBitmaskMul(Op1);
+
+  if (Decomp1) {
+    auto Decomp0 = matchBitmaskMul(Op0);
+
+    if (Decomp0) {
+      // If we have independent operands in the BitmaskMul chain, then just
+      // reassociate to encourage combining in future iterations.
+
+      if (Decomp0->isCombineableWith(*Decomp1)) {
+        auto NewAnd = Builder.CreateAnd(
+            Decomp0->X, ConstantInt::get(Decomp0->X->getType(),
+                                         (Decomp0->Mask + Decomp1->Mask)));
+
+        auto Res = Builder.CreateMul(
+            NewAnd, ConstantInt::get(NewAnd->getType(), Decomp1->Factor), "",
+            Decomp0->NUW && Decomp1->NUW, Decomp0->NSW && Decomp1->NSW);
+        return Res;
+      }
+    }
+  }
+
+  return nullptr;
+}
+
+Value *InstCombinerImpl::foldDisjointOr(Value *LHS, Value *RHS) {
+  if (Value *Res = foldBitmaskMul(LHS, RHS, Builder)) {
+    return Res;
+  }
----------------
dtcxzyw wrote:

```suggestion
  if (Value *Res = foldBitmaskMul(LHS, RHS, Builder))
    return Res;
```

https://github.com/llvm/llvm-project/pull/142503


More information about the llvm-commits mailing list