https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67052
Bug ID: 67052 Summary: tree_single_nonnegative_warnv_p and fold_relational_const are inconsistent with NaNs Product: gcc Version: 6.0 Status: UNCONFIRMED Keywords: missed-optimization, wrong-code Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: rguenth at gcc dot gnu.org CC: jsm28 at gcc dot gnu.org Target Milestone: --- int main () { double x = __builtin_nan (""); if (x < 0.0) return 1; return 0; } this simplifies via /* Convert ABS_EXPR<x> < 0 to false. */ strict_overflow_p = false; if (code == LT_EXPR && (integer_zerop (arg1) || real_zerop (arg1)) && tree_expr_nonnegative_warnv_p (arg0, &strict_overflow_p)) { if (strict_overflow_p) fold_overflow_warning (("assuming signed overflow does not occur " "when simplifying comparison of " "absolute value and zero"), WARN_STRICT_OVERFLOW_CONDITIONAL); return omit_one_operand_loc (loc, type, constant_boolean_node (false, type), arg0); } (the ABS_EXPR<x> >= 0 case is guarded with ! HONOR_NANS) but not via constant folding in fold_relational_const. bool tree_single_nonnegative_warnv_p (tree t, bool *strict_overflow_p) { ... case REAL_CST: return ! REAL_VALUE_NEGATIVE (TREE_REAL_CST (t)); but static tree fold_relational_const (enum tree_code code, tree type, tree op0, tree op1) { ... /* Handle the cases where either operand is a NaN. */ if (real_isnan (c0) || real_isnan (c1)) { ... case LT_EXPR: case LE_EXPR: case GT_EXPR: case GE_EXPR: case LTGT_EXPR: if (flag_trapping_math) return NULL_TREE; is this a missed optimization or wrong-code?