re PR tree-optimization/69615 (0 to limit signed range checks don't always use unsign...
authorJakub Jelinek <jakub@redhat.com>
Thu, 7 Jun 2018 07:41:18 +0000 (09:41 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 7 Jun 2018 07:41:18 +0000 (09:41 +0200)
PR tree-optimization/69615
* tree-ssa-reassoc.c (optimize_range_tests_var_bound): If rhs2 is lhs
of a cast from a same precision integral SSA_NAME in a bb dominated
by first_bb, retry with rhs2 set to the rhs1 of the cast.  Don't emit
cast to utype if rhs2 has already a compatible type.

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

From-SVN: r261264

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

index f6f3fe78f10a7616444cd8217b5a407566289e52..ccc02bafa41c6d2016c9c206a6f1332bb4b2ed3b 100644 (file)
@@ -1,3 +1,11 @@
+2018-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/69615
+       * tree-ssa-reassoc.c (optimize_range_tests_var_bound): If rhs2 is lhs
+       of a cast from a same precision integral SSA_NAME in a bb dominated
+       by first_bb, retry with rhs2 set to the rhs1 of the cast.  Don't emit
+       cast to utype if rhs2 has already a compatible type.
+
 2018-06-07  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/85935
index 989e497704fa0d461797dd4e4b5022394f30c846..5015f598fa7bae145d952435ed52bd262207d54f 100644 (file)
@@ -1,3 +1,8 @@
+2018-06-07  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/69615
+       * gcc.dg/tree-ssa/pr69615.c: New test.
+
 2018-06-07  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/85935
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr69615.c b/gcc/testsuite/gcc.dg/tree-ssa/pr69615.c
new file mode 100644 (file)
index 0000000..f5c4d8a
--- /dev/null
@@ -0,0 +1,16 @@
+/* PR tree-optimization/69615 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not " >= 0" "optimized" } } */
+/* { dg-final { scan-tree-dump-not " < 0" "optimized" } } */
+
+extern void foo (void);
+
+void
+bar (int z, unsigned int y)
+{
+  long long x = z;
+  y &= 0xf;
+  if (x >= 0 && x < (int) y)
+    foo ();
+}
index 38bae77ddbc70e9496913fe252e881b9da2f7a47..48d402b99fb545c602b2bba7b41bbd9b3a6c28df 100644 (file)
@@ -3172,7 +3172,7 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
         to (unsigned) k_32 < (unsigned) iftmp.0_44, then we would execute
         those stmts even for negative k_32 and the value ranges would be no
         longer guaranteed and so the optimization would be invalid.  */
-      if (opcode == ERROR_MARK)
+      while (opcode == ERROR_MARK)
        {
          gimple *g = SSA_NAME_DEF_STMT (rhs2);
          basic_block bb2 = gimple_bb (g);
@@ -3182,21 +3182,37 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
            {
              /* As an exception, handle a few common cases.  */
              if (gimple_assign_cast_p (g)
-                 && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g)))
-                 && TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g)))
-                 && (TYPE_PRECISION (TREE_TYPE (rhs2))
-                     > TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (g)))))
-               /* Zero-extension is always ok.  */ ;
+                 && INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (g))))
+               {
+                 tree op0 = gimple_assign_rhs1 (g);
+                 if (TYPE_UNSIGNED (TREE_TYPE (op0))
+                     && (TYPE_PRECISION (TREE_TYPE (rhs2))
+                         > TYPE_PRECISION (TREE_TYPE (op0))))
+                   /* Zero-extension is always ok.  */
+                   break;
+                 else if (TYPE_PRECISION (TREE_TYPE (rhs2))
+                          == TYPE_PRECISION (TREE_TYPE (op0))
+                          && TREE_CODE (op0) == SSA_NAME)
+                   {
+                     /* Cast from signed to unsigned or vice versa.  Retry
+                        with the op0 as new rhs2.  */
+                     rhs2 = op0;
+                     continue;
+                   }
+               }
              else if (is_gimple_assign (g)
                       && gimple_assign_rhs_code (g) == BIT_AND_EXPR
                       && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST
                       && !wi::neg_p (wi::to_wide (gimple_assign_rhs2 (g))))
                /* Masking with INTEGER_CST with MSB clear is always ok
-                  too.  */ ;
-             else
-               continue;
+                  too.  */
+               break;
+             rhs2 = NULL_TREE;
            }
+         break;
        }
+      if (rhs2 == NULL_TREE)
+       continue;
 
       wide_int nz = get_nonzero_bits (rhs2);
       if (wi::neg_p (nz))
@@ -3253,10 +3269,13 @@ optimize_range_tests_var_bound (enum tree_code opcode, int first, int length,
       gimple_set_uid (g, uid);
       rhs1 = gimple_assign_lhs (g);
       gsi_insert_before (&gsi, g, GSI_SAME_STMT);
-      g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2);
-      gimple_set_uid (g, uid);
-      rhs2 = gimple_assign_lhs (g);
-      gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+      if (!useless_type_conversion_p (utype, TREE_TYPE (rhs2)))
+       {
+         g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, rhs2);
+         gimple_set_uid (g, uid);
+         rhs2 = gimple_assign_lhs (g);
+         gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+       }
       if (tree_swap_operands_p (rhs1, rhs2))
        {
          std::swap (rhs1, rhs2);