https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127479
Bug ID: 127479
Summary: GCC 15.2 IPA-ICF merges distinct >= and <= comparison
functions under -flto, causing incorrect runtime
behavior
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: lto
Assignee: unassigned at gcc dot gnu.org
Reporter: samk at vulnetic dot ai
Target Milestone: ---
Description
===========
GCC 15.2 produces incorrect executable behavior when IPA-ICF is enabled during
link-time optimization.
The reproducer defines two semantically distinct functions:
- less_equal(-1) returns true
- greater_equal(-1) returns false
When compiled with -Os -flto, GCC reports the functions as semantically equal:
Semantic equality hit:less_equal/1->greater_equal/4
The resulting executable incorrectly prints WRONG. Compiling the same source
with -fno-ipa-icf restores the expected result, strongly indicating that
IPA-ICF incorrectly merges the two functions. The issue reproduces without
warnings using -Wall -Wextra. This reproducer required -Os, but the original
source exhibited the behavior with -O1 through -O3.
Reproducer (reproducer.c)
=========================
extern int puts(const char *);
char false_object;
char true_object;
char *less_equal(long comparison) {
if (comparison == 0) goto return_true;
if (comparison < 0) goto return_true;
goto return_false;
return_true:
return &true_object;
return_false:
return &false_object;
}
char *greater_equal(long comparison) {
if (comparison == 0) goto return_true;
if (comparison < 0) goto return_false;
goto return_true;
return_true:
return &true_object;
return_false:
return &false_object;
}
int main(void) {
volatile long negative = -1;
int correct =
less_equal(negative) == &true_object &&
greater_equal(negative) == &false_object;
puts(correct ? "correct" : "WRONG");
return !correct;
}
Reproduction script (reproduce.sh)
==================================
#!/bin/sh
# GCC 15.2 with -Os -flto incorrectly aliases greater_equal to less_equal.
set -u
cd "$(dirname "$0")"
echo '== GCC version and configuration =='
gcc -v 2>&1
echo
echo '== Failing build: -Os -flto =='
set -x
gcc -Wall -Wextra -Os -flto -save-temps -fdump-ipa-icf-details reproducer.c -o
reproduce-lto
set +x
echo
echo '== Failing program output =='
if ./reproduce-lto; then
echo 'UNEXPECTED: the bug did not reproduce with this compiler.'
failure_reproduced=0
else
echo 'BUG REPRODUCED: the LTO build returned the wrong comparison result.'
failure_reproduced=1
fi
echo
echo '== IPA-ICF diagnostic =='
grep -E 'Semantic equality hit:.*(less_equal|greater_equal)'
reproduce-lto.wpa.*.icf || true
echo
echo '== Control build: disable IPA-ICF =='
set -x
gcc -Wall -Wextra -Os -flto -fno-ipa-icf reproducer.c -o reproduce-no-icf
set +x
if ./reproduce-no-icf; then
echo 'CONTROL PASSED: disabling IPA-ICF restores correct behavior.'
else
echo 'UNEXPECTED: the control build failed.' >&2
exit 1
fi
[ "$failure_reproduced" -eq 1 ]
Observed output
===============
== GCC version and configuration ==
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/15/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 15.2.0-4ubuntu4'
--with-bugurl=file:///usr/share/doc/gcc-15/README.Bugs
--enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust,cobol,algol68
--prefix=/usr --with-gcc-major-version-only --program-suffix=-15
--program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace
--enable-gnu-unique-object --disable-vtable-verify --enable-plugin
--enable-default-pie --with-system-zlib --enable-libphobos-checking=release
--with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch
--disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64
--with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic
--enable-offload-targets=nvptx-none=/build/gcc-15-deiAlw/gcc-15-15.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-15-deiAlw/gcc-15-
15.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver
--enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean
--enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.2.0 (Ubuntu 15.2.0-4ubuntu4)
== Failing build: -Os -flto ==
+ gcc -Wall -Wextra -Os -flto -save-temps -fdump-ipa-icf-details reproducer.c
-o reproduce-lto
+ set +x
== Failing program output ==
WRONG
BUG REPRODUCED: the LTO build returned the wrong comparison result.
== IPA-ICF diagnostic ==
reproducer.c:6:7: optimized: Semantic equality
hit:less_equal/1->greater_equal/4
== Control build: disable IPA-ICF ==
+ gcc -Wall -Wextra -Os -flto -fno-ipa-icf reproducer.c -o reproduce-no-icf
+ set +x
correct
CONTROL PASSED: disabling IPA-ICF restores correct behavior.