https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61930

            Bug ID: 61930
           Summary: [SH] SImode addressing modes not used when storing
                    SFmode values via SImode regs
           Product: gcc
           Version: 4.10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: olegendo at gcc dot gnu.org
            Target: sh*-*-*

The following

void foo (float a[])
{
  a[1] = 123;
  a[4] = 123;
  a[2] = 123;
  a[3] = 123;
}

compiled with -O2 -m4-single results in:

        mov.l   .L3,r1  ! 8     movsf_ie/8      [length = 2]
        mov     r4,r2   ! 28    movsi_ie/2      [length = 2]
        add     #4,r2   ! 7     *addsi3_compact [length = 2]
        mov.l   r1,@r2  ! 9     movsf_ie/10     [length = 2]
        add     #12,r2  ! 11    *addsi3_compact [length = 2]
        mov.l   r1,@r2  ! 13    movsf_ie/10     [length = 2]
        add     #-8,r2  ! 15    *addsi3_compact [length = 2]
        mov.l   r1,@r2  ! 17    movsf_ie/10     [length = 2]
        add     #12,r4  ! 19    *addsi3_compact [length = 2]
        rts             ! 36    *return_i       [length = 2]
        mov.l   r1,@r4  ! 21    movsf_ie/10     [length = 2]
.L4:
        .align 2
.L3:
        .long   1123418112

In this case the displacement addressing modes could be used.  For loads/stores
to/from FP regs there are no displacement addressing modes available (on
non-SH2A).  Since the stores are SFmode stores it thinks that displacement
addressing mode is not legitimate.
The problem is that it's only known after register allocation that the SFmode
value will be stored via an SImode reg.

Storing a different SFmode value (which can be loaded efficiently into an
SFmode reg):

void foo (float a[])
{
  a[1] = 1;
  a[4] = 1;
  a[2] = 1;
  a[3] = 1;
}

results in:
        mov     r4,r1   ! 28    movsi_ie/2      [length = 2]
        add     #4,r1   ! 7     *addsi3_compact [length = 2]
        fldi1   fr1     ! 8     movsf_ie/4      [length = 2]
        fmov.s  fr1,@r1 ! 9     movsf_ie/7      [length = 2]
        add     #12,r1  ! 11    *addsi3_compact [length = 2]
        fmov.s  fr1,@r1 ! 13    movsf_ie/7      [length = 2]
        add     #-8,r1  ! 15    *addsi3_compact [length = 2]
        fmov.s  fr1,@r1 ! 17    movsf_ie/7      [length = 2]
        add     #12,r4  ! 19    *addsi3_compact [length = 2]
        rts             ! 36    *return_i       [length = 2]
        fmov.s  fr1,@r4 ! 21    movsf_ie/7      [length = 2]

A possible solution to this problem could be splitting out constant loads
before RA/reload as much as possible.  Doing so would load the SFmode constant
123.0 into an SFmode reg.  However, using SImode regs for the above sequence is
better in this case.  Maybe on SH it's better to convert SFmode loads/stores to
true SImode loads/stores before register allocation.  The question is how and
where to decide that such a transformation would be beneficial.

Possibly related: PR 54429

Reply via email to