https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67736
Bug ID: 67736 Summary: Wrong optimization with -fexpensive-optimizations on mips64el Product: gcc Version: 5.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: aurelien at aurel32 dot net Target Milestone: --- Host: mips64el-unknown-linux-gnu Target: mips64el-unknown-linux-gnu Build: mips64el-unknown-linux-gnu The following code is wrongly compiled on a mips64el target when using -fexpensive-optimizations: #include <inttypes.h> #include <stdio.h> int compare(uint64_t state, uint32_t *last, uint8_t buf) { if (*last == ((state | buf) & 0xFFFFFFFF)) { printf("B %"PRIx64" %"PRIx32"\n", state, *last); return 0; } return 1; } It produces the following code: 00000000000009a0 <compare>: 9a0: 30c200ff andi v0,a2,0xff 9a4: 8ca60000 lw a2,0(a1) 9a8: 00441025 or v0,v0,a0 9ac: 10460004 beq v0,a2,9c0 <compare+0x20> 9b0: 24020001 li v0,1 9b4: 03e00008 jr ra 9b8: 00000000 nop 9bc: 00000000 nop ... Note how the comparison is done incorrectly, dropping the & 0xFFFFFFFF and sign-extending the value when loading *last. Using -fno-expensive-optimizations produces the following valid code: 00000000000009a0 <compare>: 9a0: 30c200ff andi v0,a2,0xff 9a4: 8ca60000 lw a2,0(a1) 9a8: 00441025 or v0,v0,a0 9ac: 7cc3f803 dext v1,a2,0x0,0x20 9b0: 7c42f803 dext v0,v0,0x0,0x20 9b4: 10620004 beq v1,v0,9c8 <compare+0x28> 9b8: 24020001 li v0,1 9bc: 03e00008 jr ra 9c0: 00000000 nop 9c4: 00000000 nop 9c8: 67bdfff0 daddiu sp Here both values are zero extended to 32-bit before the comparison. Alternatively, when removing the line with the printf, GCC also produces correct code, which is more optimized: 0000000000000960 <compare>: 960: 30c600ff andi a2,a2,0xff 964: 00c42025 or a0,a2,a0 968: 9ca20000 lwu v0,0(a1) 96c: 7c86f803 dext a2,a0,0x0,0x20 970: 00c21026 xor v0,a2,v0 974: 03e00008 jr ra 978: 0002102b sltu v0,zero,v0 97c: 00000000 nop Note that at least gcc 4.8.5, 4.9.3 and 5.2.1 are affected.