https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94425
Bug ID: 94425 Summary: [D] Consider always settings ASM_VOLATILE_P on asm statements Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: d Assignee: ibuclaw at gdcproject dot org Reporter: ibuclaw at gdcproject dot org Target Milestone: --- Currently, the following have equivalents with the c-family front-ends. asm { ""; } -> asm __volatile__ (""); asm pure { ""; } -> asm (""); In the case of 'asm pure' the result can be cached, with duplicated statements being DCE'd. This happens in the std.math unittests when compiling with -O2. The example below distils what the test looks like after inlining. The last asm statement is removed, and the first result is reused, which produces wrong run-time results. The use of 'asm pure' is in line with expectations however, particularly as the getters are 'pure' in the D sense. Either will have to say that every asm statement is volatile, or will have to apply a stricter condition. In C, asm statements without output operands are automatically considered volatile, but that won't help us here. --- import core.stdc.fenv; enum ROUNDING_MASK = FE_TONEAREST|FE_DOWNWARD|FE_UPWARD|FE_TOWARDZERO; void main() { uint newMode = FE_DOWNWARD; fexcept_t oldState; asm pure { "fstcw %0;" : "=m" (oldState); } fexcept_t newState = cast(fexcept_t)((oldState & (-1 - ROUNDING_MASK)) | (newMode & ROUNDING_MASK)); asm { "fclex; fldcw %0;" : : "m" (newState); } uint mxcsr; asm { "stmxcsr %0" : "=m" (mxcsr); } mxcsr &= ~(ROUNDING_MASK << 3); mxcsr |= (newState & ROUNDING_MASK) << 3; mxcsr &= ~(FE_ALL_EXCEPT << 7); mxcsr |= (newState & FE_ALL_EXCEPT) << 7; asm { "ldmxcsr %0" : : "m" (mxcsr); } fexcept_t contState; asm pure { "fstcw %0;" : "=m" (contState); } assert(cast(uint)(contState & ROUNDING_MASK) == FE_DOWNWARD); }