https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85805
Bug ID: 85805 Summary: Improper code generation for 64 bit comparisons on avr-gcc Product: gcc Version: 4.8.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: sandor.zsuga at jubatian dot com Target Milestone: --- GCC version: avr-gcc (GCC) 4.8.1 Compiling with either -O1 or -O2 optimizations enabled, tested with some ATMega and XMega targets. Test case: #include <stdint.h> uint8_t volatile tmp; __attribute__((noinline)) void test_64(uint64_t d64) { if ((d64 & 0xFF800000UL) == 0xFF800000UL){ tmp ++; } } __attribute__((noinline)) void test_32(uint32_t d32) { if ((d32 & 0xFF800000UL) == 0xFF800000UL){ tmp ++; } } int main(void) { test_64(0); test_32(0); while(1); } A cut from the output assembly, showing the critical part (the code generated for test_64, test_32 and main): 00000228 <test_64>: 228: 08 95 ret 0000022a <test_32>: 22a: 66 27 eor r22, r22 22c: 77 27 eor r23, r23 22e: 80 78 andi r24, 0x80 ; 128 230: 61 15 cp r22, r1 232: 71 05 cpc r23, r1 234: 80 48 sbci r24, 0x80 ; 128 236: 9f 4f sbci r25, 0xFF ; 255 238: 09 f0 breq .+2 ; 0x23c <test_32+0x12> 23a: 08 95 ret 23c: 80 91 00 20 lds r24, 0x2000 240: 8f 5f subi r24, 0xFF ; 255 242: 80 93 00 20 sts 0x2000, r24 246: 08 95 ret 00000248 <main>: 248: 20 e0 ldi r18, 0x00 ; 0 24a: 30 e0 ldi r19, 0x00 ; 0 24c: 40 e0 ldi r20, 0x00 ; 0 24e: 50 e0 ldi r21, 0x00 ; 0 250: 60 e0 ldi r22, 0x00 ; 0 252: 70 e0 ldi r23, 0x00 ; 0 254: 80 e0 ldi r24, 0x00 ; 0 256: 90 e0 ldi r25, 0x00 ; 0 258: 0e 94 14 01 call 0x228 ; 0x228 <test_64> 25c: 60 e0 ldi r22, 0x00 ; 0 25e: 70 e0 ldi r23, 0x00 ; 0 260: cb 01 movw r24, r22 262: 0e 94 15 01 call 0x22a ; 0x22a <test_32> 266: ff cf rjmp .-2 ; 0x266 <main+0x1e> It seems like the compiler incorrectly determines that the "if" is always false in the 64 bit case, and produces a corresponding result (a function doing nothing). A native version of GCC produces the expected code (the comparison being performed).