We are evaluation Keil uVision V4.10 and ARMCC V4.1.0.481.
Our first test run didn't go so well.
With no optimisation, everything worked OK. Using optimisation 1 or above, the test failed.
For various reasons, I can not disclose the test source code. However, I will attempt to create a small self-contained example later on. The part of the test code that caused the problem is setting up an multi dimensional array, setting each element to '1' (ie. Array[x][y] = 1 with a for loop for both x and y).
In the meantime, I wonder if anyone has had a similar problem?
Using optimisation -O3, the assembler code in the debugger looks like this:
48: for ( y= 0 ; y < 8 ; y++ ) 0x80000AAC E5C02000 STRB R2,[R0] 0x80000AB0 E2822001 ADD R2,R2,#0x00000001 0x80000AB4 E3A0C001 MOV R12,#0x00000001 0x80000AB8 E20220FF AND R2,R2,#0x000000FF 0x80000ABC E7C3C001 STRB R12,[R3,R1] 0x80000AC0 E5C02001 STRB R2,[R0,#0x0001] 0x80000AC4 EAFFFFFC B 0x80000ABC -- Isn't this an infinite loop???
One thing with volatile and concurrency is that for example SFR represents concurrency even if no interrupts are involved.
So volatile may be required to force reads, to be able to know that the SFR contents have changed.
This is beside the fact that a read of some SFR may result in acknowledges of a hardware state machine.
And writes to memory are always subject to cancellation by code optimizers if the compiler can't see anyone else use the memory contents.
You seem to be missing the point.
Regardless of whether or not the variables used are volatile, and whether or not the compiler chooses to complete ignore the filling of the array, the compiler should change a known loop with exit condition to a loop without an exit condition.
For example, if the code was "for (x = 0; x < 64; x ++) /* do nothing */;" then we wouldn't care if the code was optimised out. That would be ok.
The problem is that the compiler changed code like "for (x = 0; x < 64; x ++)" to "while (1)". These are most definitely NOT the same, regardless of any optimisation.
Therefore, we concluded that this was an optimisation fault.
The correlation between individual pieces of C code and the generated assembly becomes vague at best the higher optimization level selected. The infinite loop must have been associated with something else - that is my opinion.
"Regardless of whether or not the variables used are volatile, and whether or not the compiler chooses to complete ignore the filling of the array, the compiler should [not] change a known loop with exit condition to a loop without an exit condition."
That depends whether that loop in the particular context was equivalent to a loop without an exit condition.
eg,
void main( void ) { // Test filling an array for (x = 0; x < 100; x ++) for (y = 0; y < 8; y ++) array[x][y] = 1; // "Test finished - we're done" for( ;; ); // Embedded code - must not exit main! }
Again, without seeing the context, further discussion is impossible.
I'm not saying this is wrong but ... I don't quite like the space between 'y' and '++'...
Is this common practice to write like this?