> Am 28.02.2025 um 17:02 schrieb Filip Kastl <fka...@suse.cz>:
> 
> Hi,
> 
> bootstrapped and regtested on x86_64 linux.  Ok to be pushed?

Ok

Richard 

> Thanks,
> Filip Kastl
> 
> 
> -- 8< --
> 
> 
> While writing the sccopy pass I didn't realize that 'replace_uses_by ()' can
> remove portions of the CFG.  This happens when replacing arguments of some
> statement results in the removal of an EH edge.  Because of this sccopy can
> then work with GIMPLE statements that aren't part of the IR anymore.  In
> PR117919 this triggered an assertion within the pass which assumes that
> statements the pass works with are reachable.
> 
> This patch tells the pass to notice when a statement isn't in the IR anymore
> and remove it from it's worklist.
> 
>    PR tree-optimization/117919
> 
> gcc/ChangeLog:
> 
>    * gimple-ssa-sccopy.cc (scc_copy_prop::propagate): Prune
>    statements that 'replace_uses_by ()' removed.
> 
> gcc/testsuite/ChangeLog:
> 
>    * g++.dg/pr117919.C: New test.
> 
> Signed-off-by: Filip Kastl <fka...@suse.cz>
> ---
> gcc/gimple-ssa-sccopy.cc        | 13 +++++++++
> gcc/testsuite/g++.dg/pr117919.C | 52 +++++++++++++++++++++++++++++++++
> 2 files changed, 65 insertions(+)
> create mode 100644 gcc/testsuite/g++.dg/pr117919.C
> 
> diff --git a/gcc/gimple-ssa-sccopy.cc b/gcc/gimple-ssa-sccopy.cc
> index 9f25fbaff36..7ffb5718ab6 100644
> --- a/gcc/gimple-ssa-sccopy.cc
> +++ b/gcc/gimple-ssa-sccopy.cc
> @@ -568,6 +568,19 @@ scc_copy_prop::propagate ()
>     {
>       vec<gimple *> scc = worklist.pop ();
> 
> +      /* When we do 'replace_scc_by_value' it may happen that some EH edges
> +     get removed.  That means parts of CFG get removed.  Those may
> +     contain copy statements.  For that reason we prune SCCs here.  */
> +      unsigned i;
> +      for (i = 0; i < scc.length (); i++)
> +    if (gimple_bb (scc[i]) == NULL)
> +      scc.unordered_remove (i);
> +      if (scc.is_empty ())
> +    {
> +      scc.release ();
> +      continue;
> +    }
> +
>       auto_vec<gimple *> inner;
>       hash_set<tree> outer_ops;
>       tree last_outer_op = NULL_TREE;
> diff --git a/gcc/testsuite/g++.dg/pr117919.C b/gcc/testsuite/g++.dg/pr117919.C
> new file mode 100644
> index 00000000000..fa2d9c9cd1e
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr117919.C
> @@ -0,0 +1,52 @@
> +/* PR tree-optimization/117919 */
> +/* { dg-do compile } */
> +/* { dg-options "-O1 -fno-tree-forwprop -fnon-call-exceptions 
> --param=early-inlining-insns=192 -std=c++20" } */
> +
> +char _M_p, _M_construct___beg;
> +struct _Alloc_hider {
> +  _Alloc_hider(char);
> +};
> +long _M_string_length;
> +void _M_destroy();
> +void _S_copy_chars(char *, char *, char *) noexcept;
> +char _M_local_data();
> +struct Trans_NS___cxx11_basic_string {
> +  _Alloc_hider _M_dataplus;
> +  bool _M_is_local() {
> +    if (_M_local_data())
> +      if (_M_string_length)
> +        return true;
> +    return false;
> +  }
> +  void _M_dispose() {
> +    if (!_M_is_local())
> +      _M_destroy();
> +  }
> +  char *_M_construct___end;
> +  Trans_NS___cxx11_basic_string(Trans_NS___cxx11_basic_string &)
> +      : _M_dataplus(0) {
> +    struct _Guard {
> +      ~_Guard() { _M_guarded->_M_dispose(); }
> +      Trans_NS___cxx11_basic_string *_M_guarded;
> +    } __guard0;
> +    _S_copy_chars(&_M_p, &_M_construct___beg, _M_construct___end);
> +  }
> +};
> +namespace filesystem {
> +struct path {
> +  path();
> +  Trans_NS___cxx11_basic_string _M_pathname;
> +};
> +} // namespace filesystem
> +struct FileWriter {
> +  filesystem::path path;
> +  FileWriter() : path(path) {}
> +};
> +struct LanguageFileWriter : FileWriter {
> +  LanguageFileWriter(filesystem::path) {}
> +};
> +int
> +main() {
> +  filesystem::path output_file;
> +  LanguageFileWriter writer(output_file);
> +}
> --
> 2.47.1
> 

Reply via email to