https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127610

            Bug ID: 127610
           Summary: 400.perlbench build 40% slower since
                    r17-4133-g230d950810f378 (inefficient LTO
                    partitioning?)
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: compile-time-hog
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: pheeck at gcc dot gnu.org
                CC: pinskia at gcc dot gnu.org
            Blocks: 26163
  Target Milestone: ---
              Host: aarch64-gnu-linux
            Target: aarch64-gnu-linux

Description
-----------

Here's a graph showing this:
https://lnt.opensuse.org/db_default/v4/SPEC/graph?plot.0=588.10.8

Building the SPEC CPU 2006 benchmark 400.perlbench with
r17-4132-ga8c97564fbc39b and with r17-4133-g230d950810f378 with -Ofast
-march=armv8.2-a+crypto+fp16+rcpc+dotprod+ssbs -flto=64 on an Nvidia Grace
(Neoverse V2) machine (the march is replicating an Ampere Altra Neoverse N1
target, where I originally observed this):

rm -f *.o; time make -j$(nproc)
CC=$HOME/gcc/playground/inst-a8c97564fbc/bin/gcc
SPEC=$HOME/gcc/benchmarks/cpu2006/
real    0m3.867s
user    0m46.742s
sys     0m5.938s

rm -f *.o; time make -j$(nproc)
CC=$HOME/gcc/playground/inst-230d950810f378a16c47ab981e0b9cf88b700622/bin/gcc
SPEC=$HOME/gcc/benchmarks/cpu2006/
real    0m5.466s
user    0m47.196s
sys     0m5.988s

That's roughly a 40% slowdown.

The commit in question:
commit 230d950810f378a16c47ab981e0b9cf88b700622
Author:     Andrea Pinski <[email protected]>
AuthorDate: Tue Aug 25 13:28:49 2026 -0700
Commit:     Andrea Pinski <[email protected]>
CommitDate: Thu Sep 10 10:21:17 2026 -0700

    phiopt/cselim: Support constants for cond_store_replacement_limited
[PR127052]


It's in LTO
-----------

Most of the time is spent in the LTO phase.

# rebuild all the .o files with a8c97564fbc, then:
time $HOME/gcc/playground/inst-a8c97564fbc/bin/gcc  -Ofast
-march=armv8.2-a+crypto+fp16+rcpc+dotprod+ssbs -flto=64 -g -fpermissive
-std=gnu17  -DSPEC_CPU_LP64 -DSPEC_CPU_LINUX_X64 -std=gnu89   
-Wl,-rpath,/home/fkastl/gcc/inst/lib64   av.o deb.o doio.o doop.o dump.o
globals.o gv.o hv.o locale.o mg.o numeric.o op.o pad.o perl.o perlapi.o
perlio.o perlmain.o perly.o pp.o pp_ctl.o pp_hot.o pp_pack.o pp_sort.o pp_sys.o
regcomp.o regexec.o run.o scope.o sv.o taint.o toke.o universal.o utf8.o util.o
xsutils.o Base64.o Cwd.o Dumper.o HiRes.o IO.o Peek.o attrs.o poll.o stdio.o
DynaLoader.o MD5.o Storable.o Parser.o specrand.o Hostname.o Opcode.o          
  -lm        -o perlbench

real    0m3.340s
user    0m41.141s
sys     0m3.617s

# rebuild all the .o files with 230d950810f378a16c47ab981e0b9cf88b700622, then:
time $HOME/gcc/playground/inst-230d950810f378a16c47ab981e0b9cf88b700622/bin/gcc
 -Ofast -march=armv8.2-a+crypto+fp16+rcpc+dotprod+ssbs -flto=64 -g -fpermissive
-std=gnu17  -DSPEC_CPU_LP64 -DSPEC_CPU_LINUX_X64 -std=gnu89   
-Wl,-rpath,/home/fkastl/gcc/inst/lib64   av.o deb.o doio.o doop.o dump.o
globals.o gv.o hv.o locale.o mg.o numeric.o op.o pad.o perl.o perlapi.o
perlio.o perlmain.o perly.o pp.o pp_ctl.o pp_hot.o pp_pack.o pp_sort.o pp_sys.o
regcomp.o regexec.o run.o scope.o sv.o taint.o toke.o universal.o utf8.o util.o
xsutils.o Base64.o Cwd.o Dumper.o HiRes.o IO.o Peek.o attrs.o poll.o stdio.o
DynaLoader.o MD5.o Storable.o Parser.o specrand.o Hostname.o Opcode.o          
  -lm        -o perlbench

