In the testcase provided, currently we lose the landing pad for the exception that could throw from the aggregate load as we remove one copy and the second statement where load happens was not marked as throwable before so the landing pad for that internal throw is now gone.
The fix is to ignore statements that could throw (internally or externally). PR tree-optimization/120599 gcc/ChangeLog: * tree-ssa-forwprop.cc (optimize_agr_copyprop): Don't try to copy from statements that throw. gcc/testsuite/ChangeLog: * g++.dg/torture/noncall-eh-1.C: New test. Signed-off-by: Andrew Pinski <quic_apin...@quicinc.com> --- gcc/testsuite/g++.dg/torture/noncall-eh-1.C | 26 +++++++++++++++++++++ gcc/tree-ssa-forwprop.cc | 4 ++++ 2 files changed, 30 insertions(+) create mode 100644 gcc/testsuite/g++.dg/torture/noncall-eh-1.C diff --git a/gcc/testsuite/g++.dg/torture/noncall-eh-1.C b/gcc/testsuite/g++.dg/torture/noncall-eh-1.C new file mode 100644 index 00000000000..ea8fd7953f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/noncall-eh-1.C @@ -0,0 +1,26 @@ +// { dg-do compile } +// For slim LTO there's no optimized dump +// { dg-skip-if "" { *-*-* } { "-flto" } { "" } } +// { dg-additional-options "-fnon-call-exceptions -fexceptions -fdump-tree-optimized-eh" } + +// PR tree-optimization/120599 +// Copying prop for aggregates should not touch `a = *__val` since that statement +// can throw (internally) so we need to be able to keep the landing pad. + +struct RefitOption { + char subtype; + int string; +} n; +void h(RefitOption) __attribute__((nothrow)); +void k(RefitOption *__val, RefitOption a) +{ + try { + a = *__val; + RefitOption __trans_tmp_2 = a; + h(__trans_tmp_2); + } + catch(...){} +} + +// Make sure There is a landing pad for the non-call exception from the aggregate load. +// { dg-final { scan-tree-dump "LP " "optimized" } } diff --git a/gcc/tree-ssa-forwprop.cc b/gcc/tree-ssa-forwprop.cc index f3abb6f7338..78305699a62 100644 --- a/gcc/tree-ssa-forwprop.cc +++ b/gcc/tree-ssa-forwprop.cc @@ -1408,6 +1408,10 @@ optimize_agr_copyprop (gimple_stmt_iterator *gsip) if (gimple_has_volatile_ops (stmt)) return false; + /* Can't prop if the statement could throw. */ + if (stmt_could_throw_p (cfun, stmt)) + return false; + tree dest = gimple_assign_lhs (stmt); tree src = gimple_assign_rhs1 (stmt); /* If the statement is `src = src;` then ignore it. */ -- 2.43.0