http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53639

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-06-12 
07:40:26 UTC ---
Created attachment 27606
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27606
gcc48-pr53639.patch

The first problem is that combiner combines:
(insn 9 8 10 2 (parallel [
            (set (reg:SI 74 [ D.1765 ])
                (and:SI (reg/v:SI 60 [ vpn ])
                    (const_int 1023 [0x3ff])))
            (clobber (reg:CC 17 flags))
        ]) pr53639.c:19 378 {*andsi_1}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))

(insn 10 9 11 2 (set (reg:DI 75 [ D.1765 ])
        (zero_extend:DI (reg:SI 74 [ D.1765 ]))) pr53639.c:19 112
{*zero_extendsidi2_rex64}
     (expr_list:REG_DEAD (reg:SI 74 [ D.1765 ])
        (nil)))

into:
(insn 10 9 11 2 (parallel [
            (set (reg:DI 75 [ D.1765 ])
                (and:DI (subreg:DI (reg/v:SI 60 [ vpn ]) 0)
                    (const_int 1023 [0x3ff])))
            (clobber (reg:CC 17 flags))
        ]) pr53639.c:19 377 {*anddi_1}
     (expr_list:REG_UNUSED (reg:CC 17 flags)
        (nil)))
(expand_compound_operation in particular).  But the presence of the DImode
paradoxical subreg leads the RA to do the move in 64-bit rather than 32-bit.

The attached untested patch cures that by splitting *anddi_1 into *andsi_1_zext
so that the zero extension from SImode to DImode is done only on the result of
the and.

The second problem looks like RA decision, initially the SI 59 register (read
from *q) and DI 80 register (zero_extend:DI (reg:SI 59)) are given the eax/rax
register:
      Popping a2(r80,l0)  -- assign reg 0
...
      Popping a5(r59,l0)  -- assign reg 0
but there is also an esi = (reg:SI 59) assignment in another code branch (set
up of parameters for the tail call), so in the end IRA decides to put SI 59
into %esi register, but doesn't reconsider that the corresponding DI 80
register could be very well moved to that register as well:
Assigning 4 to a5r59
Disposition:
    5:r59  l0     4    6:r60  l0     1    4:r62  l0     2    0:r70  l0     0
    3:r72  l0     5    8:r73  l0     4    7:r75  l0     2    1:r78  l0     1
    2:r80  l0     0
Nothing afterwards fixes this up then.  The REE pass does nothing, as the
zero_extend uses different registers (%rax = zext (%esi)), so it doesn't
eliminate the extension, and supposedly because of that other passes don't
consider it worthwhile to rename the regs.

Reply via email to