[llvm] [InstCombine] Fold X + umax(X, 1) -> umax(X << 1, 1) (PR #222727)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 12 03:28:21 PDT 2026


================
@@ -1984,6 +1984,22 @@ Instruction *InstCombinerImpl::visitAdd(BinaryOperator &I) {
     I.setHasNoUnsignedWrap(true);
   }
 
+  // X + umax(X, 1) --> umax(X << 1, 1) if X + X does not overflow.
+  if (match(&I, m_c_Add(m_Value(A), m_OneUse(m_c_UMax(m_Value(B), m_One())))) &&
+      A == B) {
+    auto Cache = A == LHSCache ? LHSCache : RHSCache;
+    auto One = ConstantInt::get(Ty, 1);
+    bool NoUW =
+        I.hasNoUnsignedWrap() || willNotOverflowUnsignedAdd(Cache, Cache, I);
+    // Do not apply this transformation if the original add might overflow.
+    if (NoUW || I.hasNoSignedWrap())
+      return replaceInstUsesWith(
+          I, Builder.CreateIntrinsic(
+                 Intrinsic::umax, {Ty},
+                 {One, Builder.CreateShl(A, One, "mul2", NoUW,
+                                         I.hasNoSignedWrap())}));
----------------
artagnon wrote:

```suggestion
    bool HasNUW = I.hasNoUnsignedWrap();
    bool HasNSW = I.hasNoSignedWrap();
    // Do not apply this transformation if the original add might overflow.
    if (HasNUW || HasNSW)
      return replaceInstUsesWith(
          I, Builder.CreateIntrinsic(
                 Intrinsic::umax, {Ty},
                 {Builder.CreateShl(A, One, "mul2", HasNUW,
                                         HasNSW), One}));
```

I think willNotOverflow is already checked and nuw/nsw are already set just above?

```cpp
  bool Changed = false;
  if (!I.hasNoSignedWrap() && willNotOverflowSignedAdd(LHSCache, RHSCache, I)) {
    Changed = true;
    I.setHasNoSignedWrap(true);
  }
  if (!I.hasNoUnsignedWrap() &&
      willNotOverflowUnsignedAdd(LHSCache, RHSCache, I)) {
    Changed = true;
    I.setHasNoUnsignedWrap(true);
  }
```

Unnecessarily commuting operands to mismatch with comment?

Fixed proof: https://alive2.llvm.org/ce/z/3PpY_B (see InstCombine contributor guide for guidance on how proofs need to be general).

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


More information about the llvm-commits mailing list