https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100394

--- Comment #6 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Richard Biener <rgue...@gcc.gnu.org>:

https://gcc.gnu.org/g:8ebf6b99952ada09bf9ea0144dcd1d46363b0464

commit r12-475-g8ebf6b99952ada09bf9ea0144dcd1d46363b0464
Author: Richard Biener <rguent...@suse.de>
Date:   Mon May 3 15:11:28 2021 +0200

    middle-end/100394 - avoid DSE/DCE of pure call that throws

    There is -fdelete-dead-exceptions now and we're tracking
    nothrow and const/pure bits separately and I do remember that
    const or pure does _not_ imply nothrow.

    Now, in the light of the PR100382 fix which added a
    stmt_unremovable_because_of_non_call_eh_p guard to DSEs "DCE"
    I wondered how -fdelete-dead-exceptions applies to calls and
    whether stmt_unremovable_because_of_non_call_eh_p doing

      return (fun->can_throw_non_call_exceptions
              && !fun->can_delete_dead_exceptions
              && stmt_could_throw_p (fun, stmt));

    really should conditionalize itself on
    fun->can_throw_non_call_exceptions.  In fact DCE happily elides
    pure function calls that throw without a LHS (probably a
    consistency bug).  The following testcase shows this:

    int x, y;
    int __attribute__((pure,noinline)) foo () { if (x) throw 1; return y; }

    int main()
    {
      int a[2];
      x = 1;
      try {
        int res = foo ();
        a[0] = res;
      } catch (...) {
          return 0;
      }
      return 1;
    }

    note that if you wrap foo () into another noinline
    wrap_foo () { foo (); return 1; } function then we need to make
    sure to not DCE this call either even though it only throws
    externally.

    2021-05-03  Richard Biener  <rguent...@suse.de>

            PR middle-end/100394
            * calls.c (expand_call): Preserve possibly throwing calls.
            * cfgexpand.c (expand_call_stmt): When a call can throw signal
            RTL expansion there are side-effects.
            * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Simplify,
            mark all possibly throwing stmts necessary unless we can elide
            dead EH.
            * tree-ssa-dse.c (pass_dse::execute): Preserve exceptions unless
            -fdelete-dead-exceptions.
            * tree.h (DECL_PURE_P): Add note about exceptions.

            * g++.dg/torture/pr100382.C: New testcase.

Reply via email to