This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR14847, bit zero test not recognized in ifcombine
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 30 Apr 2008 17:03:36 +0200 (CEST)
- Subject: [PATCH] Fix PR14847, bit zero test not recognized in ifcombine
This adds the capability to recognize a fold-munged (a & 1) ! = 0 test
in the ifcombine pass.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: tree-ssa-ifcombine.c
===================================================================
*** tree-ssa-ifcombine.c (revision 134817)
--- tree-ssa-ifcombine.c (working copy)
*************** same_phi_args_p (basic_block bb1, basic_
*** 135,140 ****
--- 135,166 ----
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).
*************** recognize_single_bit_test (tree cond_exp
*** 192,198 ****
{
/* t & 1 */
*bit = integer_zero_node;
! *name = orig_name;
}
return true;
--- 218,224 ----
{
/* t & 1 */
*bit = integer_zero_node;
! *name = get_name_for_bit_test (orig_name);
}
return true;
*************** recognize_bits_test (tree cond_expr, tre
*** 272,278 ****
if (TREE_CODE (t) != BIT_AND_EXPR)
return false;
! *name = TREE_OPERAND (t, 0);
*bits = TREE_OPERAND (t, 1);
return true;
--- 298,304 ----
if (TREE_CODE (t) != BIT_AND_EXPR)
return false;
! *name = get_name_for_bit_test (TREE_OPERAND (t, 0));
*bits = TREE_OPERAND (t, 1);
return true;
Index: testsuite/gcc.dg/tree-ssa/ssa-ifcombine-6.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/ssa-ifcombine-6.c (revision 0)
--- testsuite/gcc.dg/tree-ssa/ssa-ifcombine-6.c (revision 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" } } */