[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