From d7b339dd2a56fdc490df97f54cc031862bc35470 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 30 Apr 2008 15:06:16 +0000 Subject: [PATCH] re PR tree-optimization/14847 ([tree-ssa] combine "if (a & 1) goto there" and "if (a & 4) goto there") 2008-04-30 Richard Guenther 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 | 7 ++++ gcc/testsuite/ChangeLog | 5 +++ .../gcc.dg/tree-ssa/ssa-ifcombine-6.c | 37 +++++++++++++++++++ gcc/tree-ssa-ifcombine.c | 30 ++++++++++++++- 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-6.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 725aa2dce63..dc1555bf219 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-04-30 Richard Guenther + + 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 * ipa-cp.c (ipcp_init_stage): Calls ipa_set_called_with_variable_arg diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b0c5d64b369..e16eaff42bd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-04-30 Richard Guenther + + PR tree-optimization/14847 + * gcc.dg/tree-ssa/ssa-ifcombine-6.c: New testcase. + 2008-04-30 Jakub Jelinek 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 index 00000000000..90abc8debc9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-6.c @@ -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" } } */ diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index cec5868c636..3a28fadd792 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -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; -- 2.30.2