> On Tue, 17 Jan 2023, Jan Hubicka wrote: > > > > > We don't use same argumentation about other control flow statements. > > > > The following: > > > > > > > > fn() > > > > { > > > > try { > > > > i_read_no_global_memory (); > > > > } catch (...) > > > > { > > > > reutrn 1; > > > > } > > > > return 0; > > > > } > > > > > > > > should be detected as const. Marking throw pure would make fn pure too. > > > > > > I suppose i_read_no_global_memory is const here. Not sure why that > > Suppose we have: > > > > void > > i_read_no_global_memory () > > { > > throw(0); > > } > > > > If cxa_throw itself was annotated as 'p' rahter than 'c' ipa-modref will > > believe that cxa_throw will read any global memory and will propagate it > > to all callers. So fn() will be also marked as reading all global > > memory. > > Sure - but for the purpose of local optimizations in > i_read_no_global_memory cxa_throw has to appear to read memory.
Yes, I think every stmt that can throw externally need VUSE (just like return_stmt needs it). Even if throw(0) was replaced by a=b/c with -fnon-call-exceptions. It is still not clear to me why this should imply that we need 'p' instead of 'c' in fnspecs. So I think we should try to make the following to work: diff --git a/gcc/tree-ssa-operands.cc b/gcc/tree-ssa-operands.cc index 57e393ae164..d24f1721eb2 100644 --- a/gcc/tree-ssa-operands.cc +++ b/gcc/tree-ssa-operands.cc @@ -951,6 +951,9 @@ operands_scanner::parse_ssa_operands () enum gimple_code code = gimple_code (stmt); size_t i, n, start = 0; + if (stmt_can_throw_external (fn, stmt)) + append_vuse (gimple_vop (fn)); + switch (code) { case GIMPLE_ASM: > Having a VUSE there dependent on whether the function performs any > load or store would be quite ugly. Instead modref could special-case > cxa_throw and not treat it as reading memory (like it already does > for the return stmt I suppose - that also has a VUSE). modref looks into statements with VUSEs on them and checks what reads/stores are done. So return statement with VUSE is walked and no load is recorded because no actual load is found. Similarly that would happen with __cxa_throw if it was 'c'. With 'p' it has nothing to analyze so it would trust the fact that cxa_throw itself reads some global state. > > The problem is IIRC GIMPLE_RESX which doesn't derive from > gimple_statement_with_memory_ops_base. There's a bugzilla I can't find > right now refering to this issue. I never tried to play with gimple hiearchy. It is hard to fix resx? I wonder if we have other cases. I guess for a=b/c we are luck just because gimple_assign can also be load or store so it has memory_ops... Thanks, Honza