llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.69k stars 11.86k forks source link

[clang/c++] Very strange/bad optimizer behavior. #89699

Open no-more-secrets opened 6 months ago

no-more-secrets commented 6 months ago

Problem demo: https://godbolt.org/z/zfMohEMj7

The "good" variant produces perfectly optimized code, while the nearly-identical "bad" variant produces a giant explosion of seemingly unoptimized code.

static int len( char const* input ) {
  return std::string( input ).size();
}

int test() {
  return
    #ifdef GOOD
      len( "h" ) + len( "h" );
    #else /*BAD*/
      len( "h" ) + len( "" );
    #endif
}

This (regression?) happened between Clang versions 13 and 14: https://godbolt.org/z/brhYEK4Eh

The problem does not exist in gcc: https://godbolt.org/z/Ed6z6j61a

dtcxzyw commented 6 months ago

Seems like it is an inlining heuristics problem: https://godbolt.org/z/GxqnYfr1j

DimitryAndric commented 6 months ago

It's interesting that it doesn't happen on FreeBSD at all, which is probably because we use libc++, not libstdc++:

$ clang -std=c++20 -O3 -S pr89699.cpp -o -
...
_Z4testv:                               # @_Z4testv
        .cfi_startproc
# %bb.0:
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset %rbp, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register %rbp
        movl    $1, %eax
        popq    %rbp
        .cfi_def_cfa %rsp, 8
        retq
.Lfunc_end0:
        .size   _Z4testv, .Lfunc_end0-_Z4testv
        .cfi_endproc
aokblast commented 2 months ago

I have the same issue on FreeBSD as @no-more-secrets.