On Thu, Jul 21, 2011 at 3:00 AM, Uros Bizjak <ubiz...@gmail.com> wrote: > On Tue, Jul 19, 2011 at 6:47 AM, H.J. Lu <hongjiu...@intel.com> wrote: > > So, since copy_to_reg & co. expects x in Pmode or VOIDmode constant > (due to force_reg that won't do mode conversion), we have to implement > them with a mode conversion... > >> This patch adds the missing Pmode check and conversion. OK for trunk? > >> 2011-07-18 H.J. Lu <hongjiu...@intel.com> >> >> * config/i386/i386.c (ix86_legitimize_address): Convert to >> Pmode if needed. >> (ix86_expand_move): Likewise. >> (ix86_expand_call): Likewise. >> (ix86_expand_special_args_builtin): Likewise. >> (ix86_expand_builtin): Likewise. >>
> >> @@ -21475,7 +21554,10 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx >> callarg1, >> ? !sibcall_insn_operand (XEXP (fnaddr, 0), Pmode) >> : !call_insn_operand (XEXP (fnaddr, 0), Pmode)) >> { >> - fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0)); >> + fnaddr = XEXP (fnaddr, 0); >> + if (GET_MODE (fnaddr) != Pmode) >> + fnaddr = convert_to_mode (Pmode, fnaddr, 1); >> + fnaddr = copy_to_mode_reg (Pmode, fnaddr); >> fnaddr = gen_rtx_MEM (QImode, fnaddr); >> } >> > > Use force_reg (Pmode, ...) instead of copy_to_mode_reg (Pmode, ...). > We know we have Pmode here. No need to copy a register if > convert_to_mode returned a register. > > Better yet: > > fnaddr = gen_rtx_MEM (QImode, force_reg (Pmode, fnaddr)); > This caused the regression in 32bit: [hjl@gnu-6 gcc]$ cat /tmp/x.i f(x) { (*(void (*)())&x)(); } [hjl@gnu-6 gcc]$ ./xgcc -B./ -S /tmp/x.i -m32 -O /tmp/x.i: In function \u2018f\u2019: /tmp/x.i:4:1: error: unrecognizable insn: (call_insn 5 4 11 3 (call (mem:QI (reg/f:SI 53 virtual-incoming-args) [0 *x.0_1 S1 A8]) (const_int 0 [0])) /tmp/x.i:3 -1 (nil) (nil)) /tmp/x.i:4:1: internal compiler error: in extract_insn, at recog.c:2115 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. [hjl@gnu-6 gcc]$ I checked in the enclosed patch as an obvious fix. -- H.J. --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6456000..5ac6697 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2011-07-21 H.J. Lu <hongjiu...@intel.com> + * config/i386/i386.c (ix86_expand_call): Call copy_to_mode_reg + instead of force_reg. + +2011-07-21 H.J. Lu <hongjiu...@intel.com> + * config/i386/i386.c (ix86_expand_move): Convert to Pmode if needed and use force_reg after convert. (ix86_expand_call): Likewise. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 6e030d9..ddf674a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -21545,7 +21545,7 @@ ix86_expand_call (rtx retval, rtx fnaddr, rtx callarg1, fnaddr = XEXP (fnaddr, 0); if (GET_MODE (fnaddr) != Pmode) fnaddr = convert_to_mode (Pmode, fnaddr, 1); - fnaddr = gen_rtx_MEM (QImode, force_reg (Pmode, fnaddr)); + fnaddr = gen_rtx_MEM (QImode, copy_to_mode_reg (Pmode, fnaddr)); } call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);