]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR tree-optimization/51721 (-Warray-bounds false positives and inconsistencies)
authorJakub Jelinek <jakub@redhat.com>
Mon, 12 Mar 2012 11:12:49 +0000 (12:12 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 12 Mar 2012 11:12:49 +0000 (12:12 +0100)
PR tree-optimization/51721
* tree-vrp.c (register_edge_assert_for_2): Add asserts for unsvar
if (int) unsvar cmp CST.

* gcc.dg/tree-ssa/vrp64.c: New test.

From-SVN: r185222

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/vrp64.c [new file with mode: 0644]
gcc/tree-vrp.c

index b35706a8faccf2974d6ea755ba38e8355e1dc8ed..a408ce7aef5f4be04b4006388f0bf49cf311e537 100644 (file)
@@ -1,3 +1,9 @@
+2012-03-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/51721
+       * tree-vrp.c (register_edge_assert_for_2): Add asserts for unsvar
+       if (int) unsvar cmp CST.
+
 2012-03-12  Richard Guenther  <rguenther@suse.de>
 
         * tree-sra.c (create_access_replacement): Only rename the
index 4721de45ce15703ddf37742c1bc5bbe87c652cff..29981edae1f880ad433f46785fa712e53791e415 100644 (file)
@@ -1,5 +1,8 @@
 2012-03-12  Jakub Jelinek  <jakub@redhat.com>
 
+       PR tree-optimization/51721
+       * gcc.dg/tree-ssa/vrp64.c: New test.
+
        PR tree-optimization/52533
        * gcc.c-torture/compile/pr52533.c: New test.
 
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp64.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp64.c
new file mode 100644 (file)
index 0000000..2ab328f
--- /dev/null
@@ -0,0 +1,152 @@
+/* PR tree-optimization/51721 */
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+
+extern void link_error (void);
+
+#define BITSM1 (sizeof (int) * __CHAR_BIT__ - 1)
+
+void
+f1 (unsigned int s)
+{
+  if (s >> BITSM1 != 0)
+    {
+      if (s == 0 || s == 5 || s == __INT_MAX__)
+       link_error ();
+    }
+  else
+    {
+      if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U)
+       link_error ();
+    }
+}
+
+void
+f2 (int s)
+{
+  if (s >> BITSM1 == 0)
+    {
+      if (s == -1 || s == -5 || s == -__INT_MAX__ - 1)
+       link_error ();
+    }
+  else
+    {
+      if (s == 0 || s == 5 || s == __INT_MAX__)
+       link_error ();
+    }
+}
+
+void
+f3 (unsigned int s)
+{
+  if ((s & (1U << BITSM1)) != 0)
+    {
+      if (s == 0 || s == 5 || s == __INT_MAX__)
+       link_error ();
+    }
+  else
+    {
+      if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U)
+       link_error ();
+    }
+}
+
+void
+f4 (int s)
+{
+  if ((s & (1U << BITSM1)) == 0)
+    {
+      if (s == -1 || s == -5 || s == -__INT_MAX__ - 1)
+       link_error ();
+    }
+  else
+    {
+      if (s == 0 || s == 5 || s == __INT_MAX__)
+       link_error ();
+    }
+}
+
+void
+f5 (unsigned int s)
+{
+  if ((int) s < 0)
+    {
+      if (s == 0 || s == 5 || s == __INT_MAX__)
+       link_error ();
+    }
+  else
+    {
+      if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U)
+       link_error ();
+    }
+}
+
+void
+f6 (unsigned int s)
+{
+  if ((int) s < 4)
+    {
+      if (s == 4 || s == 6 || s == __INT_MAX__)
+       link_error ();
+    }
+  else
+    {
+      if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U
+         || s == 3 || s == 0)
+       link_error ();
+    }
+}
+
+void
+f7 (unsigned int s)
+{
+  if ((int) s <= -7)
+    {
+      if (s == -6U || s == -1U || s == 0 || s == 4 || s == 6 || s == __INT_MAX__)
+       link_error ();
+    }
+  else
+    {
+      if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -9U
+         || s == -7U)
+       link_error ();
+    }
+}
+
+void
+f8 (unsigned int s)
+{
+  if ((int) s >= 4)
+    {
+      if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -1U
+         || s == 3 || s == 0)
+       link_error ();
+    }
+  else
+    {
+      if (s == 4 || s == 6 || s == __INT_MAX__)
+       link_error ();
+    }
+}
+
+void
+f9 (unsigned int s)
+{
+  if ((int) s > -7)
+    {
+      if (s == 1U + __INT_MAX__ || s == 6U + __INT_MAX__ || s == -9U
+         || s == -7U)
+       link_error ();
+    }
+  else
+    {
+      if (s == -6U || s == -1U || s == 0 || s == 4 || s == 6 || s == __INT_MAX__)
+       link_error ();
+    }
+}
+
+int
+main ()
+{
+  return 0;
+}
index febe33f93c0fc2302dd321261ba23dcb5b32d1eb..5f89da9297a5ea42d2da5983e3a641428e191d30 100644 (file)
@@ -4462,8 +4462,6 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
        }
     }
 
