This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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" } } */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]