real    0m4.924s
user    0m41.188s
sys     0m3.384s


It is the objects that matter
-----------------------------

Note that it is not enough to use the newer compiler for LTO. The objects have
to be built by the newer compiler.  Actually, here's an experiment where I
tried to build the .o files with one compiler and LTO them with the other:

230d950810f378a16c47ab981e0b9cf88b700622 lto, a8c97564fbc .o ...
real    0m3.208s
user    0m40.500s
sys     0m3.677s
a8c97564fbc lto, 230d950810f378a16c47ab981e0b9cf88b700622 .o ...
real    0m5.032s
user    0m41.402s
sys     0m3.549s


Doesn't replicate with sequential LTO
-------------------------------------

# rebuild all the .o files with a8c97564fbc, then:
time $HOME/gcc/playground/inst-a8c97564fbc/bin/gcc  -Ofast
-march=armv8.2-a+crypto+fp16+rcpc+dotprod+ssbs -flto -flto-partition=none -g
-fpermissive -std=gnu17  -DSPEC_CPU_LP64 -DSPEC_CPU_LINUX_X64 -std=gnu89   
-Wl,-rpath,/home/fkastl/gcc/inst/lib64   av.o deb.o doio.o doop.o dump.o
globals.o gv.o hv.o locale.o mg.o numeric.o op.o pad.o perl.o perlapi.o
perlio.o perlmain.o perly.o pp.o pp_ctl.o pp_hot.o pp_pack.o pp_sort.o pp_sys.o
regcomp.o regexec.o run.o scope.o sv.o taint.o toke.o universal.o utf8.o util.o
xsutils.o Base64.o Cwd.o Dumper.o HiRes.o IO.o Peek.o attrs.o poll.o stdio.o
DynaLoader.o MD5.o Storable.o Parser.o specrand.o Hostname.o Opcode.o          
  -lm        -o perlbench

real    0m54.082s
user    0m52.273s
sys     0m0.723s

# rebuild all the .o files with 230d950810f378a16c47ab981e0b9cf88b700622, then:
time $HOME/gcc/playground/inst-230d950810f378a16c47ab981e0b9cf88b700622/bin/gcc
 -Ofast -march=armv8.2-a+crypto+fp16+rcpc+dotprod+ssbs -flto
-flto-partition=none -g -fpermissive -std=gnu17  -DSPEC_CPU_LP64
-DSPEC_CPU_LINUX_X64 -std=gnu89    -Wl,-rpath,/home/fkastl/gcc/inst/lib64  
av.o deb.o doio.o doop.o dump.o globals.o gv.o hv.o locale.o mg.o numeric.o
op.o pad.o perl.o perlapi.o perlio.o perlmain.o perly.o pp.o pp_ctl.o pp_hot.o
pp_pack.o pp_sort.o pp_sys.o regcomp.o regexec.o run.o scope.o sv.o taint.o
toke.o universal.o utf8.o util.o xsutils.o Base64.o Cwd.o Dumper.o HiRes.o IO.o
Peek.o attrs.o poll.o stdio.o DynaLoader.o MD5.o Storable.o Parser.o specrand.o
Hostname.o Opcode.o             -lm        -o perlbench

real    0m52.778s
user    0m50.911s
sys     0m0.853s

So here actually the newer compiler seems to be faster.


A theory
--------

One theory could be that we're observing LTO having difficulties distributing
work across partitions evenly.  Notice that the user time in the 'It's in LTO'
section doesn't change.

Maybe this behavior could be analyzed and LTO could be improved?  I'm not sure
about this -- I don't have experience with LTO internals.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=26163
[Bug 26163] [meta-bug] missed optimization in SPEC (2026, 2k17, 2k and 2k6 and
95)

Reply via email to