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 ();
+}