https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97497
--- Comment #4 from Andreas Krebbel <krebbel at gcc dot gnu.org> --- Reading from symbol t uses the GOT pointer in r12. The call then partially clobbers r12 but does not affect the lower 32 bits where the GOT pointer resides. So the GOT pointer stays in fact live across the call. The way this is currently handled in gcse the second access of t reads a different value than the first and this is wrong I think. This leads to a disagreement between the pre_delete_map and the insert locations. The later read of t is removed because it is an anticipated use but no copy of the value is inserted after the first read of t because the expression is not considered to be available anymore at the second location. The availability of the entire expression is broken by the set of r12 at the call insns. I didn't know how to solve this without being able to keep track of what parts of hard regs are clobbered. The idea behind the fixed_reg check is to trust the backend that it does not emit uninitialized uses of hard regs in the first place. t.c.250r.cprop1: (insn 6 3 7 2 (set (reg/f:SI 65) (mem/u/c:SI (plus:SI (reg:SI 12 %r12) (const:SI (unspec:SI [ (symbol_ref:SI ("t") [flags 0x6c0] <var_decl 0x3fffdff42d0 t>) ] UNSPEC_GOT))) [0 S4 A8])) "t.c":8:3 1387 {*movsi_zarch} (nil)) (insn 7 6 8 2 (set (reg:SI 3 %r3) (mem/f/c:SI (reg/f:SI 65) [1 t+0 S4 A32])) "t.c":8:3 1387 {*movsi_zarch} (expr_list:REG_DEAD (reg/f:SI 65) (nil))) (insn 8 7 9 2 (set (reg:SI 2 %r2) (const_int 1 [0x1])) "t.c":8:3 1387 {*movsi_zarch} (nil)) (call_insn 9 8 10 2 (parallel [ (call (mem:QI (const:SI (unspec:SI [ (symbol_ref:SI ("bar") [flags 0x41] <function_decl 0x3fff0555200 bar>) ] UNSPEC_PLT)) [0 bar S1 A8]) (const_int 0 [0])) (clobber (reg:SI 14 %r14)) ]) "t.c":8:3 2053 {*brasl} (expr_list:REG_DEAD (reg:SI 3 %r3) (expr_list:REG_DEAD (reg:SI 2 %r2) (expr_list:REG_CALL_DECL (symbol_ref:SI ("bar") [flags 0x41] <function_decl 0x3fff0555200 bar>) (nil)))) (expr_list (use (reg:SI 12 %r12)) (expr_list:SI (use (reg:SI 2 %r2)) (expr_list:SI (use (reg:SI 3 %r3)) (nil))))) ... (insn 13 12 14 4 (set (reg/f:SI 66) (mem/u/c:SI (plus:SI (reg:SI 12 %r12) (const:SI (unspec:SI [ (symbol_ref:SI ("t") [flags 0x6c0] <var_decl 0x3fffdff42d0 t>) ] UNSPEC_GOT))) [0 S4 A8])) "t.c":10:5 1387 {*movsi_zarch} (nil))