https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64226
Bug ID: 64226
Summary: Secondary reload incorrect TOC address
Product: gcc
Version: 5.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: dje at gcc dot gnu.org
Many of the GCC testsuite VMX tests fail on AIX because secondary reload is
generating an incorrect TOC reference. A MEM is being stripped from a
TOC reference causing GCC to use a pattern for a raw address,
generating a bogus reference.
226r.ira:
(insn 347 346 348 8 (set (reg/f:SI 489)
(mem/u/c:SI (unspec:SI [
(symbol_ref/u:SI ("*LC..32") [flags 0x2])
(reg:SI 2 2)
] UNSPEC_TOCREL) [0 S4 A8])) ld.c:83 411 {*movsi_internal1}
(expr_list:REG_EQUIV (symbol_ref/u:SI ("*LC..31") [flags 0x2])
(nil)))
(insn 348 347 349 8 (set (reg:V8HI 488)
(mem/u/c:V8HI (reg/f:SI 489) [0 S16 A128])) ld.c:83 972
{*altivec_movv8
hi}
(expr_list:REG_DEAD (reg/f:SI 489)
(expr_list:REG_EQUIV (const_vector:V8HI [
(const_int 0 [0])
(const_int 1 [0x1])
(const_int 2 [0x2])
(const_int 3 [0x3])
(const_int 4 [0x4])
(const_int 5 [0x5])
(const_int 6 [0x6])
(const_int 7 [0x7])
])
(nil))))
(insn 349 348 350 8 (parallel [
(set (reg:CC 74 6)
(unspec:CC [
(eq:CC (reg:V8HI 456)
(reg:V8HI 488))
] UNSPEC_PREDICATE))
(set (reg:V8HI 490)
(eq:V8HI (reg:V8HI 456)
(reg:V8HI 488)))
]) ld.c:83 1206 {*altivec_vcmpequh_p}
(expr_list:REG_DEAD (reg:V8HI 456)
(expr_list:REG_UNUSED (reg:V8HI 490)
(nil))))
227r.reload:
Reloads for insn # 349
Reload 0: reload_in (SI) = (plus:SI (reg/f:SI 1 1)
(const_int 96 [0x60]))
BASE_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 1), can't combine
reload_in_reg: (plus:SI (reg/f:SI 1 1)
(const_int 96 [0x60]))
reload_reg_rtx: (reg:SI 7 7)
Reload 1: reload_in (SI) = (symbol_ref/u:SI ("*LC..31") [flags 0x2])
BASE_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum = 2)
reload_in_reg: (symbol_ref/u:SI ("*LC..31") [flags 0x2])
reload_reg_rtx: (reg/f:SI 9 9 [489])
Reload 2: reload_in (V8HI) = (mem/c:V8HI (plus:SI (reg/f:SI 1 1)
(const_int 96 [0x60]))
[
0 %sfp+96 S16 A128])
ALTIVEC_REGS, RELOAD_FOR_INPUT (opnum = 1), can't combine
reload_in_reg: (reg:V8HI 456)
reload_reg_rtx: (reg:V8HI 78 1)Reload 3: BASE_REGS,
RELOAD_FOR_INPUT_ADDRESS (opnum = 2), can't combine, second
ary_reload_p
reload_reg_rtx: (reg:SI 7 7)
Reload 4: reload_in (V8HI) = (mem/u/c:V8HI (symbol_ref/u:SI ("*LC..31") [flags
0
x2]) [0 S16 A128])
ALTIVEC_REGS, RELOAD_FOR_INPUT (opnum = 2), can't combine
reload_in_reg: (reg:V8HI 488)
reload_reg_rtx: (reg:V8HI 90 13)
secondary_in_reload = 3
secondary_in_icode = reload_v8hi_si_load
(insn 498 497 499 8 (set (reg:SI 7 7)
(unspec:SI [
(symbol_ref/u:SI ("*LC..31") [flags 0x2])
(reg:SI 2 2)
] UNSPEC_TOCREL)) ld.c:83 532 {*tocrefsi}
(nil))
(insn 499 498 349 8 (set (reg:V8HI 90 13)
(mem/u/c:V8HI (reg:SI 7 7) [0 S16 A128])) ld.c:83 972
{*altivec_movv8hi
}
(nil))
(insn 349 499 350 8 (parallel [
(set (reg:CC 74 6)
(unspec:CC [
(eq:CC (reg:V8HI 78 1)
(reg:V8HI 90 13))
] UNSPEC_PREDICATE))
(set (reg:V8HI 77 0 [490])
(eq:V8HI (reg:V8HI 78 1)
(reg:V8HI 90 13)))
]) ld.c:83 1206 {*altivec_vcmpequh_p}
(nil))
Pseudo 489 was loaded with (mem:SI (unspec:SI [LC..32]
TOCREL)) but r7 is loaded directly with (unspec:SI [LC..31] TOCREL).
I assume that find_replacement is finding symbol_ref LC..31 and using
that. There is no valid way to reference LC..31 directly on AIX.
It's clearer with -fno-section-anchors. LC..31 is in read-only data:
.csect _ld.rw_[RO],4
.align 4
...
LC..31:
.short 0
.short 1
.short 2
.short 3
.short 4
.short 5
.short 6
.short 7
LC..32 would have been a TOC reference to LC..31
.toc
LC..32:
.tc LC..31[TC],LC..31
but that is deleted and replaced with a direct reference to the RO
data. The final instruction stream is
addi 7,1,96
lvx 1,0,7
la 7,LC..31(2) <-----
lvx 13,0,7
vcmpequh. 0,1,13
lwz 4,LC..34(2)
mfcr 3
rlwinm 3,3,25,1
bl .check
which tries to load the RO data directly and use LC..31 as a TOC displacement.