https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86340
Bug ID: 86340
Summary: GCC 8.1 produces broken code for m68k with
optimization levels above -O1
Product: gcc
Version: 8.1.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: kalamatee at gmail dot com
Target Milestone: ---
Compiling the following file for AROS m68k using gcc 8.1 produces broken code
-:
https://github.com/ezrec/AROS-mirror/blob/ABI_V1/AROS/rom/graphics/finddisplayinfo.c
Default command line used -:
m68k-aros-gcc -iquote
/mnt/NAS/PC/AROS/branches/ABI_V1-Clean/src/rom/graphics/./ -iquote
/mnt/NAS/PC/AROS/branches/ABI_V1-Clean/src/rom/graphics -iquote . -Os
-fno-strict-aliasing -ffreestanding -fomit-frame-pointer -fbuiltin -Wall
-Werror -Wno-pointer-sign -Wno-parentheses -Wno-volatile-register-var -g
-D__UTILITY_RELLIBBASE__ -D__OOP_RELLIBBASE__ -fno-ipa-cp
-I/mnt/NAS/PC/AROS/branches/ABI_V1-Clean/src/rom/cgfx
-DAROS_BUILD_TYPE=AROS_BUILD_TYPE_PERSONAL -DNOLIBINLINE -DADEBUG=1 -DMDEBUG=1
-D__OOP_NOMETHODBASES__
-I/home/test/amiga-m68k-gcc8/bin/amiga-m68k/gen/rom/graphics/graphics/include
-include
/home/test/amiga-m68k-gcc8/bin/amiga-m68k/gen/rom/graphics/graphics/include/graphics_deflibdefs.h
-D__SRCFILENAME__=\"rom/graphics/finddisplayinfo.c\" -c
/mnt/NAS/PC/AROS/branches/ABI_V1-Clean/src/rom/graphics/./finddisplayinfo.c -o
/home/test/amiga-m68k-gcc8/bin/amiga-m68k/gen/rom/graphics/graphics/finddisplayinfo.o
Only optimization levels of -O0 or -O1 produce valid results.
The broken code is as follows -:
00000000 <Graphics_121_FindDisplayInfo>:
0: 2f0e movel %fp,%sp@-
2: 2f02 movel %d2,%sp@-
4: 5280 addql #1,%d0
6: 6732 beqs 3a <Graphics_121_FindDisplayInfo+0x3a>
8: 206e 0224 moveal %fp@(548),%a0
c: b0fc 0000 cmpaw #0,%a0
10: 6608 bnes 1a <Graphics_121_FindDisplayInfo+0x1a>
12: 2008 movel %a0,%d0
14: 241f movel %sp@+,%d2
16: 2c5f moveal %sp@+,%fp
18: 4e75 rts
1a: 2228 0008 movel %a0@(8),%d1
1e: 2401 movel %d1,%d2
20: c480 andl %d0,%d2
22: b4a8 0004 cmpl %a0@(4),%d2
26: 6716 beqs 3e <Graphics_121_FindDisplayInfo+0x3e>
28: 2050 moveal %a0@,%a0
2a: 60e0 bras c <Graphics_121_FindDisplayInfo+0xc>
2c: b081 cmpl %d1,%d0
2e: 67e2 beqs 12 <Graphics_121_FindDisplayInfo+0x12>
30: 5088 addql #8,%a0
32: 2210 movel %a0@,%d1
34: 74ff moveq #-1,%d2
36: b481 cmpl %d1,%d2
38: 66f2 bnes 2c <Graphics_121_FindDisplayInfo+0x2c>
3a: 91c8 subal %a0,%a0
3c: 60d4 bras 12 <Graphics_121_FindDisplayInfo+0x12>
3e: 4681 notl %d1
40: c081 andl %d1,%d0
42: 41e8 0036 lea %a0@(54),%a0
46: 60ea bras 32 <Graphics_121_FindDisplayInfo+0x32>
It is broken because 0x00000004/0x00000006 performs an addql to d0 to determine
if ID == INVALID_ID, when ID != INVALID_ID it ends up at 0x0000001a which
performs andl against the modified d0, rather than its original value -
resulting in the function never finding the correct entry.
GCC 6.x produces correct code, however I am unable to test if this regression
was introduced with GCC 7 or GCC 8.