The following patch extends the generation of exception handling
information to cover volatile asms too.  This was already mostly
implemented, and only very minor changes are required in order to make
it work.

The change in rewrite_stmt is necessary because it inserts debug
statements after the asm, and this causes the gimple verification pass
to fail.  This code is copied from maybe_register_def which does the
same thing.  Alternatively the verification routines could be made to
ignore debug statements at the end of a block.

gcc/
2020-03-05  Jan W. Jagersma  <jwjager...@gmail.com>

        PR inline-asm/93981
        * tree-cfg.c (make_edges_bb): Call make_eh_edges for case
        GIMPLE_ASM.
        * tree-eh.c (lower_eh_constructs_2): Add case for GIMPLE_ASM.
        * tree-into-ssa.c (rewrite_stmt): For bb-ending stmts, insert
        debug notes on the fallthrough edge.  Code and comments copied
        verbatim from maybe_register_def.
---
 gcc/tree-cfg.c      |  2 ++
 gcc/tree-eh.c       |  3 +++
 gcc/tree-into-ssa.c | 38 +++++++++++++++++++++++++++++++++++++-
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index f7b817d94e6..c21a7978493 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -913,6 +913,8 @@ make_edges_bb (basic_block bb, struct omp_region 
**pcur_region, int *pomp_index)
       break;
 
     case GIMPLE_ASM:
+      if (stmt_can_throw_internal (cfun, last))
+       make_eh_edges (last);
       make_gimple_asm_edges (bb);
       fallthru = true;
       break;
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 2a409dcaffe..8314db00922 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2077,6 +2077,9 @@ lower_eh_constructs_2 (struct leh_state *state, 
gimple_stmt_iterator *gsi)
            DECL_GIMPLE_REG_P (tmp) = 1;
          gsi_insert_after (gsi, s, GSI_SAME_STMT);
        }
+      /* FALLTHRU */
+
+    case GIMPLE_ASM:
       /* Look for things that can throw exceptions, and record them.  */
       if (state->cur_region && stmt_could_throw_p (cfun, stmt))
        {
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 6528acac31a..03bc1d52cfa 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1415,7 +1415,43 @@ rewrite_stmt (gimple_stmt_iterator *si)
        if (tracked_var)
          {
            gimple *note = gimple_build_debug_bind (tracked_var, name, stmt);
-           gsi_insert_after (si, note, GSI_SAME_STMT);
+           /* If stmt ends the bb, insert the debug stmt on the single
+              non-EH edge from the stmt.  */
+           if (gsi_one_before_end_p (*si) && stmt_ends_bb_p (stmt))
+             {
+               basic_block bb = gsi_bb (*si);
+               edge_iterator ei;
+               edge e, ef = NULL;
+               FOR_EACH_EDGE (e, ei, bb->succs)
+                 if (!(e->flags & EDGE_EH))
+                   {
+                     gcc_checking_assert (!ef);
+                     ef = e;
+                   }
+               /* If there are other predecessors to ef->dest, then
+                  there must be PHI nodes for the modified
+                  variable, and therefore there will be debug bind
+                  stmts after the PHI nodes.  The debug bind notes
+                  we'd insert would force the creation of a new
+                  block (diverging codegen) and be redundant with
+                  the post-PHI bind stmts, so don't add them.
+
+                  As for the exit edge, there wouldn't be redundant
+                  bind stmts, but there wouldn't be a PC to bind
+                  them to either, so avoid diverging the CFG.  */
+               if (ef && single_pred_p (ef->dest)
+                   && ef->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
+                 {
+                   /* If there were PHI nodes in the node, we'd
+                      have to make sure the value we're binding
+                      doesn't need rewriting.  But there shouldn't
+                      be PHI nodes in a single-predecessor block,
+                      so we just add the note.  */
+                   gsi_insert_on_edge_immediate (ef, note);
+                 }
+             }
+           else
+             gsi_insert_after (si, note, GSI_SAME_STMT);
          }
       }
 }
-- 
2.25.1

Reply via email to