[SCEV] Fold zext(C+A)<nsw> -> (sext(C) + zext(A))<nsw> if possible. (#142599)
Simplify zext(C+A)<nsw> -> (sext(C) + zext(A))<nsw> if
* zext (C + A)<nsw> >=s 0 and
* A >=s V.
For now this is limited to cases where the first operand is a constant,
so the SExt can be folded to a new constant. This can be relaxed in the
future.
The initial version checks for non-negative manually to limit compile-time,
supporting only A = smax(C2, ..) where C2 >= abs(C)
Alive2 proof of the general pattern and the test changes in zext-nuw.ll
(times out in the online instance but verifies locally)
https://alive2.llvm.org/ce/z/_BtyGy
PR: github.com/llvm/llvm-project/pull/142599