[Bug target/63347] New: m68k misoptimisation with -fschedule-insns
jifl-bugzilla at jifvik dot org
gcc-bugzilla@gcc.gnu.org
Tue Sep 23 20:50:00 GMT 2014
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.
More information about the Gcc-bugs
mailing list