diff mbox series

[2/3] tree-cfg: do not duplicate returns_twice calls

Message ID 20220114182047.6270-3-amonakov@ispras.ru
State New
Headers show
Series [1/3] tree-ssa-sink: do not sink to in front of setjmp | expand

Commit Message

Alexander Monakov Jan. 14, 2022, 6:20 p.m. UTC
A returns_twice call may have associated abnormal edges that correspond
to the "second return" from the call. If the call is duplicated, the
copies of those edges also need to be abnormal, but e.g. tracer does not
enforce that. Just prohibit the (unlikely to be useful) duplication.

gcc/ChangeLog:

	* tree-cfg.c (gimple_can_duplicate_bb_p): Reject blocks with
	calls that may return twice.
---
 gcc/tree-cfg.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

Comments

Richard Biener Jan. 17, 2022, 8:08 a.m. UTC | #1
On Fri, Jan 14, 2022 at 7:21 PM Alexander Monakov <amonakov@ispras.ru> wrote:
>
> A returns_twice call may have associated abnormal edges that correspond
> to the "second return" from the call. If the call is duplicated, the
> copies of those edges also need to be abnormal, but e.g. tracer does not
> enforce that. Just prohibit the (unlikely to be useful) duplication.

The general CFG copying routines properly duplicate those edges, no?
Tracer uses duplicate_block so it should also get copies of all successor
edges of that block.  It also only traces along normal edges.  What it might
miss is abnormal incoming edges - is that what you are referring to?

That would be a thing we don't handle in duplicate_block on its own but
that callers are expected to do (though I don't see copy_bbs doing that
either).  I wonder if we can trigger this issue for some testcase?

The thing to check would be incoming abnormal edges in
can_duplicate_block_p, not (only) returns twice functions?

Richard.

> gcc/ChangeLog:
>
>         * tree-cfg.c (gimple_can_duplicate_bb_p): Reject blocks with
>         calls that may return twice.
> ---
>  gcc/tree-cfg.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index b7fe313b7..a99f1acb4 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -6304,12 +6304,15 @@ gimple_can_duplicate_bb_p (const_basic_block bb)
>      {
>        gimple *g = gsi_stmt (gsi);
>
> -      /* An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be
> +      /* Prohibit duplication of returns_twice calls, otherwise associated
> +        abnormal edges also need to be duplicated properly.
> +        An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be
>          duplicated as part of its group, or not at all.
>          The IFN_GOMP_SIMT_VOTE_ANY and IFN_GOMP_SIMT_XCHG_* are part of such a
>          group, so the same holds there.  */
>        if (is_gimple_call (g)
> -         && (gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC)
> +         && (gimple_call_flags (g) & ECF_RETURNS_TWICE
> +             || gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC)
>               || gimple_call_internal_p (g, IFN_GOMP_SIMT_EXIT)
>               || gimple_call_internal_p (g, IFN_GOMP_SIMT_VOTE_ANY)
>               || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_BFLY)
> --
> 2.33.1
>
diff mbox series

Patch

diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index b7fe313b7..a99f1acb4 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -6304,12 +6304,15 @@  gimple_can_duplicate_bb_p (const_basic_block bb)
     {
       gimple *g = gsi_stmt (gsi);
 
-      /* An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be
+      /* Prohibit duplication of returns_twice calls, otherwise associated
+	 abnormal edges also need to be duplicated properly.
+	 An IFN_GOMP_SIMT_ENTER_ALLOC/IFN_GOMP_SIMT_EXIT call must be
 	 duplicated as part of its group, or not at all.
 	 The IFN_GOMP_SIMT_VOTE_ANY and IFN_GOMP_SIMT_XCHG_* are part of such a
 	 group, so the same holds there.  */
       if (is_gimple_call (g)
-	  && (gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC)
+	  && (gimple_call_flags (g) & ECF_RETURNS_TWICE
+	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_ENTER_ALLOC)
 	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_EXIT)
 	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_VOTE_ANY)
 	      || gimple_call_internal_p (g, IFN_GOMP_SIMT_XCHG_BFLY)