On Mon, Sep 22, 2025 at 2:55 AM Richard Biener <[email protected]> wrote: > > When PRE asks VN to simplify a NARY but not insert, that bypasses > the abnormal guard in maybe_push_res_to_seq and we blindly accept > new uses of abnormals. The following fixes this. > > Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed. > > PR tree-optimization/122016 > * tree-ssa-sccvn.cc (vn_nary_simplify): Do not use the > simplified expression when it references abnormals. > > * gcc.dg/torture/pr122016.c: New testcase. > --- > gcc/testsuite/gcc.dg/torture/pr122016.c | 27 +++++++++++++++++++++++++ > gcc/tree-ssa-sccvn.cc | 6 ++++++ > 2 files changed, 33 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr122016.c > > diff --git a/gcc/testsuite/gcc.dg/torture/pr122016.c > b/gcc/testsuite/gcc.dg/torture/pr122016.c > new file mode 100644 > index 00000000000..027a63d4256 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr122016.c > @@ -0,0 +1,27 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-ftree-pre" } */ > + > +int merge_parse_args_argc; > +char merge_parse_args_argv_0; > +int strncmp(char *, char *, long); > +void _setjmp(); > +typedef enum { FALSE, TRUE } boool; > +void directory_exists(); > +void merge_parse_args() { > + int i; > + boool help_found = FALSE; > + while (i < merge_parse_args_argc && !help_found) { > + if (strncmp("", &merge_parse_args_argv_0, 2)) > + help_found = TRUE; > + else { > + for (;;) { > + _setjmp(); > + break; > + } > + i++; > + directory_exists(); > + } > + i++; > + } > + _setjmp(); > +} > diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc > index 8ec0a199705..246fa082561 100644 > --- a/gcc/tree-ssa-sccvn.cc > +++ b/gcc/tree-ssa-sccvn.cc > @@ -2622,6 +2622,12 @@ vn_nary_simplify (vn_nary_op_t nary) > nary->type, nary->length); > memcpy (op.ops, nary->op, sizeof (tree) * nary->length); > tree res = vn_nary_build_or_lookup_1 (&op, false, true); > + /* Do not update *NARY with a simplified result that contains abnormals. > + This matches what maybe_push_res_to_seq does when requesting insertion. > */ > + for (unsigned i = 0; i < op.num_ops; ++i) > + if (TREE_CODE (op.ops[i]) == SSA_NAME > + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op.ops[i])) > + return res;
You could just do: if (op.operands_occurs_in_abnormal_phi ()) return res; I added operands_occurs_in_abnormal_phi for phiopt when I started to use match_op for factoring out expression there. Thanks, Andrew > if (op.code.is_tree_code () > && op.num_ops <= nary->length > && (tree_code) op.code != CONSTRUCTOR) > -- > 2.43.0
