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?

> +  struct function *fun = DECL_STRUCT_FUNCTION (fn->decl);
> +  if (fun && fun->cfg)
> +    {
> +      basic_block bb;
> +      FOR_EACH_BB_FN (bb, fun)
> +       for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
> +            !gsi_end_p (gsi); gsi_next (&gsi))
> +         {
> +           gimple *stmt = gsi_stmt (gsi);
> +           if (gimple_code (stmt) == GIMPLE_ASM
> +               && gimple_asm_clobbers_memory_p (as_a <gasm *> (stmt)))
> +             {
> +               local->statics_read = all_module_statics;
> +               if (!fn->cannot_return_p ())
> +                 local->statics_written = all_module_statics;
> +               return;
> +             }
> +         }
> +    }
>  }
>
>
> diff --git a/gcc/testsuite/gcc.dg/ipa/pr124218.c 
> b/gcc/testsuite/gcc.dg/ipa/pr124218.c
> new file mode 100644
> index 00000000000..7cfb17034c6
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/pr124218.c
> @@ -0,0 +1,25 @@
> +/* { dg-do run { target arm*-*-eabi* } } */
> +/* { dg-options "-O1 -fwhole-program" } */
> +
> +/* 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");
> +}
> +
> +int main (void)
> +{
> +  flag = 0;
> +  clobber_and_set ();
> +  if (!flag)
> +    __builtin_abort ();
> +  return 0;
> +}
> --
> 2.53.0
>

Reply via email to