This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR/35281 1/2, fix convert_move
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 10 Mar 2008 16:05:02 +0100
- Subject: [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;
}