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