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?