re PR middle-end/15945 (Incorrect floating point optimization)
authorJakub Jelinek <jakub@redhat.com>
Mon, 14 Jun 2004 17:45:08 +0000 (19:45 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 14 Jun 2004 17:45:08 +0000 (19:45 +0200)
PR middle-end/15945
* simplify-rtx.c (simplify_binary_operation): Don't optimize out
Inf + -Inf, Inf - Inf, Inf / Inf and 0 * Inf if flag_trapping_math.

From-SVN: r83121

gcc/ChangeLog
gcc/simplify-rtx.c

index 6444b0602b2caa4d391cd426a13c4b80ae10ff57..d7faa5d7818cd70fc8f178d61ae001f99d84fc5c 100644 (file)
@@ -1,3 +1,9 @@
+2004-06-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/15945
+       * simplify-rtx.c (simplify_binary_operation): Don't optimize out
+       Inf + -Inf, Inf - Inf, Inf / Inf and 0 * Inf if flag_trapping_math.
+
 2004-06-14  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 
        * opts.sh (var_args): Fix regexp.
index fb80219155c4d56dd603b0445bfbc02986de4dbe..0d3b2bde45f0b3cee68314191fe298397b2d44e2 100644 (file)
@@ -1277,6 +1277,41 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
              && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
            return 0;
 
+         if (MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
+             && flag_trapping_math
+             && REAL_VALUE_ISINF (f0) && REAL_VALUE_ISINF (f1))
+           {
+             int s0 = REAL_VALUE_NEGATIVE (f0);
+             int s1 = REAL_VALUE_NEGATIVE (f1);
+
+             switch (code)
+               {
+               case PLUS:
+                 /* Inf + -Inf = NaN plus exception.  */
+                 if (s0 != s1)
+                   return 0;
+                 break;
+               case MINUS:
+                 /* Inf - Inf = NaN plus exception.  */
+                 if (s0 == s1)
+                   return 0;
+                 break;
+               case DIV:
+                 /* Inf / Inf = NaN plus exception.  */
+                 return 0;
+               default:
+                 break;
+               }
+           }
+
+         if (code == MULT && MODE_HAS_INFINITIES (mode) && HONOR_NANS (mode)
+             && flag_trapping_math
+             && ((REAL_VALUE_ISINF (f0) && REAL_VALUES_EQUAL (f1, dconst0))
+                 || (REAL_VALUE_ISINF (f1)
+                     && REAL_VALUES_EQUAL (f0, dconst0))))
+           /* Inf * 0 = NaN plus exception.  */
+           return 0;
+
          REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
 
          value = real_value_truncate (mode, value);