Message ID | CAFULd4aGzF3xD_n_JtfNmMMGB86roQEOf4uAgRhbDiqnfLkTNg@mail.gmail.com |
---|---|
State | New |
Headers | show |
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.
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.
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))