[llvm] [ValueTracking] Infer min/max compares from bounded operand guards (PR #227205)

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 29 03:00:41 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Akash Manna (akash-manna-sky)

<details>
<summary>Changes</summary>

Fixes #<!-- -->207131

For `if (a >= 0 && a <= 15 && b >= 0 && b <= 15) { if (min(a, b) > 15) use(); }` the call is dead, but it survives `-O3`. SimplifyCFG merges the inner check into the guard and InstCombine turns the guard into `(a | b) u< 16`, so we end up with `and (icmp ult (or b, a), 16), (icmp sgt (smin a, b), 15)`. `isImpliedCondition` couldn't prove that the first compare rules out the second: it didn't know that a bound on `a | b` also bounds `a` and `b`, and it didn't look through the `smin` at all. Nothing to do with `computeConstantRange` ignoring dominating conditions, by the way — there's no dominating branch left at that point, and `f_range_assume` only folds because the assume keeps SimplifyCFG from merging the check into the guard.

`isImpliedCondICmps` now carries a guard's upper bound over to anything `isTruePredicate` knows is no larger than the guarded value (and a lower bound to anything no smaller), e.g. `a u<= a | b`, so `(a | b) u< 16` also gives `a u< 16`. A compare of `min/max(X, Y)` is now decided through its operands: the result is always `X` or `Y`, so if the guard gives `X pred Z` and `Y pred Z` the same answer, the min/max compare gets it too, and when the compare goes the same way as the min/max, one operand is enough — `smin(X, Y) s> Z` is false as soon as `X s> Z` is. That proves `smin(a, b) s> 15` false under the guard, and the dead branch folds away.


---
Full diff: https://github.com/llvm/llvm-project/pull/227205.diff


5 Files Affected:

- (modified) llvm/lib/Analysis/ValueTracking.cpp (+63-6) 
- (modified) llvm/test/Transforms/InstCombine/implies.ll (+3-4) 
- (modified) llvm/test/Transforms/InstCombine/pr63791.ll (+1-1) 
- (modified) llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll (+191) 
- (modified) llvm/test/Transforms/PhaseOrdering/cmp-logic.ll (+185-2) 


``````````diff
The server is unavailable at this time. Please wait a few minutes before you try again.
``````````

</details>


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


More information about the llvm-commits mailing list