https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116932
Bug ID: 116932 Summary: [SH] GBR not used for some atomic imask/tcb insns Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Target Milestone: --- While working on PR 55212, I've noticed that some of the atomic insns from the pr64661 tests do not use GBR addressing, while some do use it. __Z9test_36_1v: .LFB1: .cfi_startproc stc gbr,r1 <<< gbr stored to r1 stc sr,r0 mov r0,r2 or #0xF0,r0 ldc r0,sr mov.b @r1,r0 <<< should actually use mov.b @(0,gbr),r0 add #1,r0 mov.b r0,@r1 <<< ldc r2,sr rts exts.b r0,r0 __Z9test_37_1v: .LFB7: .cfi_startproc stc sr,r0 mov r0,r1 or #0xF0,r0 ldc r0,sr mov.b @(4,gbr),r0 <<< gbr is used add #1,r0 mov.b r0,@(4,gbr) <<< ldc r1,sr rts exts.b r0,r0 The GBR addressing is formed during combine/split1. So before register allocation, an insn will typicall look like this: insn 6 5 9 2 (parallel [ (set (reg:QI 166) (mem/v:QI (plus:SI (reg:SI 144 gbr) (const_int 4 [0x4])) [-1 S1 A8])) (set (mem/v:QI (plus:SI (reg:SI 144 gbr) (const_int 4 [0x4])) [-1 S1 A8]) (unspec:QI [ (and:QI (mem/v:QI (plus:SI (reg:SI 144 gbr) (const_int 4 [0x4])) [-1 S1 A8]) (const_int 1 [0x1])) ] UNSPEC_ATOMIC)) (clobber (reg:SI 0 r0)) (clobber (reg:QI 169)) ]) "../gcc/gcc/testsuite/gcc.target/sh/pr64661-0.h":50:173 discrim 1 538 {atomic_fetch_andqi_soft_imask} (expr_list:REG_DEAD (reg:SI 144 gbr) (expr_list:REG_UNUSED (reg:QI 169) (expr_list:REG_UNUSED (reg:SI 0 r0) (nil))))) After reload/LRA it might look like this (GBR substituted by other GP reg): (insn 6 22 9 2 (parallel [ (set (reg:QI 1 r1 [166]) (mem/v:QI (plus:SI (reg:SI 3 r3 [171]) (const_int 4 [0x4])) [-1 S1 A8])) (set (mem/v:QI (plus:SI (reg:SI 3 r3 [171]) (const_int 4 [0x4])) [-1 S1 A8]) (unspec:QI [ (and:QI (mem/v:QI (plus:SI (reg:SI 3 r3 [171]) (const_int 4 [0x4])) [-1 S1 A8]) (const_int 1 [0x1])) ] UNSPEC_ATOMIC)) (clobber (reg:SI 0 r0)) (clobber (reg:QI 2 r2 [169])) ]) "../gcc/gcc/testsuite/gcc.target/sh/pr64661-0.h":50:173 discrim 1 538 {atomic_fetch_andqi_soft_imask} (nil)) --------------- * the issue happens always when LRA is enabled. with old reload it happens only for addresses where the address offset/displacement would be 0. * 0-displacement GBR addresses will require something to convert an address '@gbr' into '@(0,gbr)' during asm printing. * some insns use atomic_mem_operand_0 predicate which doesn't allow GBR addressing, it should use atomic_mem_operand_1 instead in those places * Sra and Sdd constraints don't allow GBR as part of the address with LRA enabled. However, even after adding a constraint like (define_memory_constraint "Sgb" "A memory renference that uses GBR addressing." (match_test "gbr_address_mem (op, GET_MODE (op))")) LRA will always change the "pre-allocated" GBR hard-reg into something else, which is counterproductive in this case.