On Thu, Apr 7, 2022 at 1:20 PM Jan Hubicka via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > Hi, > this patch fixes ipa-modref propagation of pure/const functions. When we > inline > function, the modref summary is updated to represent the function after > inlining and there we need to propagate nondeterministic and side-effects > flag. > > Bootstrapped/regtested x86_64-linux, will commit it shortly.
I noticed we have ->writes_errno in the summary which we do not handle in this function either? That's also missing on the GCC 11 branch (where I just picked r12-2851-g9851a1631f2915 and r12-5538-ga70faf6e4df748, both still in testing). Richard. > Honza > > gcc/ChangeLog: > > 2022-04-07 Jan Hubicka <hubi...@ucw.cz> > > PR ipa/105160 > * ipa-modref.cc (ipa_merge_modref_summary_after_inlining): > > gcc/testsuite/ChangeLog: > > 2022-04-07 Jan Hubicka <hubi...@ucw.cz> > > PR ipa/105160 > * gcc.dg/ipa/pr105160.c: New test. > > diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc > index acfd7d80ff8..556816ab429 100644 > --- a/gcc/ipa-modref.cc > +++ b/gcc/ipa-modref.cc > @@ -5281,6 +5281,29 @@ ipa_merge_modref_summary_after_inlining (cgraph_edge > *edge) > if (!ignore_stores) > to_info_lto->stores->collapse (); > } > + /* Merge side effects and non-determinism. > + PURE/CONST flags makes functions deterministic and if there is > + no LOOPING_CONST_OR_PURE they also have no side effects. */ > + if (!(flags & (ECF_CONST | ECF_NOVOPS | ECF_PURE)) > + || (flags & ECF_LOOPING_CONST_OR_PURE)) > + { > + if (to_info) > + { > + if (!callee_info || callee_info->side_effects) > + to_info->side_effects = true; > + if ((!callee_info || callee_info->nondeterministic) > + && !ignore_nondeterminism_p (edge->caller->decl, flags)) > + to_info->nondeterministic = true; > + } > + if (to_info_lto) > + { > + if (!callee_info_lto || callee_info_lto->side_effects) > + to_info_lto->side_effects = true; > + if ((!callee_info_lto || callee_info_lto->nondeterministic) > + && !ignore_nondeterminism_p (edge->caller->decl, flags)) > + to_info_lto->nondeterministic = true; > + } > + } > if (callee_info || callee_info_lto) > { > auto_vec <modref_parm_map, 32> parm_map; > diff --git a/gcc/testsuite/gcc.dg/ipa/pr105160.c > b/gcc/testsuite/gcc.dg/ipa/pr105160.c > new file mode 100644 > index 00000000000..ea80545b102 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/ipa/pr105160.c > @@ -0,0 +1,77 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O -fdump-ipa-modref" } */ > +#define sysreg_read(regname) \ > +({ \ > + unsigned long __sr_val; \ > + asm volatile(""); \ > + \ > + __sr_val; \ > +}) > + > +#define sysreg_write(regname, __sw_val) \ > +do { \ > + asm volatile(""); \ > +} while (0) > + > +#define isb() \ > +do { \ > + asm volatile( \ > + "isb" \ > + : \ > + : \ > + : "memory"); \ > +} while (0) > + > +static unsigned long sctlr_read(void) > +{ > + return sysreg_read(sctlr_el1); > +} > + > +static void sctlr_write(unsigned long val) > +{ > + sysreg_write(sctlr_el1, val); > +} > + > +static void sctlr_rmw(void) > +{ > + unsigned long val; > + > + val = sctlr_read(); > + val |= 1UL << 7; > + sctlr_write(val); > +} > + > +void sctlr_read_multiple(void) > +{ > + sctlr_read(); > + sctlr_read(); > + sctlr_read(); > + sctlr_read(); > +} > + > +void sctlr_write_multiple(void) > +{ > + sctlr_write(0); > + sctlr_write(0); > + sctlr_write(0); > + sctlr_write(0); > + sctlr_write(0); > +} > + > +void sctlr_rmw_multiple(void) > +{ > + sctlr_rmw(); > + sctlr_rmw(); > + sctlr_rmw(); > + sctlr_rmw(); > +} > + > +void function(void) > +{ > + sctlr_read_multiple(); > + sctlr_write_multiple(); > + sctlr_rmw_multiple(); > + > + isb(); > +} > +/* { dg-final { scan-ipa-dump-not "Function found to be const" "modref" } } > */