This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH 2/5][P1][tree-optimization/71437] Record more equivalences in some cases
On Wed, Mar 15, 2017 at 09:18:27PM -0600, Jeff Law wrote:
> On 03/15/2017 09:17 PM, Jeff Law wrote:
> >
> > Patch #3 will remove handle_dominating_asserts from the core of the jump
> > threading code and push it into VRP's callbacks where it should always
> > have been.
> >
> > As a side effect it causes some code which was previously only used for
> > threading from VRP to be used unconditionally. It's actually a good
> > thing as that code will find more jump threads. But in one case the
> > resulting code is tougher for tree-ssa-uninit.c to handle and we get a
> > false positive uninit warning.
> >
> > As it turns out for that case we're better off improving DOM slightly
> > which allows DOM to simplify the test even further. This patch
> > implements the DOM improvement so that we don't see a regression when
> > patch #3 is installed.
> >
> > The particular case we're looking to improve looks like
> >
> > t = a | b;
> > if (t == 0)
> > ...
> >
> > In the TRUE arm we know that a must be zero and b must be zero.
> > Discovering those equivalences allows DOM to do a better job for the
> > uninit testcase from the testsuite.
> >
> > There's clearly more that could be done with this code, but I didn't
> > want to take it any further than was needed to address the regression
> > that would be caused by patch #3.
> >
> > Bootstrapped and regression tested on x86_64-linux-gnu. Installing on
> > the trunk. I'll be testing this in combination with patch #1 tomorrow
> > on ppc64le to get additional coverage.
> >
> > Jeff
> Whoops. This time with the patch.
>
> Jeff
> PR tree-optimization/71437
> * tree-ssa-dom.c (derive_equivalences_from_bit_ior): New function.
> (record_temporary_equivalences): Use it.
>
> diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
> index ad71269..0ebe892 100644
> --- a/gcc/tree-ssa-dom.c
> +++ b/gcc/tree-ssa-dom.c
> @@ -691,6 +691,33 @@ back_propagate_equivalences (tree lhs, edge e,
> BITMAP_FREE (domby);
> }
>
> +/* Record NAME has the value zero and if NAME was set from a BIT_IOR_EXPR
> + recurse into both operands recording their values as zero too. */
> +
> +static void
> +derive_equivalencs_from_bit_ior (tree name, const_and_copies *const_and_copies)
> +{
> + if (TREE_CODE (name) == SSA_NAME)
> + {
> + tree value = fold_convert (TREE_TYPE (name), integer_zero_node);
> +
> + /* This records the equivalence for the toplevel object. */
> + record_equality (name, value, const_and_copies);
> +
> + /* And we can recurse into each operand to potentially find more
> + equivalences. */
> + gimple *def_stmt = SSA_NAME_DEF_STMT (name);
> + if (is_gimple_assign (def_stmt)
> + && gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR)
> + {
> + derive_equivalencs_from_bit_ior (gimple_assign_rhs1 (def_stmt),
> + const_and_copies);
> + derive_equivalencs_from_bit_ior (gimple_assign_rhs2 (def_stmt),
> + const_and_copies);
> + }
> + }
> +}
> +
> /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied
> by traversing edge E (which are cached in E->aux).
>
> @@ -711,7 +738,28 @@ record_temporary_equivalences (edge e,
> /* If we have 0 = COND or 1 = COND equivalences, record them
> into our expression hash tables. */
> for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i)
> - avail_exprs_stack->record_cond (eq);
> + {
> + avail_exprs_stack->record_cond (eq);
> +
> + /* If the condition is testing that X == 0 is true or X != 0 is false
> + and X is set from a BIT_IOR_EXPR, then we can record equivalences
> + for the operands of the BIT_IOR_EXPR (and recurse on those). */
> + tree op0 = eq->cond.ops.binary.opnd0;
> + tree op1 = eq->cond.ops.binary.opnd1;
> + if (TREE_CODE (op0) == SSA_NAME && integer_zerop (op1))
> + {
> + enum tree_code code = eq->cond.ops.binary.op;
> + if ((code == EQ_EXPR && eq->value == boolean_true_node)
> + || (code == NE_EXPR && eq->value == boolean_false_node))
> + derive_equivalencs_from_bit_ior (op0, const_and_copies);
> +
> + /* TODO: We could handle BIT_AND_EXPR in a similar fashion
> + recording that the operands have a nonzero value. */
> +
> + /* TODO: We can handle more cases here, particularly when OP0 is
> + known to have a boolean range. */
I don't think its necessarily useful to put a list here of all possible
improvements, but we could also handle things like if ((a | b) </> 0)
since those imply !=.
Trev