2016-03-22 Richard Biener <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Mar 2016 13:23:00 +0000 (13:23 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 22 Mar 2016 13:23:00 +0000 (13:23 +0000)
PR middle-end/70333
* fold-const.c (extract_muldiv_1): Properly perform multiplication
in the wide type.

* gcc.dg/torture/pr70333.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234401 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 973fdff..01f38d0 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-22  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70333
+       * fold-const.c (extract_muldiv_1): Properly perform multiplication
+       in the wide type.
+
 2016-03-22  Kirill Yukhin  <kirill.yukhin@intel.com>
 
        * config/i386/i386.c (def_builtin): Remove duplicated functionality.
index 696b4a6..9d861c6 100644 (file)
@@ -6376,18 +6376,17 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
          bool overflow_p = false;
          bool overflow_mul_p;
          signop sign = TYPE_SIGN (ctype);
-         wide_int mul = wi::mul (op1, c, sign, &overflow_mul_p);
+         unsigned prec = TYPE_PRECISION (ctype);
+         wide_int mul = wi::mul (wide_int::from (op1, prec, sign),
+                                 wide_int::from (c, prec, sign),
+                                 sign, &overflow_mul_p);
          overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1);
          if (overflow_mul_p
              && ((sign == UNSIGNED && tcode != MULT_EXPR) || sign == SIGNED))
            overflow_p = true;
          if (!overflow_p)
-           {
-             mul = wide_int::from (mul, TYPE_PRECISION (ctype),
-                                   TYPE_SIGN (TREE_TYPE (op1)));
-             return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
-                                 wide_int_to_tree (ctype, mul));
-           }
+           return fold_build2 (tcode, ctype, fold_convert (ctype, op0),
+                               wide_int_to_tree (ctype, mul));
        }
 
       /* If these operations "cancel" each other, we have the main
index 49f9e08..f568f1b 100644 (file)
@@ -1,3 +1,8 @@
+2016-03-22  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70333
+       * gcc.dg/torture/pr70333.c: New testcase.
+
 2016-03-22  Ilya Enkovich  <enkovich.gnu@gmail.com>
 
        * g++.dg/ext/pr70290.C: New test.
diff --git a/gcc/testsuite/gcc.dg/torture/pr70333.c b/gcc/testsuite/gcc.dg/torture/pr70333.c
new file mode 100644 (file)
index 0000000..854e6d5
--- /dev/null
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+
+unsigned long int
+foo (signed char b, signed char e)
+{
+  return ((2ULL * b) * (e * 13)) * (32 << 24);
+}
+
+int
+main ()
+{
+  if (__CHAR_BIT__ == 8
+      && sizeof (int) == 4
+      && sizeof (long long) == 8
+      && foo (-60, 1) != 0xffffff3d00000000ULL)
+    __builtin_abort ();
+  return 0;
+}