From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id BB660386EC0E; Tue, 20 Oct 2020 06:17:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BB660386EC0E From: "krebbel at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug rtl-optimization/97497] gcse wrong code generation with partial register clobbers Date: Tue, 20 Oct 2020 06:17:31 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: rtl-optimization X-Bugzilla-Version: 11.0 X-Bugzilla-Keywords: wrong-code X-Bugzilla-Severity: normal X-Bugzilla-Who: krebbel at gcc dot gnu.org X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 20 Oct 2020 06:17:31 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D97497 --- Comment #4 from Andreas Krebbel --- 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 va= lue is inserted after the first read of t because the expression is not conside= red to be available anymore at the second location. The availability of the ent= ire 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 pa= rts 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] ) ] 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]=20 ) ] 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]=20 ) (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] ) ] UNSPEC_GOT))) [0 S4 A8])) "t.c":10:5 1387 {*movsi_zarch} (nil))=