re PR tree-optimization/56899 (Wrong constant folding)
authorJakub Jelinek <jakub@redhat.com>
Thu, 11 Apr 2013 07:30:20 +0000 (09:30 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 11 Apr 2013 07:30:20 +0000 (09:30 +0200)
PR tree-optimization/56899
* fold-const.c (extract_muldiv_1): Apply distributive law
only if TYPE_OVERFLOW_WRAPS (ctype).

* gcc.c-torture/execute/pr56899.c: New test.

From-SVN: r197692

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/pr56899.c [new file with mode: 0644]

index 7e1cc32176c659479d9ea59fea86f15753ca2f50..bab67ab7b01ff9b8232312569085d6ef640e35b5 100644 (file)
@@ -1,3 +1,9 @@
+2013-04-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/56899
+       * fold-const.c (extract_muldiv_1): Apply distributive law
+       only if TYPE_OVERFLOW_WRAPS (ctype).
+
 2013-04-11  Bin Cheng  <bin.cheng@arm.com>
 
        PR target/56124
index dcf7aa0d6a5040ec24a29eb13fd154b378381a92..467b6d6561959978a7b4a3f2c765e3917e80fd28 100644 (file)
@@ -5850,8 +5850,10 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
 
       /* The last case is if we are a multiply.  In that case, we can
         apply the distributive law to commute the multiply and addition
-        if the multiplication of the constants doesn't overflow.  */
-      if (code == MULT_EXPR)
+        if the multiplication of the constants doesn't overflow
+        and overflow is defined.  With undefined overflow
+        op0 * c might overflow, while (op0 + orig_op1) * c doesn't.  */
+      if (code == MULT_EXPR && TYPE_OVERFLOW_WRAPS (ctype))
        return fold_build2 (tcode, ctype,
                            fold_build2 (code, ctype,
                                         fold_convert (ctype, op0),
index ef84fe1a495c64322daea4fcf68957cc900dd5be..62557021bba8be0acf7a62ee9384863870dc5f77 100644 (file)
@@ -1,3 +1,8 @@
+2013-04-11  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/56899
+       * gcc.c-torture/execute/pr56899.c: New test.
+
 2013-04-10  David S. Miller  <davem@davemloft.net>
 
        * gcc.target/sparc/setcc-4.c: New test.
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr56899.c b/gcc/testsuite/gcc.c-torture/execute/pr56899.c
new file mode 100644 (file)
index 0000000..9adf9af
--- /dev/null
@@ -0,0 +1,47 @@
+/* PR tree-optimization/56899 */
+
+#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8
+__attribute__((noinline, noclone)) void
+f1 (int v)
+{
+  int x = -214748365 * (v - 1);
+  if (x != -1932735285)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f2 (int v)
+{
+  int x = 214748365 * (v + 1);
+  if (x != -1932735285)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f3 (unsigned int v)
+{
+  unsigned int x = -214748365U * (v - 1);
+  if (x != -1932735285U)
+    __builtin_abort ();
+}
+
+__attribute__((noinline, noclone)) void
+f4 (unsigned int v)
+{
+  unsigned int x = 214748365U * (v + 1);
+  if (x != -1932735285U)
+    __builtin_abort ();
+}
+#endif
+
+int
+main ()
+{
+#if __SIZEOF_INT__ == 4 && __CHAR_BIT__ == 8
+  f1 (10);
+  f2 (-10);
+  f3 (10);
+  f4 (-10U);
+#endif
+  return 0;
+}