> On Mar 4, 2026, at 8:34 AM, Jan Hubicka <[email protected]> wrote:
> 
> 
>> 
>>> On Wed, Mar 4, 2026 at 11:05 AM Chris Copeland <[email protected]> wrote:
>>> 
>>> I reported https://gcc.gnu.org/bugzilla/show_bug.cgi?id=124218
>>> recently after learning it affects the synchronization interfaces
>>> provided by real-time operating systems when using -fwhole-program or
>>> -flto. For example, this can leads to moving accesses outside of a
>>> section where a FreeRTOS mutex is held. Other ipa passes like
>>> ipa-pure-const and ipa-modref handle memory clobbers in their analysis
>>> already.
>>> 
>>> I've added a new test that runs on arm-none and will fail without the
>>> change to ipa-reference.cc, by having an assembly statement that
>>> declares a memory clobber and actually writes a global that the previous
>>> version of the analysis would treat as not modified. Please let me know
>>> if there's a more appropriate way to test this. Other tests are passing
>>> on an aarch64 linux host.
>>> 
>>>        PR ipa/124218
>>> ---
>>> gcc/ChangeLog                       |  6 ++++++
>>> gcc/ipa-reference.cc                | 23 +++++++++++++++++++++++
>>> gcc/testsuite/gcc.dg/ipa/pr124218.c | 25 +++++++++++++++++++++++++
>>> 3 files changed, 54 insertions(+)
>>> create mode 100644 gcc/testsuite/gcc.dg/ipa/pr124218.c
>>> 
>>> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
>>> index 8f5a62893c1..1be3b678fda 100644
>>> --- a/gcc/ChangeLog
>>> +++ b/gcc/ChangeLog
>>> @@ -1,3 +1,9 @@
>>> +2026-03-03  Chris Copeland  <[email protected]>
>>> +
>>> +       PR ipa/124218
>>> +       * ipa-reference.cc (analyze_function): Treat memory clobbers as
>>> +       reading/writing all_module_statics.
>>> +
>>> 2026-03-03  H.J. Lu  <[email protected]>
>>> 
>>>        PR target/124165
>>> diff --git a/gcc/ipa-reference.cc b/gcc/ipa-reference.cc
>>> index c5699312c8f..0c50b4b2df7 100644
>>> --- a/gcc/ipa-reference.cc
>>> +++ b/gcc/ipa-reference.cc
>>> @@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
>>> #include "backend.h"
>>> #include "tree.h"
>>> #include "gimple.h"
>>> +#include "gimple-iterator.h"
>>> #include "tree-pass.h"
>>> #include "cgraph.h"
>>> #include "data-streamer.h"
>>> @@ -550,6 +551,28 @@ analyze_function (struct cgraph_node *fn)
>>> 
>>>   if (fn->cannot_return_p ())
>>>     bitmap_clear (local->statics_written);
>>> +
>>> +  /* If the function body contains any asm statement that clobbers memory,
>>> +     mark all module statics as read and written.  */
>> 
>> An extra IL walk seems excessive for this, I wonder if we (should)
>> have recorded such fact
>> elsewhere, like in some other IPA summary?
> 
> I suppose best fit is fnsummary which holds all kinds of stuff useful
> for IPA passes and is always computed.
> 
>>> +/* PR ipa/124218: ipa-reference must honor memory clobbers in inline asm.  
>>> */
>>> +
>>> +int flag;
>>> +
>>> +__attribute__ ((noinline))
>>> +static void
>>> +clobber_and_set (void)
>>> +{
>>> +  __asm__ volatile ("ldr r0, =flag\n\t"
>>> +                   "mov r1, #1\n\t"
>>> +                   "str r1, [r0]"
>>> +                   ::: "r0", "r1", "memory");
> 
> At least withtout new Michal's heuristics, for making this safe with LTO
> you need used attribute on flag and that disables ipa-reference on it.

This was discussed some on the bug report, but in the real code this clobber is 
at the location where a context switch is triggered, which eventually leads to 
another task executing that modifies flag. I wrote the test this way because 
it's the simplest thing I could come up with to represent that situation. Would 
an unrelated and not-called function that does modify the flag obviate the need 
for ((used)) in this test, even without forthcoming changes?

> 
> Honza
>>> +}
>>> +
>>> +int main (void)
>>> +{
>>> +  flag = 0;
>>> +  clobber_and_set ();
>>> +  if (!flag)
>>> +    __builtin_abort ();
>>> +  return 0;
>>> +}
>>> --
>>> 2.53.0
>>> 

Reply via email to