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.