[PATCH] Handle ASHIFTRT with constant shift count >= BITS_PER_WORD in subreg lowering (PR rtl-optimization/50339)
Richard Henderson
rth@redhat.com
Thu Feb 21 18:40:00 GMT 2013
On 02/21/2013 08:42 AM, Jakub Jelinek wrote:
> @@ -1243,12 +1258,20 @@ resolve_shift_zext (rtx insn)
> dest_reg = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
> GET_MODE (SET_DEST (set)),
> offset1);
> - dest_zero = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
> - GET_MODE (SET_DEST (set)),
> - offset2);
> + dest_upper = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
> + GET_MODE (SET_DEST (set)),
> + offset2);
> src_reg = simplify_gen_subreg_concatn (word_mode, op_operand,
> GET_MODE (op_operand),
> src_offset);
> + if (GET_CODE (op) == ASHIFTRT
> + && INTVAL (XEXP (op, 1)) != 2 * BITS_PER_WORD - 1)
> + {
> + rtx tem = expand_shift (RSHIFT_EXPR, word_mode, copy_rtx (src_reg),
> + BITS_PER_WORD - 1, dest_upper, 0);
> + if (dest_upper != tem)
> + emit_move_insn (dest_upper, tem);
> + }
> if (GET_CODE (op) != ZERO_EXTEND)
> {
> int shift_count = INTVAL (XEXP (op, 1));
> @@ -1257,12 +1280,15 @@ resolve_shift_zext (rtx insn)
> LSHIFT_EXPR : RSHIFT_EXPR,
> word_mode, src_reg,
> shift_count - BITS_PER_WORD,
> - dest_reg, 1);
> + dest_reg, GET_CODE (op) != ASHIFTRT);
> }
>
> if (dest_reg != src_reg)
> emit_move_insn (dest_reg, src_reg);
> - emit_move_insn (dest_zero, CONST0_RTX (word_mode));
> + if (GET_CODE (op) != ASHIFTRT)
> + emit_move_insn (dest_upper, CONST0_RTX (word_mode));
> + else if (INTVAL (XEXP (op, 1)) == 2 * BITS_PER_WORD - 1)
> + emit_move_insn (dest_upper, copy_rtx (src_reg));
> insns = get_insns ();
Am I missing something? This looks like it would clobber the input too
early in the case of
(set (reg:DI x) (ashiftrt (reg:DI x) (const_int 60)))
where src_reg and dest_upper could resolve to the same concatn, and thus
the same SImode registers underneath?
Don't you need to delay that upper copy til the final block?
r~
More information about the Gcc-patches
mailing list