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

Reply via email to