https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82677
--- Comment #9 from infinity0 at pwned dot gg --- (In reply to rguent...@suse.de from comment #7) > [..] > > You still have to mark stmts with side-effects as volatile. > > Conditional side-effects are tricky to get correct of course. I think with the current asm() syntax and semantics, the only way to get this correct in the C source code, is by using __volatile__. It is not possible to even *express* "conditional side-effects" using the current syntax. To demonstrate: The "explicit zero check" that I mentioned in the first post does not actually work, see the newer udiv.c test that I just attached. I think that is correct behaviour from GCC as well. AIUI, asm() without volatile, says to GCC: "this code will *never* cause side effects under *any circumstance*, it depends only on its declared inputs/outputs/clobbers". Under this assumption, it is correct to optimise | if(d) { asm(d); ... } ... into | asm(d); if(d) { ... } as long as the outputs to asm(d) don't clobber the inputs to if(d) or any else-branches - I assume other parts of the optimiser will already check that. However, it is *not* correct to perform the above, when the asm(d) has conditional side-effects depending on d, that the if(d) checks for. But there is no way to express this conditional-side-effect using the current asm() syntax. So GCC will happily go ahead and perform the optimisation, since it believes asm(d) will never have any side effects. So, the pre-optimised code "looks correct", it's explicitly checking d, but will in fact cause the types of unintended optimisations that we're looking at here. The only way to avoid this is to use "volatile". In conclusion: whilst making the optimiser more strict for this case as you suggested, would fix this specific instance, I believe that it is not "the proper fix" for GCC. A proper fix would have to involve changing the *semantics* of a asm(div) call so that GCC understands that it has "side effects depending on the divisor and n1[1]". Otherwise, more sophisticated optimisations added to GCC in the future might make this issue come back. If that is not done, then it would be necessary to fix these 20 projects's C source code to properly express __volatile__. Actually this is probably necessary regardless of any GCC fixes - from some quick searches it seems that asm() semantics is not standardised, and also these projects might want to support older GCC that has the existing semantics. [1] it can also raise DE when n1 >= divisor.