This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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.

-- 
H.J.
---
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;
   else if (GET_CODE (addr) == PLUS)
@@ -12167,8 +12174,9 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIB
UTE_UNUSED,
 	/* Base is not a register.  */
 	return false;

-      if (GET_MODE (base) != Pmode)
-	/* Base is not in Pmode.  */
+      if (GET_MODE (base) != Pmode
+	  && !(TARGET_X32 && GET_MODE (base) == ptr_mode))
+	/* Base is not in Pmode nor ptr_mode.  */
 	return false;

       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
@@ -12196,8 +12204,9 @@ ix86_legitimate_address_p (enum machine_mode mode ATTRIB
UTE_UNUSED,
 	/* Index is not a register.  */
 	return false;

-      if (GET_MODE (index) != Pmode)
-	/* Index is not in Pmode.  */
+      if (GET_MODE (index) != Pmode
+	  && !(TARGET_X32 && GET_MODE (index) == ptr_mode))
+	/* Index is not in Pmode nor ptr_mode.  */
 	return false;

       if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))
@@ -15954,6 +15952,16 @@ ix86_fixup_binary_operands (enum rtx_code code, enum ma
chine_mode mode,
       else
 	src2 = force_reg (mode, src2);
     }
+  else
+    {
+      /* Support 32bit address in x32 mode.  */
+      if (TARGET_X32
+	  && code == PLUS
+	  && !MEM_P (dst)
+	  && !MEM_P (src1)
+	  && MEM_P (src2) )
+	src2 = force_reg (mode, src2);
+    }

   /* If the destination is memory, and we do not have matching source
      operands, do things in registers.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]