+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
--- /dev/null
+/* { 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" } } */
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).
{
/* t & 1 */
*bit = integer_zero_node;
- *name = orig_name;
+ *name = get_name_for_bit_test (orig_name);
}
return true;
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;