> 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

Reply via email to