3
votes

From the Procedure Call Standard for the ARM architecture (§7.1.5):

a compiler may ignore a volatile qualification of an automatic variable whose address is never taken unless the function calls setjmp().

Is that mean that in following code:

volatile int x = 8;
if (x == 1)
{
    printf("can be optimised away??");
}

The whole if scope can be optimised out?

This just contradict the standard, for starters, volatile accesses are part of the observable behaviour and must be performed as in the abstract machine code:

§5.1.2.3:

The least requirements on a conforming implementation are:

Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.

And also §6.7.3:

An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine

Is there a contradiction? And if so, how is it legit that a PCS contradict the C standard?

1
Why is it contradicting the standard? If no one is observing x through a pointer, then why does it still need to be treated as volatile? The C standard says "At sequence points, volatile objects are stable in the sense that previous accesses are complete and subsequent accesses have not yet occurred." This looks like it can be met given the constraints set by the PCS. - John Szakmeister
The least requirements on a conforming implementation are: Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine... can it get simpler than that? also An object that has volatile-qualified type may be modified in ways unknown to the implementation or have other unknown side effects. Therefore any expression referring to such an object shall be evaluated strictly according to the rules of the abstract machine, - user2162550
I cannot find any compiler in godbolt that optimize it. Examples- godbolt.org/z/DlA4vs , godbolt.org/z/yUU6O9 - user2162550
How could x be modified in a way unknown to the compiler? <- by an ISR or memory-mapped hardware etc. The compiler is not aware of how the HW works. This happens a lot in embedded software. - Morten Jensen
I think the key is in "Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine." ARM procedure call standard applies to not any abstract machine, just ARM abstract machines and so can optimize out the code as it knows x is not accessed within its world of abstract machines. - chux - Reinstate Monica

1 Answers

0
votes

So I reached ARM toolchain's support group, and according to them the ARM PCS standard is an independent standard that is not bound to the C standard, such that a compiler can choose to comply to one, or both of them. In their own words:

In a way it's not really a contradiction

  • the APCS permits a compiler to respect or ignore local volatile
  • the C standard requires a compiler to respect local volatile

so a compiler that is compatible with both will respect local volatile.

Armclang has elected to follow the C standard which makes it compatible with both

So if a compiler choose to perform this non C-conforming optimization, it is still ARM PCS conforming implementation, but not a C-conforming compiler.

To conclude, a C-conforming compiler for ARM architecture which implements ARM PCS will never perform this optimization.