[gcc r17-3234] match: Fix recent pattern for signed integer overflow dealing with - [PR126418]
Andrea Pinski via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:610f1166538ad2e637c913be78b074100270cc5c commit r17-3234-g610f1166538ad2e637c913be78b074100270cc5c Author: Andrea Pinski <[email protected]> Date: Mon Jul 27 20:11:33 2026 -0700 match: Fix recent pattern for signed integer overflow dealing with - [PR126418] A recent match patterns were added that introduce signed integer overflow where there was none before. `cmp + (-cmp ^ x)` has no signed integer overflow when x is INT_MIN when cmp is 0. This gets translated into cmp ? -x : x. But this has now introduced an signed integer overflow for INT_MIN. The fix is to use unsigned type for the negative. Bootstrapped and tested on x86_64-linux-gnu. Changes since v1: * v2: Remove the abs patterns since a signed integer overflow would have happened anyways. PR tree-optimization/126418 gcc/ChangeLog: * match.pd (`(A ^ -cmp) + cmp`): Cast to unsigned type before taking the negative. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/pr126418-1.c: New test. Signed-off-by: Andrea Pinski <[email protected]> Diff: --- gcc/match.pd | 8 +++++++- gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c | 11 +++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/gcc/match.pd b/gcc/match.pd index eee44365ea37..3f476cc4baad 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4987,7 +4987,13 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (INTEGRAL_TYPE_P (type) && !TYPE_SATURATING (type) && (GIMPLE || !TREE_SIDE_EFFECTS (@0))) - (cond (convert:boolean_type_node @1) (negate @0) @0))) + /* Do the negate in unsigned type always; otherwise + we would be introducing an overflow. */ + (with { tree utype = unsigned_type_for (type); } + (cond + (convert:boolean_type_node @1) + (convert:type (negate (convert:utype @0))) + @0)))) /* Transform A & (B*cmp) into (A&B)*cmp. */ (simplify diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c new file mode 100644 index 000000000000..3714069b43f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126418-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop1" } */ + +int f_cmp_gt_commuted(int x, int y) +{ + int cmp = x > y; + return cmp + (-cmp ^ x); +} + +/* { dg-final { scan-tree-dump-times "\\(unsigned int\\) " 1 "forwprop1" } } */ +/* { dg-final { scan-tree-dump-times "\\(int\\) " 1 "forwprop1" } } */