r = range_true (type);
return true;
}
- if (!fop_lt.fold_range (r, type, op1, op2, rel))
+ frange op1_no_nan = op1;
+ frange op2_no_nan = op2;
+ if (op1.maybe_isnan ())
+ op1_no_nan.clear_nan ();
+ if (op2.maybe_isnan ())
+ op2_no_nan.clear_nan ();
+ if (!fop_lt.fold_range (r, type, op1_no_nan, op2_no_nan, rel))
return false;
// The result is the same as the ordered version when the
// comparison is true or when the operands cannot be NANs.
r = range_true (type);
return true;
}
- if (!fop_le.fold_range (r, type, op1, op2, rel))
+ frange op1_no_nan = op1;
+ frange op2_no_nan = op2;
+ if (op1.maybe_isnan ())
+ op1_no_nan.clear_nan ();
+ if (op2.maybe_isnan ())
+ op2_no_nan.clear_nan ();
+ if (!fop_le.fold_range (r, type, op1_no_nan, op2_no_nan, rel))
return false;
// The result is the same as the ordered version when the
// comparison is true or when the operands cannot be NANs.
r = range_true (type);
return true;
}
- if (!fop_gt.fold_range (r, type, op1, op2, rel))
+ frange op1_no_nan = op1;
+ frange op2_no_nan = op2;
+ if (op1.maybe_isnan ())
+ op1_no_nan.clear_nan ();
+ if (op2.maybe_isnan ())
+ op2_no_nan.clear_nan ();
+ if (!fop_gt.fold_range (r, type, op1_no_nan, op2_no_nan, rel))
return false;
// The result is the same as the ordered version when the
// comparison is true or when the operands cannot be NANs.
r = range_true (type);
return true;
}
- if (!fop_ge.fold_range (r, type, op1, op2, rel))
+ frange op1_no_nan = op1;
+ frange op2_no_nan = op2;
+ if (op1.maybe_isnan ())
+ op1_no_nan.clear_nan ();
+ if (op2.maybe_isnan ())
+ op2_no_nan.clear_nan ();
+ if (!fop_ge.fold_range (r, type, op1_no_nan, op2_no_nan, rel))
return false;
// The result is the same as the ordered version when the
// comparison is true or when the operands cannot be NANs.
r = range_true (type);
return true;
}
- if (!fop_equal.fold_range (r, type, op1, op2, rel))
+ frange op1_no_nan = op1;
+ frange op2_no_nan = op2;
+ if (op1.maybe_isnan ())
+ op1_no_nan.clear_nan ();
+ if (op2.maybe_isnan ())
+ op2_no_nan.clear_nan ();
+ if (!fop_equal.fold_range (r, type, op1_no_nan, op2_no_nan, rel))
return false;
// The result is the same as the ordered version when the
// comparison is true or when the operands cannot be NANs.
default:
break;
}
- if (BINARY_CLASS_P (expr))
+ if (BINARY_CLASS_P (expr) || COMPARISON_CLASS_P (expr))
{
- range_op_handler op (TREE_CODE (expr), type);
+ tree op0 = TREE_OPERAND (expr, 0);
+ tree op1 = TREE_OPERAND (expr, 1);
+ if (COMPARISON_CLASS_P (expr)
+ && !Value_Range::supports_type_p (TREE_TYPE (op0)))
+ return false;
+ range_op_handler op (TREE_CODE (expr),
+ BINARY_CLASS_P (expr) ? type : TREE_TYPE (op0));
if (op)
{
- Value_Range r0 (TREE_TYPE (TREE_OPERAND (expr, 0)));
- Value_Range r1 (TREE_TYPE (TREE_OPERAND (expr, 1)));
- range_of_expr (r0, TREE_OPERAND (expr, 0), stmt);
- range_of_expr (r1, TREE_OPERAND (expr, 1), stmt);
+ Value_Range r0 (TREE_TYPE (op0));
+ Value_Range r1 (TREE_TYPE (op1));
+ range_of_expr (r0, op0, stmt);
+ range_of_expr (r1, op1, stmt);
if (!op.fold_range (r, type, r0, r1))
r.set_varying (type);
}