This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PR/35281 1/2, fix convert_move


convert_move tries to do a two step conversion when from_mode is smaller than word_mode, and to_mode is larger. However, using gen_lowpart for the intermediate result gives hard-to-optimize RTL like:

    (set (subreg:SI (reg:DI x) 0) (zero_extend:SI (reg:HI y)))
    (set (reg:DI x) (zero_extend:DI (subreg:SI (reg:DI x 0))))

Using a new pseudo, and together with 2/2, GCC is able to optimize a 64x16->64 multiplication successfully.

Bootstrapped/regtested i686-pc-linux-gnu, ok for mainline?

Paolo

2008-03-10 Paolo Bonzini <bonzini@gnu.org>

	* expr.c (convert_move): Use a new pseudo for the intermediate
	from_mode->word_mode result.

Index: expr.c
===================================================================
--- expr.c      (revision 133071)
+++ expr.c      (working copy)
@@ -552,15 +552,15 @@ convert_move (rtx to, rtx from, int unsi
               && ((code = can_extend_p (to_mode, word_mode, unsignedp))
                   != CODE_FOR_nothing))
        {
+         rtx word_to = gen_reg_rtx (word_mode);
          if (REG_P (to))
            {
              if (reg_overlap_mentioned_p (to, from))
                from = force_reg (from_mode, from);
              emit_insn (gen_rtx_CLOBBER (VOIDmode, to));
            }
-         convert_move (gen_lowpart (word_mode, to), from, unsignedp);
-         emit_unop_insn (code, to,
-                         gen_lowpart (word_mode, to), equiv_code);
+         convert_move (word_to, from, unsignedp);
+         emit_unop_insn (code, to, word_to, equiv_code);
          return;
        }



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]