This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch] PR 32283
On Wed, Nov 19, 2008 at 5:18 PM, Zdenek Dvorak <rakdver@kam.mff.cuni.cz> wrote:
> Hi,
>
>> > this transformation is different from the one needed (this piece of
>> > code is turning ((x << 2) - 4) & ~3 to (x << 2) - 4).
>>
>> Oops, yes, the transformation I had in mind is still done (by
>> force_to_mode and simplify_and_const_int) in combine.c only.
>>
>> > However,
>> > implementing the required transformation using nonzero_bits would
>> > indeed be a better idea,
>>
>> Good, thanks.
>
> here is the new version. I kept the transformation (x-4) & 3 -> x & 3
> (even though it is not necessary to achieve the optimization), as it
> might be useful by itself.
The middle-end parts are ok.
Thanks,
Richard.
> Zdenek
>
> Index: tree-ssa-loop-niter.c
> ===================================================================
> *** tree-ssa-loop-niter.c (revision 141981)
> --- tree-ssa-loop-niter.c (working copy)
> *************** scev_probably_wraps_p (tree base, tree s
> *** 3053,3059 ****
>
> /* If we can use the fact that signed and pointer arithmetics does not
> wrap, we are done. */
> ! if (use_overflow_semantics && nowrap_type_p (type))
> return false;
>
> /* To be able to use estimates on number of iterations of the loop,
> --- 3053,3059 ----
>
> /* If we can use the fact that signed and pointer arithmetics does not
> wrap, we are done. */
> ! if (use_overflow_semantics && nowrap_type_p (TREE_TYPE (base)))
> return false;
>
> /* To be able to use estimates on number of iterations of the loop,
> Index: tree-ssa-loop-ivopts.c
> ===================================================================
> *** tree-ssa-loop-ivopts.c (revision 141981)
> --- tree-ssa-loop-ivopts.c (working copy)
> *************** rewrite_use_compare (struct ivopts_data
> *** 5323,5333 ****
> {
> tree var = var_at_stmt (data->current_loop, cand, use->stmt);
> tree var_type = TREE_TYPE (var);
>
> compare = iv_elimination_compare (data, use);
> bound = unshare_expr (fold_convert (var_type, bound));
> ! op = force_gimple_operand_gsi (&bsi, bound, true, NULL_TREE,
> ! true, GSI_SAME_STMT);
>
> gimple_cond_set_lhs (use->stmt, var);
> gimple_cond_set_code (use->stmt, compare);
> --- 5323,5337 ----
> {
> tree var = var_at_stmt (data->current_loop, cand, use->stmt);
> tree var_type = TREE_TYPE (var);
> + gimple_seq stmts;
>
> compare = iv_elimination_compare (data, use);
> bound = unshare_expr (fold_convert (var_type, bound));
> ! op = force_gimple_operand (bound, &stmts, true, NULL_TREE);
> ! if (stmts)
> ! gsi_insert_seq_on_edge_immediate (
> ! loop_preheader_edge (data->current_loop),
> ! stmts);
>
> gimple_cond_set_lhs (use->stmt, var);
> gimple_cond_set_code (use->stmt, compare);
> Index: simplify-rtx.c
> ===================================================================
> *** simplify-rtx.c (revision 141981)
> --- simplify-rtx.c (working copy)
> *************** simplify_binary_operation_1 (enum rtx_co
> *** 2304,2315 ****
> case AND:
> if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
> return trueop1;
> - /* If we are turning off bits already known off in OP0, we need
> - not do an AND. */
> if (GET_CODE (trueop1) == CONST_INT
> ! && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
> ! && (nonzero_bits (trueop0, mode) & ~INTVAL (trueop1)) == 0)
> ! return op0;
> if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
> && GET_MODE_CLASS (mode) != MODE_CC)
> return op0;
> --- 2304,2322 ----
> case AND:
> if (trueop1 == CONST0_RTX (mode) && ! side_effects_p (op0))
> return trueop1;
> if (GET_CODE (trueop1) == CONST_INT
> ! && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
> ! {
> ! HOST_WIDE_INT nzop0 = nonzero_bits (trueop0, mode);
> ! HOST_WIDE_INT val1 = INTVAL (trueop1);
> ! /* If we are turning off bits already known off in OP0, we need
> ! not do an AND. */
> ! if ((nzop0 & ~val1) == 0)
> ! return op0;
> ! /* If we are clearing all the nonzero bits, the result is zero. */
> ! if ((val1 & nzop0) == 0 && !side_effects_p (op0))
> ! return CONST0_RTX (mode);
> ! }
> if (rtx_equal_p (trueop0, trueop1) && ! side_effects_p (op0)
> && GET_MODE_CLASS (mode) != MODE_CC)
> return op0;
> *************** simplify_binary_operation_1 (enum rtx_co
> *** 2391,2397 ****
> ((A & N) + B) & M -> (A + B) & M
> Similarly if (N & M) == 0,
> ((A | N) + B) & M -> (A + B) & M
> ! and for - instead of + and/or ^ instead of |. */
> if (GET_CODE (trueop1) == CONST_INT
> && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
> && ~INTVAL (trueop1)
> --- 2398,2406 ----
> ((A & N) + B) & M -> (A + B) & M
> Similarly if (N & M) == 0,
> ((A | N) + B) & M -> (A + B) & M
> ! and for - instead of + and/or ^ instead of |.
> ! Also, if (N & M) == 0, then
> ! (A +- N) & M -> A & M. */
> if (GET_CODE (trueop1) == CONST_INT
> && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT
> && ~INTVAL (trueop1)
> *************** simplify_binary_operation_1 (enum rtx_co
> *** 2404,2409 ****
> --- 2413,2422 ----
> pmop[0] = XEXP (op0, 0);
> pmop[1] = XEXP (op0, 1);
>
> + if (GET_CODE (pmop[1]) == CONST_INT
> + && (INTVAL (pmop[1]) & INTVAL (trueop1)) == 0)
> + return simplify_gen_binary (AND, mode, pmop[0], op1);
> +
> for (which = 0; which < 2; which++)
> {
> tem = pmop[which];
> *************** simplify_plus_minus (enum rtx_code code,
> *** 3591,3600 ****
> ops[j + 1] = save;
> }
>
> - /* This is only useful the first time through. */
> - if (!canonicalized)
> - return NULL_RTX;
> -
> changed = 0;
> for (i = n_ops - 1; i > 0; i--)
> for (j = i - 1; j >= 0; j--)
> --- 3604,3609 ----
> *************** simplify_plus_minus (enum rtx_code code,
> *** 3650,3659 ****
> --- 3659,3673 ----
> ops[i].neg = lneg;
> ops[j].op = NULL_RTX;
> changed = 1;
> + canonicalized = 1;
> }
> }
> }
>
> + /* If nothing changed, fail. */
> + if (!canonicalized)
> + return NULL_RTX;
> +
> /* Pack all the operands to the lower-numbered entries. */
> for (i = 0, j = 0; j < n_ops; j++)
> if (ops[j].op)
> Index: loop-iv.c
> ===================================================================
> *** loop-iv.c (revision 141981)
> --- loop-iv.c (working copy)
> *************** simple_rhs_p (rtx rhs)
> *** 1337,1349 ****
> case MINUS:
> op0 = XEXP (rhs, 0);
> op1 = XEXP (rhs, 1);
> ! /* Allow reg + const sets only. */
> ! if (REG_P (op0) && !HARD_REGISTER_P (op0) && CONSTANT_P (op1))
> ! return true;
> ! if (REG_P (op1) && !HARD_REGISTER_P (op1) && CONSTANT_P (op0))
> ! return true;
>
> ! return false;
>
> default:
> return false;
> --- 1337,1362 ----
> case MINUS:
> op0 = XEXP (rhs, 0);
> op1 = XEXP (rhs, 1);
> ! /* Allow reg + const and reg + reg. */
> ! if (!(REG_P (op0) && !HARD_REGISTER_P (op0))
> ! && !CONSTANT_P (op0))
> ! return false;
> ! if (!(REG_P (op1) && !HARD_REGISTER_P (op1))
> ! && !CONSTANT_P (op1))
> ! return false;
>
> ! return true;
> !
> ! case ASHIFT:
> ! op0 = XEXP (rhs, 0);
> ! op1 = XEXP (rhs, 1);
> ! /* Allow reg << const. */
> ! if (!(REG_P (op0) && !HARD_REGISTER_P (op0)))
> ! return false;
> ! if (!CONSTANT_P (op1))
> ! return false;
> !
> ! return true;
>
> default:
> return false;
>