View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0000453 | mercury | Bug | public | 2018-03-09 15:57 | 2018-03-16 15:15 | ||||||||
Reporter | wangp | ||||||||||||
Assigned To | |||||||||||||
Priority | normal | Severity | crash | Reproducibility | always | ||||||||
Status | new | Resolution | open | ||||||||||
Product Version | |||||||||||||
Target Version | Fixed in Version | ||||||||||||
Summary | 0000453: asm_fast does not work with gcc 5.4 | ||||||||||||
Description | One of the test cases (of many) which crash is hard_coded/bit_buffer_test. This configuration crashes: Ubuntu 16.04 i386 gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9) Mercury rotd 2016-02-18 and rotd 2018-03-07 asm_fast.gc (none.gc, reg.gc, hlc.gc are OK) | ||||||||||||
Tags | No tags attached. | ||||||||||||
Attached Files |
|
Notes | |
wangp (developer) 2018-03-13 14:23 |
The previous configuration (gcc 5.4.0, asm_fast.gc, x86) passes bootcheck if the Mercury libraries are statically linked, i.e. ./configure --disable-dynamic-link |
wangp (developer) 2018-03-15 12:57 |
I can reproduce a crash more simply with a call to string.count_codepoints/2. I've copied that predicate to a separate module for ease of debugging, and generated the assembly with mmake string2.pic_s. Then we can edit the assembly and create libmer_std.so with: as -g string2.pic_s -o string2.pic_o && mmake libmer_std.so This is the start of string2.count_codepoints: .globl _entry_mercury__string2__count_codepoints_2_0 .type _entry_mercury__string2__count_codepoints_2_0,@function _entry_mercury__string2__count_codepoints_2_0: call 0f 0: popl %ebx addl $_GLOBAL_OFFSET_TABLE_+[.-0b],%ebx # 0 "" 2 .LDL1: #NO_APP .L4: movl -12(%ebp), %ebx leal .L5@GOTOFF(%ebx), %eax .LBB2: .loc 1 281 0 movl MR_engine_base@GOT(%ebx), %eax movl 8(%eax), %ecx ... The four lines beginning with "call 0f" are due to MR_INLINE_ASM_FIXUP_REGS, to (as I understand it) load the position of the code into ebx. Right afterwards, gcc has added an instruction to copy something off the stack into ebx (presumably it would have stashed the correct value on the stack, but we've jumped into the middle of a C function). Inserting an instruction "movl %ebx, -12(%ebp)" to cancel out that instruction makes this particular predicate work, so I think this is on the right track. |
wangp (developer) 2018-03-15 14:59 |
On the other hand... x86 usage is only decreasing, linking with Mercury shared libraries is not very important, and inter-function jumps were never officially supported by gcc anyway. Maybe it is time to drop support for the combination? |
juliensf (administrator) 2018-03-15 16:14 |
If you disable optimization in GCC (e.g. -O0) does the problem still occur? |
wangp (developer) 2018-03-15 16:26 |
It works at -O0, but not -O1, and not at -O1 with -f* options I could find disabled (everything listed by "gcc -O1 -Q --help=optimizers"). |
wangp (developer) 2018-03-15 16:40 |
My guess is that it is related to this change in GCC 5.0: https://software.intel.com/en-us/blogs/2014/12/26/new-optimizations-for-x86-in-upcoming-gcc-50-32bit-pic-mode https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54232 Previously EBX was reserved for the GOT address so GCC probably had no need to save/restore it. If EBX can be used for other purposes then GCC might try to restore a value from the stack after our inline asm. The question is how to convince GCC not to do that. |
wangp (developer) 2018-03-15 17:04 |
(convince GCC not to restore the GOT address from the stack, not only directly after the MR_INLINE_ASM_FIXUP_REGS sequence) |
juliensf (administrator) 2018-03-15 17:11 |
You could try starting at -O0 and adding optimizations. (Past experience of this kind of thing indicates that GCC is not entirely truthful about which optimizations it applies at which optimization level.) |
wangp (developer) 2018-03-16 15:15 |
Ok, bootcheck still passes with these options (which are what gcc reports as being enabled by -O1): -fbranch-count-reg -fcombine-stack-adjustments -fcompare-elim -fcprop-registers -fforward-propagate -fguess-branch-probability -fif-conversion -fif-conversion2 -finline-functions-called-once -fipa-profile -fipa-pure-const -fipa-reference -freorder-blocks -fshrink-wrap -fsplit-wide-types -fssa-phiopt -ftree-bit-ccp -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-coalesce-vars -ftree-copy-prop -ftree-dce -ftree-dse -ftree-fre -ftree-pta -ftree-sink -ftree-slsr -ftree-sra -ftree-ter Regardless, gcc 5 and up do not use a fixed PIC register on x86. Jumping into the middle of a function and putting the GOT address into EBX is not going to work if the rest of the function is not expecting it there. |
Issue History | |||
Date Modified | Username | Field | Change |
---|---|---|---|
2018-03-09 15:57 | wangp | New Issue | |
2018-03-13 14:23 | wangp | Note Added: 0000976 | |
2018-03-15 12:57 | wangp | Note Added: 0000988 | |
2018-03-15 14:59 | wangp | Note Added: 0000989 | |
2018-03-15 16:14 | juliensf | Note Added: 0000990 | |
2018-03-15 16:26 | wangp | Note Added: 0000991 | |
2018-03-15 16:40 | wangp | Note Added: 0000992 | |
2018-03-15 17:04 | wangp | Note Added: 0000993 | |
2018-03-15 17:11 | juliensf | Note Added: 0000994 | |
2018-03-16 15:15 | wangp | Note Added: 0000995 |