Skip to content
Snippets Groups Projects
  • Jakub Jelinek's avatar
    2b4efc5d
    expand: Fix handling of asm goto outputs vs. PHI argument adjustments [PR113921] · 2b4efc5d
    Jakub Jelinek authored
    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  <jakub@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.
    2b4efc5d
    History
    expand: Fix handling of asm goto outputs vs. PHI argument adjustments [PR113921]
    Jakub Jelinek authored
    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  <jakub@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.