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

Reply via email to