https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126310
Bug ID: 126310
Summary: [16 regression] Miscompile due to erroneous value
range propagation
Product: gcc
Version: 16.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: engelke at in dot tum.de
CC: mjambor at suse dot cz
Target Milestone: ---
When optimizing, GCC in some cases wrongly infers the value range of member
function pointer __delta as zero. Regressed in GCC 16, reproduced on GCC 16.1
and recent trunk, bisected to 27d9cefeebc2551b6756ef372b80bf03243ad5f.
Reproducer:
// g++ -O2 -std=gnu++20 -Wall -Wextra -Wpedantic -S -o - -c repro.ii
int compile_inst;
template <typename Derived> struct CompilerBase {
class ValuePart {};
};
bool compile_intrin_zero_is_poison;
template <typename Derived>
struct LLVMCompilerBase : CompilerBase<Derived> {
using Base = CompilerBase<Derived>;
virtual void compile_call(Derived &__trans_tmp_4) {
using EncodeFnTy = bool (Derived::*)(typename Base::ValuePart &&);
static constexpr EncodeFnTy encode_fns[]{&Derived::encode_ctlzi8,
&Derived::encode_ctlzi8};
(&__trans_tmp_4->*encode_fns[compile_intrin_zero_is_poison])(
typename Base::ValuePart());
}
};
struct LLVMCompilerX64;
struct EncodeCompiler {
using CompilerX64 = ::CompilerBase<LLVMCompilerX64>;
using ValuePart = CompilerX64::ValuePart;
bool encode_ctlzi8(ValuePart &&);
int symbols;
};
struct LLVMCompilerX64 : LLVMCompilerBase<LLVMCompilerX64>, EncodeCompiler {
} __trans_tmp_5;
When optimizing, GCC 16 performs the member function pointer call on
__trans_tmp_4 without adjusting the object pointer by 8 (evrp erroneously
infers range [0, 0]).
GCC 16 assembly
.cfi_startproc
subq $24, %rsp
.cfi_def_cfa_offset 32
movzbl compile_intrin_zero_is_poison(%rip), %eax
leaq
_ZZN16LLVMCompilerBaseI15LLVMCompilerX64E12compile_callERS0_E10encode_fns(%rip),
%rdx
movq %fs:40, %rdi
movq %rdi, 8(%rsp)
movq %rsi, %rdi ; <==== rdi = rsi, no adjustment
salq $4, %rax
movq (%rdx,%rax), %rax
testb $1, %al
je .L2
movq (%rdi), %rdx
movq -1(%rdx,%rax), %rax
.L2:
leaq 7(%rsp), %rsi
call *%rax
; ...
Clang assembly
.cfi_startproc
# %bb.0:
subq $24, %rsp
.cfi_def_cfa_offset 32
movq %fs:40, %rax
movq %rax, 16(%rsp)
leaq 8(%rsi), %rdi ; <==== rdi = rsi + 8
leaq 15(%rsp), %rsi
callq
_ZN14EncodeCompiler13encode_ctlzi8EON12CompilerBaseI15LLVMCompilerX64E9ValuePartE@PLT