Hi! On Tue, Oct 17, 2017 at 12:27:08AM +0200, David Brown wrote: > There has been a discussion going on about asm volatile statement > reordering, where there has been surprising code generated for the ARM > with certain code and compiler flags. The discussion has been in the > comp.arch.embedded Usenet group, the gcc-arm-embedded project (the most > common source of gcc for embedded ARM devices, both for individuals and > for companies), and some other related projects. I believe it is time > to ask the gcc folks too! > > This is a link to the gcc-arm-embedded issue, which is perhaps the most > complete version. > > <https://bugs.launchpad.net/gcc-arm-embedded/+bug/1722849?comments=all> I cannot reproduce this problem (with trunk GCC). What is different about the compiler used there / what else is different? ... I now also tried with some GCC 5, and the problem does happen there. Please open a PR! This is similar to PR62642, which is about unspec_volatile -- essentially everything that applies to unspec_volatile also applies to volatile asm. I did the following patch, which fixes the problem in the testcase. Please try it with the "real" code? (And do open a PR please). > Much of this boils down to the question of when gcc is allowed to > re-order "asm volatile" statements, with respect to other "asm volatile" > statements, volatile memory accesses, and unknown functions (which may > contain observable behaviour). "asm volatile" means the asm has an (unknown) side effect when executed. It cannot be moved over any other side effects. > My testing suggests that gcc will re-order "asm volatile" statements > that have an output, such as the "save the PRIMASK into status" > statement, but it will /not/ re-order "asm volatile" statements that > have no outputs. > > Is that correct? Nope, you found a bug :-) Segher Index: gcc/ira.c =================================================================== --- gcc/ira.c (revision 251105) +++ gcc/ira.c (working copy) @@ -4418,6 +4418,10 @@ for a reason. */ return false; + case ASM_OPERANDS: + if (MEM_VOLATILE_P (x)) + return false; + default: break; }