On 10/22/26 5:48 PM, Jeff Law wrote: > Is this still relevant or is it subsumed by the if-combine fix?
It is still needed. The ifcombine fix (r17-4921, "Preserve comparison operand order when if-combining") makes ifcombine pass the comparisons in evaluation order, which covers the short-circuited case. This patch is about the callers that combine two comparisons that are both evaluated: reassoc, for the operands of a BIT_AND_EXPR or BIT_IOR_EXPR, and if-conversion's fold_or_predicates. They still pass TRUTH_ANDIF_EXPR/TRUTH_ORIF_EXPR, so combine_comparisons may drop the exception of the second comparison. On current trunk at -O2 on x86_64, all three examples in the patch still return without raising FE_INVALID for a quiet NaN operand; with the patch they raise it. It does not depend on patch 1/2, so I will repost it on its own as v2, rebased onto current trunk, with its execution test in a file of its own (in this version it adds to the test that patch 1/2 creates). Igor ________________________________ From: Jeff Law <[email protected]> Sent: Thursday, October 22, 2026 5:48:18 PM To: Igor Shevlyakov; [email protected] Cc: [email protected]; [email protected] Subject: Re: [PATCH 2/2] gimple-fold: Combine two comparisons as both evaluated [PR127786] [EXTERNAL] Caution: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and know the content is safe. 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
