tkchia / gcc-ia16

Fork of Lambertsen & Jenner (& al.)'s IA-16 (Intel 16-bit x86) port of GNU compilers ― added far pointers & more • use https://github.com/tkchia/build-ia16 to build • Ubuntu binaries at https://launchpad.net/%7Etkchia/+archive/ubuntu/build-ia16/ • DJGPP/MS-DOS binaries at https://gitlab.com/tkchia/build-ia16/-/releases • mirror of https://gitlab.com/tkchia/gcc-ia16
GNU General Public License v2.0
173 stars 13 forks source link

internal compiler errors while building Doom #144

Closed FrenkelS closed 2 months ago

FrenkelS commented 11 months ago

I'm trying to use this compiler to build Doom for 16-bit DOS computers, but it fails with some internal compiler errors.

Compiling r_draw.c with -O2 gives an error while all the other optimization levels succeed:

ia16-elf-gcc -c r_draw.c -O2
(plus:HI (reg/f:HI 4 d [18])
    (const_int 8 [0x8]))
r_draw.c: In function ‘R_PointOnSide.isra.5’:
r_draw.c:351:1: internal compiler error: output_operand: Invalid or unsupported operand plus (code
 }
 ^
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

Compiling p_mobj.c and p_spec.c succeeds with -O0 and -Og, but gives errors with all the other optimization levels:

ia16-elf-gcc -c p_mobj.c -Ofast
p_mobj.c: In function ‘P_SpawnMobj’:
p_mobj.c:655:15: internal compiler error: in immed_wide_int_const, at emit-rtl.c:606
 mobj_t __far* P_SpawnMobj(fixed_t x,fixed_t y,fixed_t z,mobjtype_t type)
               ^~~~~~~~~~~
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
ia16-elf-gcc -c p_spec.c -Os
p_spec.c: In function ‘P_FindNextHighestFloor’:
p_spec.c:232:9: internal compiler error: in immed_wide_int_const, at emit-rtl.c:606
 fixed_t P_FindNextHighestFloor(sector_t __far* sec)
         ^~~~~~~~~~~~~~~~~~~~~~
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

I can create an executable when I build p_mobj.c and p_spec.c with -O0 and all the other files with -Os, ~but the game fails almost immediately when trying to open Doom1.wad.~ The game is a bit faster than the version that Watcom produces.

LowLevelMahn commented 11 months ago

can't help but just a wow! for your work - what means "a bit faster" what does doom timedemo says?

FrenkelS commented 11 months ago

I've run it in DOSBox at 50000 cycles, Watcom gets about 40 fps, gcc-ia16 50 fps.

Here's a video of Doom8088 compiled with gcc-ia16 on a 386SX at 20 MHz

ghaerr commented 11 months ago

Compiling r_draw.c with -O2 gives an error while all the other optimization levels succeed:

Have you compiled r_draw.c with FixedMul not inlined, as is also done for Watcom C? That might improve the optimization-related problem.

tkchia commented 11 months ago

Hello @FrenkelS,

Thanks for the report. I hope to get around to look at the compiler crashes some time, but no promises.

Thank you!

FrenkelS commented 11 months ago

Compiling r_draw.c with -O2 gives an error while all the other optimization levels succeed:

Have you compiled r_draw.c with FixedMul not inlined, as is also done for Watcom C? That might improve the optimization-related problem.

Well spotted. FixedMul isn't inlined in the case of Watcom, because when the keyword inline is added, other files have linking errors concerning the undefined symbol FixedMul_. That's probably fixable by inlining FixedMul the same way as FixedDiv.

I've removed the keyword 'inline' in front of FixedMul, but I still get the same internal compiler error :(

FrenkelS commented 11 months ago

BTW, I'm also having trouble with some files and -flto. Adding -flto in the build-script to i_main.c, p_map.c or p_switch.c results in

/usr/lib/x86_64-linux-gnu/gcc/ia16-elf/6.3.0/../../../../../ia16-elf/bin/ld: BFD (GNU Binutils) 2.39 internal error, aborting at ../../bfd/linker.c:2204 in _bfd_generic_link_output_symbols

/usr/lib/x86_64-linux-gnu/gcc/ia16-elf/6.3.0/../../../../../ia16-elf/bin/ld: Please report this bug.

collect2: error: ld returned 1 exit status

and adding -flto to z_bmallo.c or z_zone.c results in

lto1: fatal error: target specific builtin not available
compilation terminated.
lto-wrapper: fatal error: ia16-elf-gcc returned 1 exit status
compilation terminated.
/usr/lib/x86_64-linux-gnu/gcc/ia16-elf/6.3.0/../../../../../ia16-elf/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
tkchia commented 11 months ago

Hello @FrenkelS,

Compiling r_draw.c with -O2 gives an error while all the other optimization levels succeed:

I have managed to reproduce this, though I am still not sure why it is happening. Apparently the compiler somehow produced a nonsensical operand of the form %dx + 4 (?) in the output, and tried to output that.

