re PR tree-optimization/14847 ([tree-ssa] combine "if (a & 1) goto there" and "if...
authorRichard Guenther <rguenther@suse.de>
Wed, 30 Apr 2008 15:06:16 +0000 (15:06 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 30 Apr 2008 15:06:16 +0000 (15:06 +0000)
2008-04-30  Richard Guenther  <rguenther@suse.de>

PR tree-optimization/14847
* tree-ssa-ifcombine.c (get_name_for_bit_test): New helper function.
(recognize_bits_test): Use it.
(recognize_single_bit_test): Likewise.

* gcc.dg/tree-ssa/ssa-ifcombine-6.c: New testcase.

From-SVN: r134825

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

index 725aa2dce63ddb1622bd051486337a4c89a1562b..dc1555bf219437c94191f973346936061621e00e 100644 (file)
@@ -1,3 +1,10 @@
+2008-04-30  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/14847
+       * tree-ssa-ifcombine.c (get_name_for_bit_test): New helper function.
+       (recognize_bits_test): Use it.
+       (recognize_single_bit_test): Likewise.
+
 2008-04-30  Martin Jambor  <mjambor@suse.cz>
 
        * ipa-cp.c (ipcp_init_stage): Calls ipa_set_called_with_variable_arg
index b0c5d64b369d33f1052004893b9ecd20d91d1c63..e16eaff42bd0523bfacf157b0043e5fe071d4dc9 100644 (file)
@@ -1,3 +1,8 @@
+2008-04-30  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/14847
+       * gcc.dg/tree-ssa/ssa-ifcombine-6.c: New testcase.
+
 2008-04-30  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/35986
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-6.c
new file mode 100644 (file)
index 0000000..90abc8d
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ifcombine" } */
+
+void bar (void);
+
+void
+foo1 (unsigned int a)
+{
+  if (a & 1)
+    goto heaven;
+  if (a & 4)
+    goto heaven;
+  return;
+
+ heaven:
+  bar ();
+}
+
+void
+foo2 (unsigned int a)
+{
+  if (a & 1)
+    if (a & 4)
+      goto heaven;
+  return;
+
+ heaven:
+  bar ();
+}
+
+
+/* The special treatment of a & 1 != 0 in fold caused the pattern not
+   to be recognized due to extra conversions inserted.  */
+
+/* { dg-final { scan-tree-dump "optimizing bits or bits test" "ifcombine" } } */
+/* { dg-final { scan-tree-dump "optimizing double bit test" "ifcombine" } } */
+/* { dg-final { cleanup-tree-dump "ifcombine" } } */
index cec5868c6364160a79cc3f9effa5633af91088bc..3a28fadd7920fecff6fecac68d30dacd28d96b6a 100644 (file)
@@ -135,6 +135,32 @@ same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
   return true;
 }
 
+/* Return the best representative SSA name for CANDIDATE which is used
+   in a bit test.  */
+
+static tree
+get_name_for_bit_test (tree candidate)
+{
+  /* Skip single-use names in favor of using the name from a
+     non-widening conversion definition.  */
+  if (TREE_CODE (candidate) == SSA_NAME
+      && has_single_use (candidate))
+    {
+      tree def_stmt = SSA_NAME_DEF_STMT (candidate);
+      if (TREE_CODE (def_stmt) == GIMPLE_MODIFY_STMT
+         && (TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == NOP_EXPR
+             || TREE_CODE (GIMPLE_STMT_OPERAND (def_stmt, 1)) == CONVERT_EXPR))
+       {
+         tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
+         if (TYPE_PRECISION (TREE_TYPE (rhs))
+             <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (rhs, 0))))
+           return TREE_OPERAND (rhs, 0);
+       }
+    }
+
+  return candidate;
+}
+
 /* Recognize a single bit test pattern in COND_EXPR and its defining
    statements.  Store the name being tested in *NAME and the bit
    in *BIT.  The COND_EXPR computes *NAME & (1 << *BIT).
@@ -192,7 +218,7 @@ recognize_single_bit_test (tree cond_expr, tree *name, tree *bit)
        {
          /* t & 1 */
          *bit = integer_zero_node;
-         *name = orig_name;
+         *name = get_name_for_bit_test (orig_name);
        }
 
       return true;
@@ -272,7 +298,7 @@ recognize_bits_test (tree cond_expr, tree *name, tree *bits)
   if (TREE_CODE (t) != BIT_AND_EXPR)
     return false;
 
-  *name = TREE_OPERAND (t, 0);
+  *name = get_name_for_bit_test (TREE_OPERAND (t, 0));
   *bits = TREE_OPERAND (t, 1);
 
   return true;