This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH][RFC] Teach tree-loop-im to rewrite (A >> B) & 1
Hello,
> > Right, this is only equal if we compare the result with zero in a COND_EXPR.
> > I'll add code to verify that and split the transformation out in extra
> > functions.
>
> Here is it. Bootstrapped and tested on x86_64-unknown-linux-gnu. Is
> this ok with you?
yes, but see the comments below. IMHO it would also be cleaner to move all
the tests (TREE_CODE (rhs) == ... and so on) into rewrite_reciprocal and
rewrite_bittest, and perhaps extend the comments a bit, but I may do
that in a followup patch.
> + /* Get at the operands of the shift. The rhs is TMP1 & 1. */
> + stmt1 = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
> + if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT)
> + return stmt;
> +
> + /* From TMP1 get to the right shift. There is a conversion inbetween
> + possibly inserted by fold. */
> + t = GIMPLE_STMT_OPERAND (stmt1, 1);
> + if (TREE_CODE (t) == NOP_EXPR
> + || TREE_CODE (t) == CONVERT_EXPR)
> + t = TREE_OPERAND (t, 0);
> + if (TREE_CODE (t) != SSA_NAME
> + || !has_single_use (t))
> + return stmt;
this seems to match only the code
x = a >> b;
y = (cast) x;
z = y & 1;
however it would fail for
x = a >> b;
z = x & 1;
?
> + /* Get STMT1, the statement with the A >> B rhs. */
> + stmt1 = SSA_NAME_DEF_STMT (t);
> + if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT)
> + return stmt;
> +
> + /* Verify that B is loop invariant but A is not. Verify that with
> + all the stmt walking we are still in the same loop. */
> + t = GIMPLE_STMT_OPERAND (stmt1, 1);
> + if (TREE_CODE (t) == RSHIFT_EXPR
> + && loop_containing_stmt (stmt1) == loop_containing_stmt (stmt)
> + && outermost_invariant_loop_expr (TREE_OPERAND (t, 1),
> + loop_containing_stmt (stmt1)) != NULL
> + && outermost_invariant_loop_expr (TREE_OPERAND (t, 0),
> + loop_containing_stmt (stmt1)) == NULL)
> + {
> + tree a = TREE_OPERAND (t, 0);
> + tree b = TREE_OPERAND (t, 1);
> +
> + /* 1 << B */
> + var = create_tmp_var (TREE_TYPE (a), "shifttmp");
> + add_referenced_var (var);
> + t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (a),
> + integer_one_node, b);
this should probably be build_int_cst (TREE_TYPE (a), 1)
Zdenek