http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54500
Bug #: 54500 Summary: While(TRUE) loop optimization of global struct variables Classification: Unclassified Product: gcc Version: 4.3.2 Status: UNCONFIRMED Severity: major Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: t...@email.cz Target: avr-* Build: WinAVR 20081205 I have large global static structure with substructers, longs etc. struct { longs ... structs ... struct { boolean isEnd; } ss; etc. } gs; void procedure() { while(true) { if (gs.ss.isEnd) { if (an_cond1) { break; } } if (an_cond2) { break; } do_access_and_modify_gs_fields; gs.ss.isEnd = TRUE; do_access_and_modify_gs_fields; } if (gs.ss.IsEnd) { } when used in "neverending" while with breaks then gcc fails to optimize correctly changed fields of global structure. Gcc tries to cache field used in loop into registers and when no more registers on the stack (what is benefit of copying vars from global variable onto stack ???). Changed values are flushed back into global variable when loop terminates. There are several breaks how to exit the loop. Suprisingly every loop has "copy&pasted" the same exit code (why don't reuse one to save some memory ??). Respectively they should be at least equal but in my case one of them did not flush back one field (gs.isEnd after loop get unupdated value). I tried somehow persuade gcc to know that isEnd is really modified by asm inline code. Sucessfully but any change of code may change optimization and it appears again in another form. Currently is problem that "gs.isEnd = TRUE;" updates optimized value in register but "if (gs.ss.isEnd)" in loop check again global memory. Seems gcc is totally confused with this construction. I hope setting struct as volatile should help. avr-g++ -MM -mmcu=atmega2560 -g -Os -Wall -Wextra -w -ffunct ion-sections -fdata-sections -fno-exceptions my.cpp -MF my.d -MT my.o