aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2013-04-11 09:30:20 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2013-04-11 09:30:20 +0200
commit146b8692e33b78872476435d084d5062a243a200 (patch)
treecfb012f8c9037ad4b63ec4f3e82cbc88f9a21773 /gcc
parentb8578ff77f8ea4d23fa5edc2805e1f3625b46c14 (diff)
downloadgcc-146b8692e33b78872476435d084d5062a243a200.zip
gcc-146b8692e33b78872476435d084d5062a243a200.tar.gz
gcc-146b8692e33b78872476435d084d5062a243a200.tar.bz2
re PR tree-optimization/56899 (Wrong constant folding)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/fold-const.c6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr56899.c47
4 files changed, 62 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7e1cc32..bab67ab 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index dcf7aa0..467b6d6 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -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),
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ef84fe1..6255702 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..9adf9af
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr56899.c
@@ -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;
+}