https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86617
Bug ID: 86617 Summary: Volatile qualifier is ignored sometimes for unsigned char Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: yso at melexis dot com Target Milestone: --- I'm using http://gcc.godbolt.org/ to reproduce this issue. Compiler: x86-64 gcc (trunk); gcc (GCC-Explorer-Build) 9.0.0 20180719 Options: -Os Test code: ``` volatile unsigned char u8; void test (void) { u8 = u8 + u8; u8 = u8 - u8; } ``` Disassembly: ``` test: mov al, BYTE PTR u8[rip] add eax, eax mov BYTE PTR u8[rip], al mov al, BYTE PTR u8[rip] mov BYTE PTR u8[rip], 0 ret ``` In the addition expression `u8 + u8`, volatile variable u8 is copied to the register only once and then register is doubled. This seems incorrect, as volatile variable shall be read out from the memory also for the second term of the sum. In the subtraction expression `u8 - u8`, result (0) is calculated at compile time without explicit subtraction. Also can be reproduced in: - x86-64 gcc 8.1; gcc (GCC-Explorer-Build) 8.1.0 - x86-64 gcc 7.3; gcc (GCC-Explorer-Build) 7.3.0 - x86-64 gcc 6.3; gcc (GCC-Explorer-Build) 6.3.0 - x86-64 gcc 5.4; gcc (GCC-Explorer-Build) 5.4.0 When g++ is used to compile the same code, everything is fine! Compiler: x86-64 gcc (trunk); g++ (GCC-Explorer-Build) 9.0.0 20180719 Options: -Os Disassembly: ``` _Z3foov: mov al, BYTE PTR u8[rip] mov dl, BYTE PTR u8[rip] add eax, edx mov BYTE PTR u8[rip], al mov al, BYTE PTR u8[rip] mov dl, BYTE PTR u8[rip] sub eax, edx mov BYTE PTR u8[rip], al ret u8: .zero 1 ```