https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63347
Bug ID: 63347 Summary: m68k misoptimisation with -fschedule-insns Product: gcc Version: 4.7.4 Status: UNCONFIRMED Severity: major Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: jifl-bugzilla at jifvik dot org The following minimal test case (derived from much larger code) demonstrates a problem which I could reproduce on m68k-elf-gcc 4.7.4. It can be built with simply: m68k-elf-gcc -c -O1 -fschedule-insns foo.c extern int printf(const char *fmt, ...); int print_info(unsigned int *ip_addr) { int invalid = 0; if (ip_addr) { unsigned int haddr = *ip_addr; printf("%d.%d.%d.%d", (int)((haddr >> 24) & 0xff), (int)((haddr >> 16) & 0xff), (int)((haddr >> 8) & 0xff), (int)((haddr >> 0) & 0xff)); if (0x0 == haddr) { invalid = 1; } printf("\n"); } else { invalid = 1; } return invalid; } The problem manifests with the 'tstl' instruction corresponding to the 'if (0x0==haddr)' simply disappearing, resulting in an incorrect return value. Here's the relevant section of asm for a working version (without -fschedule-insns): 48: 4fef 0014 lea %sp@(20),%sp 4c: 4a82 tstl %d2 4e: 57c2 seq %d2 50: 49c2 extbl %d2 52: 4482 negl %d2 54: 4879 0000 0000 pea 0 <print_info> 56: R_68K_32 .rodata.str1.1+0xc %d2 is later moved to %d0 to give the return value. and for a broken version: 4c: 4fef 0014 lea %sp@(20),%sp 50: 4879 0000 0000 pea 0 <print_info> 52: R_68K_32 .rodata.str1.1+0xc 56: 57c2 seq %d2 58: 49c2 extbl %d2 5a: 4482 negl %d2 The 'tstl' insn is gone! If you want to make this an executable, I added on the following which demonstrates the problem: int main(int argc, char *argv[]) { unsigned int myaddr; int ret; myaddr = 0x0; ret = print_info(&myaddr); if (!ret) printf("FAIL: addr 0 returned %d\n", ret); myaddr = 0x01020304; ret = print_info(&myaddr); if (ret) printf("FAIL: addr 1234 returned %d\n", ret); return 0; } This worked in gcc 4.4.5, but I haven't tried 4.5 or 4.6. Of course other changes in the optimizer would probably perturb things enough that this code wouldn't trigger it any more with different gcc versions (including 4.8 or 4.9), even if the problem in the compiler still remains.