-  /* Similarly add asserts for NAME == CST and NAME being defined as
-     NAME = NAME2 >> CST2.  */
   if (TREE_CODE_CLASS (comp_code) == tcc_comparison
       && TREE_CODE (val) == INTEGER_CST)
     {
@@ -4473,7 +4471,60 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
       double_int mask = double_int_zero;
       unsigned int prec = TYPE_PRECISION (TREE_TYPE (val));
 
-      /* Extract CST2 from the right shift.  */
+      /* Add asserts for NAME cmp CST and NAME being defined
+        as NAME = (int) NAME2.  */
+      if (!TYPE_UNSIGNED (TREE_TYPE (val))
+         && (comp_code == LE_EXPR || comp_code == LT_EXPR
+             || comp_code == GT_EXPR || comp_code == GE_EXPR)
+         && gimple_assign_cast_p (def_stmt))
+       {
+         name2 = gimple_assign_rhs1 (def_stmt);
+         if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
+             && INTEGRAL_TYPE_P (TREE_TYPE (name2))
+             && TYPE_UNSIGNED (TREE_TYPE (name2))
+             && prec == TYPE_PRECISION (TREE_TYPE (name2))
+             && (comp_code == LE_EXPR || comp_code == GT_EXPR
+                 || !tree_int_cst_equal (val,
+                                         TYPE_MIN_VALUE (TREE_TYPE (val))))
+             && live_on_edge (e, name2)
+             && !has_single_use (name2))
+           {
+             tree tmp, cst;
+             enum tree_code new_comp_code = comp_code;
+
+             cst = fold_convert (TREE_TYPE (name2),
+                                 TYPE_MIN_VALUE (TREE_TYPE (val)));
+             /* Build an expression for the range test.  */
+             tmp = build2 (PLUS_EXPR, TREE_TYPE (name2), name2, cst);
+             cst = fold_build2 (PLUS_EXPR, TREE_TYPE (name2), cst,
+                                fold_convert (TREE_TYPE (name2), val));
+             if (comp_code == LT_EXPR || comp_code == GE_EXPR)
+               {
+                 new_comp_code = comp_code == LT_EXPR ? LE_EXPR : GT_EXPR;
+                 cst = fold_build2 (MINUS_EXPR, TREE_TYPE (name2), cst,
+                                    build_int_cst (TREE_TYPE (name2), 1));
+               }
+
+             if (dump_file)
+               {
+                 fprintf (dump_file, "Adding assert for ");
+                 print_generic_expr (dump_file, name2, 0);
+                 fprintf (dump_file, " from ");
+                 print_generic_expr (dump_file, tmp, 0);
+                 fprintf (dump_file, "\n");
+               }
+
+             register_new_assert_for (name2, tmp, new_comp_code, cst, NULL,
+                                      e, bsi);
+
+             retval = true;
+           }
+       }
+
+      /* Add asserts for NAME cmp CST and NAME being defined as
+        NAME = NAME2 >> CST2.
+
+        Extract CST2 from the right shift.  */
       if (is_gimple_assign (def_stmt)
          && gimple_assign_rhs_code (def_stmt) == RSHIFT_EXPR)
        {
@@ -4491,7 +4542,6 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
              val2 = fold_binary (LSHIFT_EXPR, TREE_TYPE (val), val, cst2);
            }
        }
-
       if (val2 != NULL_TREE
          && TREE_CODE (val2) == INTEGER_CST
          && simple_cst_equal (fold_build2 (RSHIFT_EXPR,