This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/46316] [4.6 regression] incorrect loop optimization


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46316

--- Comment #16 from davidxl <xinliangli at gmail dot com> 2010-11-08 08:18:31 UTC ---
The revised patch:


Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c    (revision 166426)
+++ gcc/tree-vrp.c    (working copy)
@@ -3403,13 +3403,18 @@ adjust_range_with_scev (value_range_t *v
     {
       value_range_t maxvr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
       double_int dtmp;
-      dtmp = double_int_mul (tree_to_double_int (step),
-                 double_int_sub (loop->nb_iterations_upper_bound,
-                         double_int_one));
+      bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (step));
+      int overflow = 0;
+
+      dtmp = double_int_mul_with_sign (tree_to_double_int (step),
+                                       double_int_sub (
+                                           loop->nb_iterations_upper_bound,
+                                           double_int_one),
+                                       unsigned_p, &overflow);
       tem = double_int_to_tree (TREE_TYPE (init), dtmp);
       /* If the multiplication overflowed we can't do a meaningful
      adjustment.  */
-      if (double_int_equal_p (dtmp, tree_to_double_int (tem)))
+      if (!overflow && double_int_equal_p (dtmp, tree_to_double_int (tem)))
     {
       extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
                       TREE_TYPE (init), init, tem);
Index: gcc/double-int.c
===================================================================
--- gcc/double-int.c    (revision 166426)
+++ gcc/double-int.c    (working copy)
@@ -718,6 +718,19 @@ double_int_mul (double_int a, double_int
   return ret;
 }

+/* Returns A * B. If the operation overflows according to UNSIGNED_P,
+   *OVERFLOW is set to nonzero.  */
+
+double_int
+double_int_mul_with_sign (double_int a, double_int b,
+                          bool unsigned_p, int *overflow)
+{
+  double_int ret;
+  *overflow = mul_double_with_sign (a.low, a.high, b.low, b.high,
+                                    &ret.low, &ret.high, unsigned_p);
+  return ret;
+}
+
 /* Returns A + B.  */

 double_int
Index: gcc/double-int.h
===================================================================
--- gcc/double-int.h    (revision 166426)
+++ gcc/double-int.h    (working copy)
@@ -132,6 +132,7 @@ double_int_fits_in_uhwi_p (double_int cs
    2 * HOST_BITS_PER_WIDE_INT bits.  */

 double_int double_int_mul (double_int, double_int);
+double_int double_int_mul_with_sign (double_int, double_int, bool, int *);
 double_int double_int_add (double_int, double_int);
 double_int double_int_sub (double_int, double_int);
 double_int double_int_neg (double_int);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]