diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc index 41d497e96ade884af13e45a919eebea7070e9ef6..e0e91bad44d6d1d7739768ccf662c882ba49b7ea 100644 --- a/gcc/range-op-float.cc +++ b/gcc/range-op-float.cc @@ -886,7 +886,7 @@ foperator_lt::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x < NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else build_ge (r, type, op2); @@ -923,7 +923,7 @@ foperator_lt::op2_range (frange &r, case BRS_FALSE: // On the FALSE side of NAN < x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else build_le (r, type, op1); @@ -998,7 +998,7 @@ foperator_le::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x <= NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else build_gt (r, type, op2); @@ -1031,7 +1031,7 @@ foperator_le::op2_range (frange &r, case BRS_FALSE: // On the FALSE side of NAN <= x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1112,7 +1112,7 @@ foperator_gt::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x > NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1151,7 +1151,7 @@ foperator_gt::op2_range (frange &r, case BRS_FALSE: // On The FALSE side of NAN > x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1228,7 +1228,7 @@ foperator_ge::op1_range (frange &r, case BRS_FALSE: // On the FALSE side of x >= NAN, we know nothing about x. - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1262,7 +1262,7 @@ foperator_ge::op2_range (frange &r, tree type, case BRS_FALSE: // On the FALSE side of NAN >= x, we know nothing about x. - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1618,7 +1618,7 @@ foperator_unordered_lt::op1_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1652,7 +1652,7 @@ foperator_unordered_lt::op2_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1726,7 +1726,7 @@ foperator_unordered_le::op1_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1759,7 +1759,7 @@ foperator_unordered_le::op2_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1835,7 +1835,7 @@ foperator_unordered_gt::op1_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1870,7 +1870,7 @@ foperator_unordered_gt::op2_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; @@ -1946,7 +1946,7 @@ foperator_unordered_ge::op1_range (frange &r, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op2.known_isnan ()) + if (op2.known_isnan () || op2.maybe_isnan ()) r.set_varying (type); else if (op2.undefined_p ()) return false; @@ -1980,7 +1980,7 @@ foperator_unordered_ge::op2_range (frange &r, tree type, switch (get_bool_state (r, lhs, type)) { case BRS_TRUE: - if (op1.known_isnan ()) + if (op1.known_isnan () || op1.maybe_isnan ()) r.set_varying (type); else if (op1.undefined_p ()) return false; diff --git a/gcc/testsuite/gcc.c-torture/execute/ieee/pr109386.c b/gcc/testsuite/gcc.c-torture/execute/ieee/pr109386.c new file mode 100644 index 0000000000000000000000000000000000000000..98895d1e8aeed6cd06a23dddedba709d8ce2c6b3 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/ieee/pr109386.c @@ -0,0 +1,21 @@ +/* PR tree-optimization/109386 */ + +static inline float +foo (float x, float y) +{ + float u = __builtin_fabsf (x); + float v = __builtin_fabsf (y); + if (!(u >= v)) + { + if (__builtin_isinf (v)) return v; + if (__builtin_isinf (u)) return u; + } + return 42.0f; +} + +int +main () +{ + if (!__builtin_isinf (foo (__builtin_inff (), __builtin_nanf ("")))) + __builtin_abort (); +}