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
>