The following patch fixes PR70450 where I (again...) was not able
to decipher wide-int workings in a first try.  (the 'sign' op
looks redundant for a tree wide_int::from so I was thinking it
must apply to the destination to specify eventual zero/sign-extension
if the 'precision' arg is not a multiple of HWI bits - appearantly
a case that needs to be handled separately - I wonder about
lurking bits in other similar users for this case).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2016-03-30  Richard Biener  <rguent...@suse.de>

        PR middle-end/70450
        * fold-const.c (extract_muldiv_1): Fix thinko in wide_int::from
        usage.

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

Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c    (revision 234546)
--- gcc/fold-const.c    (working copy)
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 6375,6382 ****
          bool overflow_mul_p;
          signop sign = TYPE_SIGN (ctype);
          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
--- 6375,6384 ----
          bool overflow_mul_p;
          signop sign = TYPE_SIGN (ctype);
          unsigned prec = TYPE_PRECISION (ctype);
!         wide_int mul = wi::mul (wide_int::from (op1, prec,
!                                                 TYPE_SIGN (TREE_TYPE (op1))),
!                                 wide_int::from (c, prec,
!                                                 TYPE_SIGN (TREE_TYPE (c))),
                                  sign, &overflow_mul_p);
          overflow_p = TREE_OVERFLOW (c) | TREE_OVERFLOW (op1);
          if (overflow_mul_p
Index: gcc/testsuite/gcc.dg/torture/pr70450.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr70450.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr70450.c      (working copy)
***************
*** 0 ****
--- 1,19 ----
+ /* { dg-do run } */
+ /* { dg-require-effective-target lp64 } */
+ 
+ unsigned long int a = 2UL;
+ int b = 2;
+ unsigned long int c = 2UL;
+ 
+ void foo ()
+ {
+   c = 2 * ((2 * a) * (2 * (-b)));
+ }
+ 
+ int main ()
+ {
+   foo();
+   if (c != 18446744073709551584UL)
+     __builtin_abort();
+   return 0;
+ }

Reply via email to