https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113921

--- Comment #12 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-13 branch has been updated by Jakub Jelinek
<ja...@gcc.gnu.org>:

https://gcc.gnu.org/g:4040d472825f203660371331c9e86cd75e30f8d2

commit r13-8328-g4040d472825f203660371331c9e86cd75e30f8d2
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Thu Feb 15 15:53:01 2024 +0100

    expand: Fix handling of asm goto outputs vs. PHI argument adjustments
[PR113921]

    The Linux kernel and the following testcase distilled from it is
    miscompiled, because tree-outof-ssa.cc (eliminate_phi) emits some
    fixups on some of the edges (but doesn't commit edge insertions).
    Later expand_asm_stmt emits further instructions on the same edge.
    Now the problem is that expand_asm_stmt uses insert_insn_on_edge
    to add its own fixups, but that function appends to the existing
    sequence on the edge if any.  And the bug triggers when the
    fixup sequence emitted by eliminate_phi uses a pseudo which the
    fixup sequence emitted by expand_asm_stmt later on sets.
    So, we end up with
      (set (reg A) (asm_operands ...))
    and on one of the edges queued sequence
      (set (reg C) (reg B)) // added by eliminate_phi
      (set (reg B) (reg A)) // added by expand_asm_stmt
    That is wrong, what we emit by expand_asm_stmt needs to be as close
    to the asm_operands as possible (they aren't known until expand_asm_stmt
    is called, the PHI fixup code assumes it is reg B which holds the right
    value) and the PHI adjustments need to be done after it.

    So, the following patch introduces a prepend_insn_to_edge function and
    uses it from expand_asm_stmt, so that we queue
      (set (reg B) (reg A)) // added by expand_asm_stmt
      (set (reg C) (reg B)) // added by eliminate_phi
    instead and so the value from the asm_operands output propagates correctly
    to the PHI result.

    2024-02-15  Jakub Jelinek  <ja...@redhat.com>

            PR middle-end/113921
            * cfgrtl.h (prepend_insn_to_edge): New declaration.
            * cfgrtl.cc (insert_insn_on_edge): Clarify behavior in function
            comment.
            (prepend_insn_to_edge): New function.
            * cfgexpand.cc (expand_asm_stmt): Use prepend_insn_to_edge instead
of
            insert_insn_on_edge.

            * gcc.target/i386/pr113921.c: New test.

    (cherry picked from commit 2b4efc5db2aedb59196987300e14951d08cd7106)

Reply via email to