Reference:
GCC 15.3: Tooling / gnu-toolchains-for-arm · GitLab
GCC 13.2: Tooling / gnu-toolchains-for-arm · GitLabSummary:
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:
g_Module_A_correction_info
volatile
-O2
status = Module_A_CORRECTION_RUN
Module_A_CORRECTION_RUN
scanbuf
status
Module_A_CORRECTION_COMPLETE
Flow code:
[1] is removed by GCC 15.3 -O2. Only [2] is emitted, so the ISR always reads COMPLETE.Disassembly
[1]
[2]
COMPLETE
On the left is GCC 13.2: the status variable is not optimized out and its assignment is preserved, allowing the ISR to read the RUN state.
RUN
On the right is GCC 15.3: the status variable is optimized out and the assignment is eliminated. As a result, the ISR fails to read it, leading to a failure.
Environment / result
Questions:
1. Upon investigation, I suspect this optimization is related to Dead Store Elimination (DSE). I managed to work around it by adding the compiler flag --param=dse-max-alias-queries-per-store=16 to reduce the query limit from its default value of 256, which resolved the issue and made the code work.I am not entirely clear on the underlying optimization mechanism. Could you please verify and explain how this optimization works, whether it is indeed DSE, and how it depends on the --param=dse-max-alias-queries-per-store flag?
--param=dse-max-alias-queries-per-store=16
--param=dse-max-alias-queries-per-store
2. Besides, I also tried fixing it by adding __COMPILER_BARRIER(); right after assigning the status variable to prevent Dead Store Elimination (DSE) optimization, and the code worked as well.
__COMPILER_BARRIER();
Could you explain the underlying mechanism of this optimization?
Please help me check it.Thank you so much.
Hi,It is hard to be certain given the information you provided, but it sounds to me like GCC 15.3's DSE believes 'status = Module_A_CORRECTION_RUN' is 'dead', i.e. irrelevant. In your flow code image, if GCC doesn't think status is read between [1] and [2] then it rightfully assumes [1] is dead. It's not entirely clear to me whether APP and Module_A ISR are running concurrently, nor how g_Module_A_correction_info is shared between the two so I can't give you a good suggestion on how to best go about this, all I can say is that you need to make the compiler aware somehow that 'status' can be accessed between [1] and [2]. Potential solutions are using atomic read/writes, volatile or passing around the variable so the dataflow becomes visible to the compiler.