Patchwork PATCH [6/n] X32: Supprot 32bit address

login
register
mail settings
Submitter Uros Bizjak
Date July 19, 2011, 7:08 p.m.
Message ID <CAFULd4aGzF3xD_n_JtfNmMMGB86roQEOf4uAgRhbDiqnfLkTNg@mail.gmail.com>
Download mbox | patch
Permalink /patch/105508/
State New
Headers show

Comments

Uros Bizjak - July 19, 2011, 7:08 p.m.
On Tue, Jul 19, 2011 at 6:30 PM, Jakub Jelinek <jakub@redhat.com> wrote:

>> Sometimes, the compiler is really creative in inventing instructions:
>>
>> (insn 47 46 49 7 (set (reg:SI 68 [ D.1686 ])
>>         (subreg:SI (plus:SF (reg:SF 159 [ D.1685 ])
>>                 (reg:SF 159 [ D.1685 ])) 0)) omp_atomic1.f90:17 247 {*lea_2}
>>      (expr_list:REG_DEAD (reg:SF 159 [ D.1685 ])
>>         (nil)))
>>
>> Really funny.
>
> That's the job of combiner to try all kinds of stuff and it is the
> responsibility of the backend to reject those.  I think it would be better
> to get back to testing Pmode in the legitimate address hook, perhaps
> allowing ptr_mode too in addition to Pmode (which for -m32/-m64 won't mean
> any change, just for -mx32).

I agree that we still need to check naked registers. However, for
64bit targets it is OK to pass both, SImode and DImode registers. We
are sure that SImode values in DImode regs have top 32bits equal to 0
in address calculations. This is not true for QImode regs (assignment
to lowpart only). We also have to prevent non-integer registers.

Attached is my final version of the patch.

Uros.
H.J. Lu - July 20, 2011, 12:54 p.m.
On Tue, Jul 19, 2011 at 12:08 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Tue, Jul 19, 2011 at 6:30 PM, Jakub Jelinek <jakub@redhat.com> wrote:
>
>>> Sometimes, the compiler is really creative in inventing instructions:
>>>
>>> (insn 47 46 49 7 (set (reg:SI 68 [ D.1686 ])
>>>         (subreg:SI (plus:SF (reg:SF 159 [ D.1685 ])
>>>                 (reg:SF 159 [ D.1685 ])) 0)) omp_atomic1.f90:17 247 {*lea_2}
>>>      (expr_list:REG_DEAD (reg:SF 159 [ D.1685 ])
>>>         (nil)))
>>>
>>> Really funny.
>>
>> That's the job of combiner to try all kinds of stuff and it is the
>> responsibility of the backend to reject those.  I think it would be better
>> to get back to testing Pmode in the legitimate address hook, perhaps
>> allowing ptr_mode too in addition to Pmode (which for -m32/-m64 won't mean
>> any change, just for -mx32).
>
> I agree that we still need to check naked registers. However, for
> 64bit targets it is OK to pass both, SImode and DImode registers. We
> are sure that SImode values in DImode regs have top 32bits equal to 0
> in address calculations. This is not true for QImode regs (assignment
> to lowpart only). We also have to prevent non-integer registers.
>
> Attached is my final version of the patch.
>

It works fine.  Can you check it in?

Thanks.
Uros Bizjak - July 20, 2011, 1 p.m.
On Wed, Jul 20, 2011 at 2:54 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>>> Sometimes, the compiler is really creative in inventing instructions:
>>>>
>>>> (insn 47 46 49 7 (set (reg:SI 68 [ D.1686 ])
>>>>         (subreg:SI (plus:SF (reg:SF 159 [ D.1685 ])
>>>>                 (reg:SF 159 [ D.1685 ])) 0)) omp_atomic1.f90:17 247 {*lea_2}
>>>>      (expr_list:REG_DEAD (reg:SF 159 [ D.1685 ])
>>>>         (nil)))
>>>>
>>>> Really funny.
>>>
>>> That's the job of combiner to try all kinds of stuff and it is the
>>> responsibility of the backend to reject those.  I think it would be better
>>> to get back to testing Pmode in the legitimate address hook, perhaps
>>> allowing ptr_mode too in addition to Pmode (which for -m32/-m64 won't mean
>>> any change, just for -mx32).
>>
>> I agree that we still need to check naked registers. However, for
>> 64bit targets it is OK to pass both, SImode and DImode registers. We
>> are sure that SImode values in DImode regs have top 32bits equal to 0
>> in address calculations. This is not true for QImode regs (assignment
>> to lowpart only). We also have to prevent non-integer registers.
>>
>> Attached is my final version of the patch.
>>
>
> It works fine.  Can you check it in?

Tested on x86_64-pc-linux-gnu {,-m32} and committed to mainline SVN
with following ChangeLog:

2011-07-20  Uros Bizjak  <ubizjak@gmail.com>

	PR target/49780
	* config/i386/predicates.md (no_seg_addres_operand): No more special.
	* config/i386/i386.c (ix86_decompose_address): Allow only subregs
	of DImode hard registers in base.
	(ix86_legitimate_address_p): Allow SImode and DImode base and index
	registers.

Uros.

Patch

Index: predicates.md
===================================================================
--- predicates.md	(revision 176462)
+++ predicates.md	(working copy)
@@ -796,7 +796,7 @@ 
 
 ;; Return true if op if a valid address, and does not contain
 ;; a segment override.
-(define_special_predicate "no_seg_address_operand"
+(define_predicate "no_seg_address_operand"
   (match_operand 0 "address_operand")
 {
   struct ix86_address parts;
Index: i386.c
===================================================================
--- i386.c	(revision 176462)
+++ i386.c	(working copy)
@@ -11085,8 +11085,16 @@  ix86_decompose_address (rtx addr, struct
   int retval = 1;
   enum ix86_address_seg seg = SEG_DEFAULT;
 
-  if (REG_P (addr) || GET_CODE (addr) == SUBREG)
+  if (REG_P (addr))
     base = addr;
+  else if (GET_CODE (addr) == SUBREG)
+    {
+      /* Allow only subregs of DImode hard regs.  */
+      if (register_no_elim_operand (SUBREG_REG (addr), DImode))
+	base = addr;
+      else
+	return 0;
+    }
   else if (GET_CODE (addr) == PLUS)
     {
       rtx addends[4], op;
@@ -11643,8 +11651,7 @@  ix86_legitimate_address_p (enum machine_
 	/* Base is not a register.  */
 	return false;
 
-      if (GET_MODE (base) != Pmode)
-	/* Base is not in Pmode.  */
+      if (GET_MODE (base) != SImode && GET_MODE (base) != DImode)
 	return false;
 
       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (reg))
@@ -11672,8 +11679,7 @@  ix86_legitimate_address_p (enum machine_
 	/* Index is not a register.  */
 	return false;
 
-      if (GET_MODE (index) != Pmode)
-	/* Index is not in Pmode.  */
+      if (GET_MODE (index) != SImode && GET_MODE (index) != DImode)
 	return false;
 
       if ((strict && ! REG_OK_FOR_INDEX_STRICT_P (reg))