diff mbox

PATCH: PR middle-end/47383: ivopts miscompiles Pmode != ptr_mode

Message ID AANLkTikFFLWBv=kpjR_JeOzU9QN347FHUUV9OfY=7_Vq@mail.gmail.com
State New
Headers show

Commit Message

H.J. Lu Feb. 11, 2011, 4:47 a.m. UTC
On Thu, Feb 10, 2011 at 4:09 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Thu, Feb 10, 2011 at 8:31 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Thu, Feb 10, 2011 at 3:41 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> On Thu, Feb 10, 2011 at 2:18 AM, Richard Guenther
>>> <richard.guenther@gmail.com> wrote:
>>>
>>>>>>
>>>>>> By combined brain-power we dug out the last sentence of 3.3.7
>>>>>> of the ia32 basic arch manual which says the address is zero-extended
>>>>>> from 32bit after computing it.  So there is no problem?
>>>>>>
>>>>>
>>>>> In x32 mode, we use (%rax,%rbx,4), not (%eax,%ebx,4).  When we generate
>>>>> (%rax,%rbx,4) in x32 mode, we have to put sign-extended value in RBX.
>>>>
>>>> TARGET_MEM_REF does not support this kind of addressing mode.  That's
>>>> one of the results of choosing ptr_mode != Pmode.  TARGET_MEM_REF
>>>> only supports (%eax,%ebx,4), or lea (%eax,%ebx,4), %ecx; mov %ecx, %rax
>>>> and (%rax).
>>>>
>>>
>>> lea is also used for arithmetic. Is there a way to tell an RTL is
>>> TARGET_MEM_REF?
>>
>> ?
>>
>>>> TARGET_MEM_REF
>>>> only supports (%eax,%ebx,4), or lea (%eax,%ebx,4), %ecx; mov %ecx, %rax
>>>> and (%rax).
>>
>> as in TARGET_MEM_REF <*ax, *bx, 4> needs to be expanded
>> as
>>
>>  compute address in ptr_mode, for example with
>>    lea (%eax,%ebx,4), %ecx
>>  zero-extend the address
>>    mov %ecx, %rax
>>  do the memory access
>>    mov (%rax), ...
>>
>> which is a very inefficient way of using addr32 prefix (basically manually
>> emulating it).
>>
>> As Jakub says, don't use ptr_mode != Pmode.  Or disable IVOPTs
>> (it is useless for such port).  I bet you also will run into POINTER_PLUS_EXPR
>> issues and the fact it does not preserve signedness of the offset operand.
>>
>
> ptr_mode != Pmode won't work too well. I will see what I can do.
>

This is what I come up with.
diff mbox

Patch

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b090e7f..90b6104 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11614,6 +11614,13 @@  ix86_decompose_address (rtx addr, struct ix86_address *
out)
   int retval = 1;
   enum ix86_address_seg seg = SEG_DEFAULT;

+  /* Support 32bit address in x32 mode.  */
+  if (TARGET_X32
+      && GET_CODE (addr) == ZERO_EXTEND
+      && GET_MODE (addr) == Pmode
+      && GET_CODE (XEXP (addr, 0)) == PLUS)
+    addr = XEXP (addr, 0);
+
   if (REG_P (addr) || GET_CODE (addr) == SUBREG)
     base = addr;