[Bug c/94075] New: When using linker-generated list, bad optimization performed in -O2
fabrice.girardot at flowbird dot group
gcc-bugzilla@gcc.gnu.org
Fri Mar 6 15:42:00 GMT 2020
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94075
Bug ID: 94075
Summary: When using linker-generated list, bad optimization
performed in -O2
Product: gcc
Version: 5.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: fabrice.girardot at flowbird dot group
Target Milestone: ---
Created attachment 47992
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=47992&action=edit
Test case + Makefile to reproduice bug
GCC does a wrong optimization in -O2 when using linker-generated lists, when
such a list is empty.
Linker-generated lists are convenient to automatically group items at link
time.
A 0-sized item array is located at start of list (section ".foo_1").
A 0-sized item array is located at end of list (section ".foo_3").
All other items with section ".foo_2" will automatically be located between the
top and bottom tags.
When there is *NO* item with section ".foo_2", the list is empty, the start and
end addresses are the same.
When compiling with "-O2", gcc assumes start and end addresses can't be equal,
and always enter the for() loop in the attached example.
If attached example is compiled with "-O0" (please edit Makefile), then
generated code is correct.
This bug was found on arm-none-eabi-gcc version 6.2.1 with a real linker script
for STM32 micro-controller, and the result is an embedded hard fault.
For convenient testing under Linux, the Makefile in the attached zip file
automatically generates a linker script to add a section for linker-generated
lists.
==================================
Correct output result (example compiled with -O0):
----------------------------------
$ make clean && make
rm -rf output
gcc -dumpversion
5.4.0
gcc -c -std=c99 -O0 -DOPTIMIZE="\"-O0\"" -o output/main.o src/main.c
ld --verbose \
| sed -n '/===/,$p' \
| sed '/===/d' \
| sed -e '/.rodata[ ]*:/a .foobar : { KEEP(*(SORT(.foo_*))); } ' \
> output/test.ld
gcc -Wl,-Map=output/test.map -T output/test.ld -o output/test output/main.o
$ output/test
I am compiled with '-O0' !
start = 0x4006a0
end = 0x4006a0
==================================
Wrong optimization (example compiled with -O2)
----------------------------------
$ make clean && make
rm -rf output
gcc -dumpversion
5.4.0
gcc -c -std=c99 -O2 -DOPTIMIZE="\"-O2\"" -o output/main.o src/main.c
ld --verbose \
| sed -n '/===/,$p' \
| sed '/===/d' \
| sed -e '/.rodata[ ]*:/a .foobar : { KEEP(*(SORT(.foo_*))); } ' \
> output/test.ld
gcc -Wl,-Map=output/test.map -T output/test.ld -o output/test output/main.o
$ output/test
I am compiled with '-O2' !
start = 0x400680
end = 0x400680
[0] p = 0x400680 ; *p = 0
[1] p = 0x400684 ; *p = 52
[2] p = 0x400688 ; *p = 5
[3] p = 0x40068c ; *p = -736
[4] p = 0x400690 ; *p = 128
[5] p = 0x400694 ; *p = -672
[6] p = 0x400698 ; *p = 168
[7] p = 0x40069c ; *p = -480
[8] p = 0x4006a0 ; *p = 80
[9] p = 0x4006a4 ; *p = -224
Aborting...
==================================
More information about the Gcc-bugs
mailing list