On 10/9/26 10:55 AM, Igor Shevlyakov wrote:
and_comparisons_1 and or_comparisons_1 pass TRUTH_ANDIF_EXPR and
TRUTH_ORIF_EXPR to combine_comparisons. Under -ftrapping-math those
codes tell it that the second comparison is only evaluated when the
first does not decide the result, so it may drop the exception the
second one raises. That is wrong for reassoc, which combines the
operands of a BIT_AND_EXPR or BIT_IOR_EXPR, both of them evaluated:
- !__builtin_isgreaterequal (a, b) | (a > b) became a quiet a != b,
dropping the FE_INVALID that a > b raises for a NaN;
- (a <= b) & (a == b) became a quiet a == b;
- a < b || __builtin_isunordered (a, b), once phiopt has made both
comparisons unconditional, became a quiet a u< b.
if-conversion's fold_or_predicates likewise combines block predicates
that the if-converted code computes unconditionally.
Pass TRUTH_AND_EXPR and TRUTH_OR_EXPR instead, as
fold_truth_andor_for_ifcombine already does. combine_comparisons then
requires the combined comparison to trap exactly when one of the two
does. ifcombine, the one caller whose conditions are short-circuited,
loses nothing: since r17-4921 it passes them in evaluation order, it
combines an inner condition that can trap itself, with TRUTH_ANDIF_EXPR,
and it only calls maybe_fold_and_comparisons for one that cannot. For a
second comparison that cannot trap the short-circuit rules of
combine_comparisons make no difference. fp-trapping-cmp-8.c checks that
ifcombine still merges if (a == b) if (a <= b) into a == b.
A combination that folds to a constant, e.g. (a < b) & (a > b) -> 0,
can still lose the exception, as x < x -> 0 does.
PR middle-end/127786
gcc/ChangeLog:
* gimple-fold.cc (and_comparisons_1): Pass TRUTH_AND_EXPR to
combine_comparisons.
(or_comparisons_1): Pass TRUTH_OR_EXPR to combine_comparisons.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/cmp-of-cmp-fenv.c (unlt_or_gt, le_and_eq)
(le_then_eq, lt_orif_uno): New functions.
(tests): Add them.
* gcc.dg/tree-ssa/fp-trapping-cmp-8.c: New test.
Signed-off-by: Igor Shevlyakov <[email protected]>
Is this still relevant or is it subsumed by the if-combine fix?
Jeff