]> git.ipfire.org Git - thirdparty/gcc.git/commit
middle-end/100394 - avoid DSE/DCE of pure call that throws
authorRichard Biener <rguenther@suse.de>
Mon, 3 May 2021 13:11:28 +0000 (15:11 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 5 May 2021 07:11:23 +0000 (09:11 +0200)
commit8ebf6b99952ada09bf9ea0144dcd1d46363b0464
tree4c5614950602b44572548fc6f3e1be9e85584664
parent61d48b1e2b5bae1e0e5e48af296facd61617139c
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  <rguenther@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.
gcc/calls.c
gcc/cfgexpand.c
gcc/testsuite/g++.dg/torture/pr100382.C [new file with mode: 0644]
gcc/tree-ssa-dce.c
gcc/tree-ssa-dse.c
gcc/tree.h