[gcc r17-2707] fold: Allow combining eq/ne with a trapping to get a trapping [PR126138]
Andrea Pinski via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:7d781db9c3d5159386b1f645355955da5f844ec4 commit r17-2707-g7d781db9c3d5159386b1f645355955da5f844ec4 Author: Andrea Pinski <[email protected]> Date: Sat Jul 11 22:56:40 2026 -0700 fold: Allow combining eq/ne with a trapping to get a trapping [PR126138] For `(i == j) || (i < j)` this can be combined to just `i <= j` without worrying about removal of a trap as a NaN would cause the the equal to be false which will cause not to short circuit and the trapping instruction will always be executed. `(i != j) && (i < j)` has the same reasoning. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/126138 gcc/ChangeLog: * fold-const.cc (combine_comparisons): Allow eq to combine with || and ne combine with && if the original rcode was trapping and the new code is trapping. gcc/testsuite/ChangeLog: * gcc.dg/tree-ssa/fp-trapping-cmp-1.c: New test. Signed-off-by: Andrea Pinski <[email protected]> Diff: --- gcc/fold-const.cc | 13 ++++++++++--- gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-1.c | 21 +++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc index b4e3a56aeb55..e1793ac89f25 100644 --- a/gcc/fold-const.cc +++ b/gcc/fold-const.cc @@ -3002,14 +3002,21 @@ combine_comparisons (enum tree_code code, enum tree_code lcode, || (code == TRUTH_ANDIF_EXPR && !(lcompcode & COMPCODE_UNORD))) rtrap = false; + /* Allow combining of `a != b && a < b` since NAN will cause != to be + always true, and `a < b` will cause a trap. This is trap neutral. */ + if (code == TRUTH_ANDIF_EXPR && lcompcode == COMPCODE_NE && rtrap && trap) + ; + /* Likewise of `a == b || a < b` for the same reason. */ + else if (code == TRUTH_ORIF_EXPR && lcompcode == COMPCODE_EQ && rtrap && trap) + ; /* If the comparison was short-circuited, and only the RHS trapped, we may now generate a spurious trap. */ - if (rtrap && !ltrap - && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)) + else if (rtrap && !ltrap + && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)) return ERROR_MARK; /* If we changed the conditions that cause a trap, we lose. */ - if ((ltrap || rtrap) != trap) + else if ((ltrap || rtrap) != trap) return ERROR_MARK; } diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-1.c new file mode 100644 index 000000000000..9d88dc10c2d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/fp-trapping-cmp-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftrapping-math -fdump-tree-original -fdump-tree-optimized" } */ +/* PR tree-optimization/126138 */ + +/* (eq || trap) -> trap is fine as eq will be false for NaN + which means it is not short circuit and will cause a trap + on the trapping instruction always. */ +int +f (double i, double j) +{ + return (i == j) || (i < j); +} +/* (ne && trap) -> trap has a story. */ +int +f1 (double i, double j) +{ + return (i != j) && (i < j); +} +/* { dg-final { scan-tree-dump-not " && " "original" } } */ +/* { dg-final { scan-tree-dump-not " \\\|\\\| " "original" } } */ +/* { dg-final { scan-tree-dump-not " if " "optimized" } } */