On Fri, 12 Jun 2015 19:53:03 +0100 Andrew Haley <aph@xxxxxxxxxx> wrote: > No it isn't. It is. > > > That's the whole point about the example. > > No it's not. The only thing moved across the barrier is the > division. A memory op cannot be moved across a memory barrier. One memory barrier is at the cli(), as the article points out "where the potentially slow division is moved across cli(),". The assignment to val is moved, over that. It was before cli() in the C source and it's after cli() after optimization. As your own comment shows. > Here's the code: > > 00000112 <test2>: > 112: bc 01 movw r22, r24 > 114: f8 94 cli That's the cli(). > 116: 8f ef ldi r24, 0xFF ; 255 > 118: 9f ef ldi r25, 0xFF ; 255 > 11a: 0e 94 96 00 call 0x12c ; 0x12c <__udivmodhi4> > 11e: 70 93 01 02 sts 0x0201, r23 > 122: 60 93 00 02 sts 0x0200, r22 > > The store to val is here ^ Thanks. Didn't try to find that, just figured that it would be difficult to assign the result of the division before the division happened. So you just confirmed everything. This is after cli(). Actually, I think you're wrong here - this is not the store to val (I guess you could r24 consider to be val, since that's it at the beginning of the function), it's the store to ivar. The store to val never happens, it is optimized away because val is not a volatile variable, it's just a temporary one which is never used afterwards. Which, still, is the point of the article: Because val is not declared volatile, it is not "memory", so assignments to it (and the division required to happen before the assignment) can be moved across the barrier. So, again, why would it be ok to remove the volatile qualifier from my array elements? How else can I be sure a variable of mine is "memory"? Sebastian