diff options
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 91df355b9ac..92567fe3c41 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -1288,12 +1288,13 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, } else { - REAL_VALUE_TYPE f0, f1, value; + REAL_VALUE_TYPE f0, f1, value, result; + bool inexact; REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0); REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1); - f0 = real_value_truncate (mode, f0); - f1 = real_value_truncate (mode, f1); + real_convert (&f0, mode, &f0); + real_convert (&f1, mode, &f1); if (HONOR_SNANS (mode) && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1))) @@ -1339,10 +1340,18 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode, /* Inf * 0 = NaN plus exception. */ return 0; - REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1); + inexact = real_arithmetic (&value, rtx_to_tree_code (code), + &f0, &f1); + real_convert (&result, mode, &value); - value = real_value_truncate (mode, value); - return CONST_DOUBLE_FROM_REAL_VALUE (value, mode); + /* Don't constant fold this floating point operation if the + result may dependent upon the run-time rounding mode and + flag_rounding_math is set. */ + if (flag_rounding_math + && (inexact || !real_identical (&result, &value))) + return NULL_RTX; + + return CONST_DOUBLE_FROM_REAL_VALUE (result, mode); } } |