Thank you!

FrenkelS commented 11 months ago

Thanks.

BTW, I've moved some code from p_mobj.c and pspec.c to some other p-files and now both files will compile with -Ofast and -Os. So when you try to reproduce this, make sure you use the versions I linked to instead of the latests ones.

tkchia commented 11 months ago

Hello @FrenkelS,

Roger that, thanks!

The compiler crash on r_draw.c was because one of the optimization passes (IPA SRA) in the GCC middle-end was rewriting the R_PointOnSide function to pass node->x, node->y, node->dx, and node->dy instead of the node pointer itself — this is why the output function was called R_PointOnSide.isra.5. Unfortunately the resulting x, y, dx, and dy parameters were (still) erroneously marked as __far, which confused the IA-16 back-end engine and is probably wrong.

This issue (interaction of optimizations with named address spaces) might also be relevant to mainline GCC. But, later GCC versions seem to have refactored the SRA optimization passes, so I am not sure if they have somehow solved this issue along the way.

I will see if I can get around to looking at the other compiler crashes.

Thank you!

FrenkelS commented 11 months ago

aha, so %dx + 4 wasn't about the register dx :)

tkchia commented 11 months ago

Hello @FrenkelS,

The compiler crashes from p_mobj.c and p_spec.c seem to be triggered by the fact that the routines P_SpawnMobj and P_FindNextHighestFloor being compiled were trying to use 32-bit integers as array indices. This was messing with one of GCC's other optimization passes (IV optimization).

(Using 32-bit array indices is probably not the best thing for 16-bit code to do. But even so, the compiler should probably do something more intelligible, rather than crash...)

Thank you!

FrenkelS commented 10 months ago

BTW, I'm also having trouble with some files and -flto. Adding -flto in the build-script to i_main.c, p_map.c or p_switch.c results in

and adding -flto to z_bmallo.c or z_zone.c results in

lto1: fatal error: target specific builtin not available
compilation terminated.
lto-wrapper: fatal error: ia16-elf-gcc returned 1 exit status
compilation terminated.
/usr/lib/x86_64-linux-gnu/gcc/ia16-elf/6.3.0/../../../../../ia16-elf/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status

That's caused by the usage of FP_OFF / __builtin_ia16_FP_OFF. The builtin part of the error makes a bit more sense now. It's mentioned on the releases page.

FrenkelS commented 10 months ago

Here's another error. When I change -Os to -O3 in the build-script, I get the following error:

z_zone.c: In function ‘Z_Malloc.part.0’:
z_zone.c:532:1: error: could not split insn
 }
 ^
(insn 18 16 19 (set (reg:HI 12 ds [orig:103 largestFreeBlockSize ] [103])
        (reg:HI 12 ds [orig:127 totalFreeMemory ] [127])) z_zone.c:412 12 {*movhi}
     (expr_list:REG_DEAD (reg:HI 0 c [orig:127 totalFreeMemory ] [127])
        (expr_list:REG_EQUAL (const_int 0 [0])
            (nil))))
z_zone.c:532:1: internal compiler error: in final_scan_insn, at final.c:2982
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
lto-wrapper: fatal error: ia16-elf-gcc returned 1 exit status
compilation terminated.
/usr/lib/x86_64-linux-gnu/gcc/ia16-elf/6.3.0/../../../../../ia16-elf/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status

It doesn't happen when I only compile z_zone.c. ia16-elf-gcc -march=i286 -mcmodel=medium -li86 -O3 -fomit-frame-pointer -fgcse-sm -fgcse-las -fipa-pta -ffunction-sections -mregparmcall -flto -fwhole-program -c z_zone.c.

tkchia commented 10 months ago

Hello @FrenkelS,

Hmm, this looks like the RTL for a movw %ds, %ds instruction (or maybe a pushw %ds; popw %ds sequence), which is not very useful. If I have time I hope to look closer into why such an insn is cropping up. Thank you!

FrenkelS commented 10 months ago

BTW, I'm also having trouble with some files and -flto. Adding -flto in the build-script to i_main.c, p_map.c or p_switch.c results in

/usr/lib/x86_64-linux-gnu/gcc/ia16-elf/6.3.0/../../../../../ia16-elf/bin/ld: BFD (GNU Binutils) 2.39 internal error, aborting at ../../bfd/linker.c:2204 in _bfd_generic_link_output_symbols

/usr/lib/x86_64-linux-gnu/gcc/ia16-elf/6.3.0/../../../../../ia16-elf/bin/ld: Please report this bug.

collect2: error: ld returned 1 exit status

FYI, I've solved the problem of p_map.c by moving the variables _g_crushchange, _g_nofit to p_floor.c, the only place where they are used, and making them static.

The problem of i_main.c was solved by making the variables myargc and myargv static in d_main.c and passing them as arguments from main() to D_DoomMain().