Differences in the optimization mechanism between GCC 13.2 and GCC 15.3 result in code failure


Reference:

GCC 15.3: Tooling / gnu-toolchains-for-arm · GitLab

GCC 13.2: Tooling / gnu-toolchains-for-arm · GitLab


Summary:

g_Module_A_correction_info is shared between the application and the Module_A ISR, but it is not declared volatile. With the same source code and the same -O2 level, the result depends on the compiler version:

  • GCC 13.2: the store status = Module_A_CORRECTION_RUN is kept. The ISR sees Module_A_CORRECTION_RUN, updates scanbuf, and the correction data is correct.
  • GCC 15.3: the same store is removed as a dead store, because status is overwritten with Module_A_CORRECTION_COMPLETE later in the same function. The ISR never sees Module_A_CORRECTION_RUN, never updates scanbuf, and the correction data is wrong.

Flow code:

[1] is removed by GCC 15.3 -O2. Only [2] is emitted, so the ISR always reads COMPLETE.

Environment / result

Compiler Opt. Result
GCC 13.2 -O2 OK (works by chance)
GCC 15.3 -O2 NG: store [1] eliminated, ISR skips update

Expected: status is CTSU_CORRECTION_RUN while the measurement runs, and the ISR updates scanbuf.
Actual: status goes straight to CTSU_CORRECTION_COMPLETE, and the ISR condition is never true.

Questions:

  1. Root cause of the difference between compiler versions: With the same source code and the same -O2 level, why does GCC 15.3 remove the store status = Module_A_CORRECTION_RUN, while GCC 13.2 keeps it?
  2. Optimization mechanism: Which optimization (pass or technique) removes this store, and under what conditions does GCC treat it as a dead store?
  3. Official documentation: Is there official documentation, such as the GCC manual or the GCC 14/15 release notes, that describes this optimization or the change in its behavior?
  4. Fix on GCC 15.3: What is the recommended fix for this issue on GCC 15.3? Is it related to the --param=dse-max-alias-queries-per-store option?

Please help me check it.
Thank you so much.