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;
--- /dev/null
+/* 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
+}