[llvm] [InstCombine] Generalize zext(add X, -C) + C folding (PR #191723)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 13 07:31:12 PDT 2026
Maiowaa wrote:
> I noticed that the patch includes test coverage for cases where the inner constant and outer constant are of different types (e.g., inner: -4 as i8, outer: 4 as i32):
>
> ```
> %inner = add i8 %or, -4
> %z = zext i8 %inner to i32
> %r = add i32 %z, 4
> ```
>
> This clearly demonstrates the optimization for the `zext(add(x, -const)) + const` pattern. However, I have one question: does this optimization also handle the symmetric pattern `zext(add(x, const)) + -const`?
>
> If not, I would suggest adding a negative test case (or a TODO comment) to explicitly cover the reverse scenario, e.g.:
>
> ```
> %inner = add i8 %or, 4
> %z = zext i8 %inner to i32
> %r = add i32 %z, -4 ; outer constant is negative
> ```
>
> thank you
Good question.
The symmetric pattern:
zext(add(X, C)) + (-C)
is intentionally not handled. Unlike the zext(add(X, -C)) + C case, this form does not simplify to zext(X) in general due to wrap-around semantics.
Specifically, the addition (X + C) is performed in the narrower type and may overflow before the zext. This means:
zext((X + C) mod 2^n) - C != zext(X)
in general.
For example, with 8-bit integers:
X = 254, C = 3
(X + C) = 257 --> wraps to 1
zext(1) = 1
1 - 3 = -2 != 254
So this transformation is not valid. I can add a negative test to document this behavior if that would be helpful.
Thank you
https://github.com/llvm/llvm-project/pull/191723
More information about the llvm-commits
mailing list