PATCH: fix PR tree-optimization/39874
Richard Guenther
richard.guenther@gmail.com
Tue Jun 1 11:30:00 GMT 2010
On Tue, Jun 1, 2010 at 2:32 AM, Sandra Loosemore
<sandra@codesourcery.com> wrote:
> This patch adds some more sophisticated logic for simplifying logical AND
> and OR expressions to fix PR39874, one of the sub-cases of PR28685.
>
> The test case illustrates the problem:
>
> void func();
> void test(char *signature)
> {
> char ch = signature[0];
> if (ch == 15 || ch == 3)
> {
> if (ch == 15) func();
> }
> }
>
> Here, the ifcombine pass was being too stupid to optimize away the outer
> "if" because it was relying on combine_comparisons only to detect when it
> can do that. So, the basic idea of my patch is to provide better logic for
> optimizing logical ANDs and ORs in the ifcombine pass. I recently added a
> patch to tree_ssa_reassoc that also used combine_comparisons for a similar
> purpose to fix another one of the PR28685 sub-cases, and my new functions
> can apply there as well.
>
> This patch didn't really start out being quite this complicated, but once I
> got started I figured I might as well add all the usual boolean identities
> and comparison simplifications. Much of this duplicates simplifications
> that are performed on trees in fold-const.c, but my code deals with gimple
> representations and simplifications that can be performed by
> copy-propagating SSA variables. (E.g., in the example above, the "ch == 15"
> expression is PRE'ed coming into the ifcombine pass.)
>
> This patch passed 3-stage bootstrap and testing on native x86_64 Linux. I
> also tested on ARM Linux, and ran SPEC benchmarks on ARM to make sure this
> wasn't accidentally un-optimizing something else. OK to check in?
+ fold_convert (TREE_TYPE (expr), integer_zero_node));
use build_int_cst (TREE_TYPE (expr), 0).
+/* Check to see if a boolean expression OP0 is logically equivalent to the
+ comparison (OP1 CODE OP2). Check for various identities involving
+ SSA_NAMEs. */
+
+static bool
+same_bool_comparison_p (const_tree op0, enum tree_code code,
+ const_tree op1, const_tree op2)
I think op0 is an unfortunate name, 'expr' would be better.
+ if (is_gimple_assign (s = SSA_NAME_DEF_STMT (op0)))
+ {
please move the assignment before the if ().
+ /* If op1 is of the form (name != 0) or (name == 0), and the definition
+ of name is a comparison, recurse. */
+ if (TREE_CODE (op1) == SSA_NAME
+ && TREE_TYPE (op1) == boolean_type_node
+ && is_gimple_assign (s = SSA_NAME_DEF_STMT (op1))
likewise.
Instead of testing for equality to boolean_type_node please
replace the checks with a check for TREE_CODE (TREE_TYPE (op1)) == BOOLEAN_TYPE.
+ if (TREE_CODE (op1) == INTEGER_CST || TREE_CODE (op2) == INTEGER_CST)
+ return operand_equal_p (op1, op2, 0);
tree_int_cst_equal ()
you fall back to operand_equal_p later, so why not do that test
here first like
if (operand_equal_p (op1, op2, 0))
return true;
and fall back to return false?
+ if ((code2 == NE_EXPR && integer_zerop (op2b))
+ || (code2 == EQ_EXPR && integer_nonzerop (op2b)))
I see this pattern in multiple places - as you check for
BOOLEAN_TYPE on var and later do an equality comparison
with op2a you know that that also has BOOLEAN_TYPE and
thus we should have canonicalized bool == 1 to plain bool
by fold.
+ /* maybe_fold_and_comparisons and maybe_fold_or_comparisons
+ always give us a boolean_type_node value back. If the original
+ BIT_AND_EXPR or BIT_IOR_EXPR was of a wider integer type,
+ we need to convert. */
+ t = fold_convert (TREE_TYPE (curr->op), t);
guard this with if (!useless_type_conversion_p (TREE_TYPE (curr->op),
TREE_TYPE (t))
Overall the patch is large and it feels like it duplicates a lot of
code from fold-const (but indeed in a better way, without building
trees all the time). Please give others the chance to review it (I
know I get distracted after a while when looking at large patches like
this ... ;)).
Thus - the patch is ok if nobody dares to give it another look within a week.
Thanks,
Richard.
> -Sandra
>
>
> 2010-05-31 Sandra Loosemore <sandra@codesourcery.com>
>
> PR tree-optimization/39874
> PR middle-end/28685
>
> gcc/
> * gimple.h (maybe_fold_and_comparisons, maybe_fold_or_comparisons):
> Declare.
> * gimple-fold.c (canonicalize_bool, same_bool_comparison_p,
> same_bool_result_p): New.
> (and_var_with_comparison, and_var_with_comparison_1,
> and_comparisons_1, and_comparisons, maybe_fold_and_comparisons): New.
> (or_var_with_comparison, or_var_with_comparison_1,
> or_comparisons_1, or_comparisons, maybe_fold_or_comparisons): New.
> * tree-ssa-reassoc.c (eliminate_redundant_comparison): Use
> maybe_fold_and_comparisons or maybe_fold_or_comparisons instead
> of combine_comparisons.
> * tree-ssa-ifcombine.c (ifcombine_ifandif, ifcombine_iforif):
> Likewise.
>
> gcc/testsuite/
> * gcc.dg/pr39874.c: New file.
>
More information about the Gcc-patches
mailing list