diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 238a3262d2be77cb9bbca4844929b4d79dee15f6..a8d39cff27f559b885b47a2f7236ce1e9655f76a 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -324,6 +324,24 @@ frange_arithmetic (enum tree_code code, tree type,
   bool inexact = real_arithmetic (&value, code, &op1, &op2);
   real_convert (&result, mode, &value);
 
+  /* When rounding towards negative infinity, x + (-x) and
+     x - x is -0 rather than +0 real_arithmetic computes.
+     So, when we are looking for lower bound (inf is negative),
+     use -0 rather than +0.  */
+  if (flag_rounding_math
+      && (code == PLUS_EXPR || code == MINUS_EXPR)
+      && !inexact
+      && real_iszero (&result)
+      && !real_isneg (&result)
+      && real_isneg (&inf))
+    {
+      REAL_VALUE_TYPE op2a = op2;
+      if (code == PLUS_EXPR)
+	op2a.sign ^= 1;
+      if (real_isneg (&op1) == real_isneg (&op2a) && real_equal (&op1, &op2a))
+	result.sign = 1;
+    }
+
   // Be extra careful if there may be discrepancies between the
   // compile and runtime results.
   bool round = false;
diff --git a/gcc/testsuite/gcc.dg/pr110755.c b/gcc/testsuite/gcc.dg/pr110755.c
new file mode 100644
index 0000000000000000000000000000000000000000..c3bfaa61cb4a76d34efd09389168e397f186abd0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr110755.c
@@ -0,0 +1,29 @@
+/* PR tree-optimization/110755 */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv } */
+/* { dg-require-effective-target hard_float } */
+/* { dg-options "-O2 -frounding-math" } */
+
+#include <fenv.h>
+
+__attribute__((noipa)) float
+foo (float x)
+{ 
+  if (x > 0.0)
+    { 
+      x += 0x1p+23;
+      x -= 0x1p+23;
+      x = __builtin_fabsf (x);
+    }
+  return x;
+}
+
+int
+main ()
+{
+#ifdef FE_DOWNWARD
+  fesetround (FE_DOWNWARD);
+  if (__builtin_signbit (foo (0.5)))
+    __builtin_abort ();
+#endif
+}