From 3d2210dafd872e8470e2a6ae5eea74d2669bc055 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 11 Apr 2023 15:06:59 +0200 Subject: [PATCH] tree-optimization/109434 - bogus DSE of throwing call LHS The byte tracking of call LHS didn't properly handle possibly throwing calls correctly which cases bogus DSE and in turn, for the testcase a bogus uninit diagnostic and (unreliable) wrong-code. PR tree-optimization/109434 * tree-ssa-dse.cc (initialize_ao_ref_for_dse): Properly handle possibly throwing calls when processing the LHS and may-defs are not OK. Add mode to initialize a may-def. (dse_optimize_stmt): Query may-defs. * g++.dg/opt/pr109434.C: New testcase. --- gcc/testsuite/g++.dg/opt/pr109434.C | 28 ++++++++++++++++++++++++++++ gcc/tree-ssa-dse.cc | 15 ++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/pr109434.C diff --git a/gcc/testsuite/g++.dg/opt/pr109434.C b/gcc/testsuite/g++.dg/opt/pr109434.C new file mode 100644 index 000000000000..cffa327fd9b5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/pr109434.C @@ -0,0 +1,28 @@ +// { dg-do compile } +// { dg-require-effective-target c++17 } +// { dg-options "-O2 -Wall" } + +#include +#include + +std::optional foo() +{ + volatile int x = 1; + if (x) + throw std::runtime_error("haha"); + return 42; +} + +int main() +{ + std::optional optInt; + try { + // We falsely DSEd the LHS of the call even though foo throws + // which results in an uninitialized diagnostic + optInt = foo(); + } catch (...) { + return optInt.has_value(); + } + std::optional optDbl{optInt}; + return optDbl ? optDbl.value () : 2.0; +} diff --git a/gcc/tree-ssa-dse.cc b/gcc/tree-ssa-dse.cc index e647f0e7368c..ba448c999dd7 100644 --- a/gcc/tree-ssa-dse.cc +++ b/gcc/tree-ssa-dse.cc @@ -93,7 +93,9 @@ static bitmap need_eh_cleanup; static bitmap need_ab_cleanup; /* STMT is a statement that may write into memory. Analyze it and - initialize WRITE to describe how STMT affects memory. + initialize WRITE to describe how STMT affects memory. When + MAY_DEF_OK is true then the function initializes WRITE to what + the stmt may define. Return TRUE if the statement was analyzed, FALSE otherwise. @@ -101,7 +103,7 @@ static bitmap need_ab_cleanup; can be achieved by analyzing more statements. */ static bool -initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write) +initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write, bool may_def_ok = false) { /* It's advantageous to handle certain mem* functions. */ if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)) @@ -148,7 +150,8 @@ initialize_ao_ref_for_dse (gimple *stmt, ao_ref *write) } else if (tree lhs = gimple_get_lhs (stmt)) { - if (TREE_CODE (lhs) != SSA_NAME) + if (TREE_CODE (lhs) != SSA_NAME + && (may_def_ok || !stmt_could_throw_p (cfun, stmt))) { ao_ref_init (write, lhs); return true; @@ -1293,8 +1296,10 @@ dse_optimize_stmt (function *fun, gimple_stmt_iterator *gsi, sbitmap live_bytes) ao_ref ref; /* If this is not a store we can still remove dead call using - modref summary. */ - if (!initialize_ao_ref_for_dse (stmt, &ref)) + modref summary. Note we specifically allow ref to be initialized + to a conservative may-def since we are looking for followup stores + to kill all of it. */ + if (!initialize_ao_ref_for_dse (stmt, &ref, true)) { dse_optimize_call (gsi, live_bytes); return; -- 2.47.2