LTO ignores -fno-short-enums

Bug #1315810 reported by Joey Ye
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Fix Released
Low
Hale Wang

Bug Description

Hi,

I am trying to partially link a project into a single object file, that I will later archive into a static library. The object file needs to be linked against code generated with full-sized enums.

I am passing -fno-short-enums when compiling all object files.

I'd like to enable link-time optimization while performing the partial link step.

If I build the project with -flto, then the output file has the Tag_ABI_enum_size = small elf attribute. Leaving out -flto is enough to get a Tag_ABI_enum_size = int attribute.

I was able to boil the issue down to a minimal example. I have two trivial source files

obj1.cc:

    int x(int y)
    {
        return y - 10;
    }

obj2.cc:

    int foo(int bar)
    {
        return bar*10;
    }

and I compile each source file using

    $ arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s -c obj1.cc -o obj1.o -Os -flto -nostdlib
    $ arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s -c obj2.cc -o obj2.o -Os -flto -nostdlib

If I link them without -flto, link time optimization is not invoked, and I get an object file marked as having int-sized enums:

    $ arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s obj1.cc obj2.cc -Wl,-Ur -o partial_link_result.o -nostdlib -Os
    $ arm-none-eabi-readelf.exe -a partial_link_result.o | grep enum
      Tag_ABI_enum_size: int

But if I simply add -flto to the linker invocation, the output claims that it has small enums:

    $ arm-none-eabi-g++.exe -fno-short-enums -mcpu=arm946e-s obj1.cc obj2.cc -Wl,-Ur -o partial_link_result.o -nostdlib -Os -flto
    $ arm-none-eabi-readelf.exe -a partial_link_result.o | grep enum
      Tag_ABI_enum_size: small

If I run the link step with `-v`, I can see this when gcc gets to the lto stage:

Thread model: single
gcc version 4.8.3 20140228 (release) [ARM/embedded-4_8-branch revision 208322] (GNU Tools for ARM Embedded Processors)
COLLECT_GCC_OPTIONS='-c' '-fexceptions' '-mcpu=arm946e-s' '-mcpu=arm946e-s' '-nostdlib' '-Os' '-v' '-dumpdir' './' '-dumpbase' 'partial_link_result.o.ltrans0' '-fltrans' '-o' '/tmp/ccOd77GF.ltrans0.ltrans.o'
 /usr/bin/../lib/gcc/arm-none-eabi/4.8.3/lto1 -quiet -dumpdir ./ -dumpbase partial_link_result.o.ltrans0 -mcpu=arm946e-s -mcpu=arm946e-s -auxbase-strip /tmp/ccOd77GF.ltrans0.ltrans.o -Os -version -fexceptions -fltrans @/tmp/ccCixY4J -o /tmp/ccnQeRsb.s

It sure looks to me like something removed `-fno-short-enums` from `COLLECT_GCC_OPTIONS` during the LTO step. I have reproduced the same behavior on several different gcc 4.8 distributions (Mentor's Sourcery 4.8.1, Ubuntu's 4.8.2, and now the gcc-arm-embedded 4.8.3).

Is this a bug? How can I use gcc's link-time optimization while generating code without short enums?

Thanks,
Bobby

Joey Ye (jinyun-ye)
Changed in gcc-arm-embedded:
status: New → Confirmed
importance: Undecided → Low
Joey Ye (jinyun-ye)
Changed in gcc-arm-embedded:
assignee: nobody → Hale Wang (hale.wang)
Revision history for this message
Joey Ye (jinyun-ye) wrote :

Created bug record in GCC bug tracking system: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=61123

Changed in gcc-arm-embedded:
status: Confirmed → In Progress
milestone: none → 4.9-2014-q4-major
Revision history for this message
Hale Wang (hale.wang) wrote :

The reason is that: if we add -flto option, link time optimization is invoked. And the lto need to call the function run_gcc(unsigned argc, char *argv[]) in lto-wrapper.c. The options in *argv[] are filtered by the following commands:
    if(!(cl_options[option->opt_index].flags & (CL_COMMON | CL_TARGET | CL_DRIVER | CL_LTO)))
      continue;
So all the options which do not belong to the CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO groups will be ignored by LTO. And -fno-short-enums is one of these options.

I think it is a bug of LTO. Because the option flag_short_enums can change the enum size in the generated object file. We should allow the users to disable this optimization as they like.

I suggest we can add the option flag_short_enums to the CL_COMMON group(or CL_LTO group, I am not sure which group is more reasonable). And I have confirmed that this change works.

I have got a command from Richard Biener on GCC Bugzilla: All ABI changing options should be also enabled for LTO and they also deserve handling in lto-opts.c (always stream, not only if explicitely set) and lto-wrapper.c (diagnose mismatches and force a setting for the link stage). At least enabling them for LTO is minimally required, like you suggest.

So I will continue to analyze all the similar options that can change ABI, and add them to the LTO group to solve this problem.

Thanks very much.

Revision history for this message
Bobby Moretti (bobmoretti) wrote :

Thanks so much for tracking this down.

I found another ABI-affecting flag that seems to get dropped during LTO: -fshort-wchar.

I also tried -funsafe-math-optimizations, which also affects the ABI output. This flag seems to get handled correctly by LTO.

Revision history for this message
Hale Wang (hale.wang) wrote :

Hi Bobby,

Yes, you are right. There are several options that are similer with fno-short-enums which can change the ABI. I am overviewing all these options. And I will post my commands about these in the following days.

Thanks for your reminder.

Revision history for this message
Hale Wang (hale.wang) wrote :

Hi Bobby,

This issue is fixed in the gcc patch: https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01429.html.

Thanks and Best Regards,
Hale Wang

Hale Wang (hale.wang)
Changed in gcc-arm-embedded:
status: In Progress → Fix Released
Joey Ye (jinyun-ye)
Changed in gcc-arm-embedded:
status: Fix Released → Fix Committed
Terry Guo (terry.guo)
Changed in gcc-arm-embedded:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Related questions

Remote bug watches

Bug watches keep track of this bug in other bug trackers.