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~