> Am 13.08.2026 um 19:52 schrieb Aldy Hernandez <[email protected]>:
>
> The backward threader refuses to look at any SSA name occurring in an
> abnormal PHI, but DOM's threader does, at least for PHIs where the
> path taken does not include an abnormal edge. For example:
>
> x_5(ab) = PHI <45(5), y_8(ab)>
> ...
> if (x_5 == 45)
>
> If we're threading a path coming in from BB5, it's perfectly valid to
> thread this path, even if x_5 itself is AB.
>
> With gimple_range_ssa_p no longer rejecting these names, the path
> solver handles them as is: a path never includes abnormal edges, so an
> abnormal PHI still resolves to its argument on the path's incoming
> edge. Drop the last discovery restriction in the backward threader.
> Only normal predecessor edges are ever walked, so no abnormal edge is
> duplicated.
>
> This also enables threading computed gotos whose destination occurs
> in an abnormal PHI, which happens when the goto block is itself one
> of the goto's targets.
>
> Tested on ppc64le Linux.
>
> OK?
Ok as well
Richard
> gcc/ChangeLog:
>
> PR tree-optimization/126103
> * tree-ssa-threadbackward.cc (back_threader::find_paths_to_names):
> Follow abnormal PHIs.
>
> gcc/testsuite/ChangeLog:
>
> PR tree-optimization/126103
> * gcc.dg/tree-ssa/ssa-thread-abnormal-phi-1.c: New test.
> * gcc.dg/tree-ssa/ssa-thread-abnormal-phi-2.c: New test.
> * gcc.dg/tree-ssa/backthread-computed-goto-2.c: New test.
> ---
> .../tree-ssa/backthread-computed-goto-2.c | 22 +++++++++
> .../tree-ssa/ssa-thread-abnormal-phi-1.c | 46 +++++++++++++++++++
> .../tree-ssa/ssa-thread-abnormal-phi-2.c | 45 ++++++++++++++++++
> gcc/tree-ssa-threadbackward.cc | 6 +--
> 4 files changed, 114 insertions(+), 5 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/backthread-computed-goto-2.c
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-1.c
> create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-2.c
>
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/backthread-computed-goto-2.c
> b/gcc/testsuite/gcc.dg/tree-ssa/backthread-computed-goto-2.c
> new file mode 100644
> index 00000000000..86d0f688210
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/backthread-computed-goto-2.c
> @@ -0,0 +1,22 @@
> +/* PR tree-optimization/126103 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdisable-tree-ethread -fdump-tree-threadfull1-details"
> } */
> +
> +int g;
> +
> +void
> +h (int a)
> +{
> + void *q;
> + if (a)
> + q = &&L0;
> + else
> + q = &&L2;
> +L2:
> + g++;
> + goto *q;
> +L0:
> + return;
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Registering jump thread" 2
> "threadfull1" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-1.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-1.c
> new file mode 100644
> index 00000000000..7fe315fdea8
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-1.c
> @@ -0,0 +1,46 @@
> +/* PR tree-optimization/126103 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdisable-tree-ethread -fdump-tree-threadfull1-details"
> } */
> +
> +/* The conditional at "join" tests the result of an abnormal PHI:
> + t = PHI <k(ab), 0, 0>. Both normal predecessors feed constant 0,
> + so the backward threader must thread them past the conditional;
> + the abnormal predecessor keeps the original block. The two normal
> + predecessors of the computed goto also know its destination, so
> + they are threaded as well. */
> +
> +void foo (void);
> +void bar (void);
> +
> +void
> +f (int k)
> +{
> + void *p = (k & 1) ? &&yes : &&join;
> + int t;
> +
> + if (k > 0)
> + {
> + t = k;
> + goto *p;
> + }
> +
> + if (k < -5)
> + {
> + foo ();
> + t = 0;
> + }
> + else
> + {
> + bar ();
> + t = 0;
> + }
> +
> +join:
> + if (t != 0)
> + {
> +yes:
> + foo ();
> + }
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Registering jump thread" 4
> "threadfull1" } } */
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-2.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-2.c
> new file mode 100644
> index 00000000000..8f74084ee2c
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-abnormal-phi-2.c
> @@ -0,0 +1,45 @@
> +/* PR tree-optimization/126103 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdisable-tree-ethread -fdump-tree-threadfull1-details"
> } */
> +
> +/* Like ssa-thread-abnormal-phi-1.c, but the conditional tests a value
> + derived from the abnormal PHI. */
> +
> +void foo (void);
> +void bar (void);
> +int g;
> +
> +void
> +f (int k)
> +{
> + void *p = (k & 1) ? &&yes : &&join;
> + int t;
> +
> + if (k > 0)
> + {
> + t = k;
> + goto *p;
> + }
> +
> + if (k < -5)
> + {
> + foo ();
> + t = 1;
> + }
> + else
> + {
> + bar ();
> + t = 0;
> + }
> +
> +join:
> + if (g)
> + bar ();
> + if ((t & 2) == 0)
> + {
> +yes:
> + foo ();
> + }
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Registering jump thread" 6
> "threadfull1" } } */
> diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc
> index 77726ba66cd..ca1af87bb40 100644
> --- a/gcc/tree-ssa-threadbackward.cc
> +++ b/gcc/tree-ssa-threadbackward.cc
> @@ -450,11 +450,7 @@ back_threader::find_paths_to_names (basic_block bb,
> bitmap interesting,
> }
> /* Local PHIs participate in renaming below. */
> if (gphi *phi = dyn_cast<gphi *> (def_stmt))
> - {
> - tree res = gimple_phi_result (phi);
> - if (!SSA_NAME_OCCURS_IN_ABNORMAL_PHI (res))
> - interesting_phis.safe_push (phi);
> - }
> + interesting_phis.safe_push (phi);
> /* For other local defs process their uses, amending
> imports on the way. */
> else
> --
> 2.47.3
>