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

Paolo Bonzini bonzini@gnu.org
Mon Mar 10 15:05:00 GMT 2008


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;
         }




More information about the Gcc-patches mailing list