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.

Reply via email to