llvm / llvm-project

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

missed optimization for dead code elimination at -O3 (vs. -O2) #49119

Open zhendongsu opened 3 years ago

zhendongsu commented 3 years ago
Bugzilla Link 49775
Version trunk
OS All
CC @fhahn,@ttheodor

Extended Description

[582] % clangtk -v clang version 13.0.0 (https://github.com/llvm/llvm-project.git 9fb0025f7084db14d16fe5cbe1d799f4ee0020af) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /local/suz-local/opfuzz/bin Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/6.5.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0 Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8 Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/7.5.0 Candidate multilib: .;@m64 Candidate multilib: 32;@m32 Candidate multilib: x32;@mx32 Selected multilib: .;@m64 [583] % [583] % clangtk -O2 -S -o O2.s small.c [584] % clangtk -O3 -S -o O3.s small.c [585] % [585] % wc O2.s O3.s 32 76 770 O2.s 147 415 2958 O3.s 179 491 3728 total [586] % [586] % grep foo O2.s [587] % grep foo O3.s callq foo [588] % [588] % cat small.c

extern void foo(void);
static int b, c, *d = &b, *e = &b;
char *f;
int h;
static void g() { b = h; }
int main() {
  int i = 0;
  while (i < 2)
    i++;
  if (!(i ^ *e)) {
    foo();
    g();
    for (c = 0; c < 50; c++)
      *f = 0;
  }
  *d = 0;
}
zhendongsu commented 3 years ago

Bisects to commit https://github.com/llvm/llvm-project/commit/fb109c42d91c30c8c7497ef1fd7aff6f2969c6e7

Before the commit, neither -O2 nor -O3 removes the dead call to foo. After the commit, -O2 removes the call, but -O3 does not.

fhahn commented 2 years ago

Still reproduces: https://clang.godbolt.org/z/v14cMd7x6

fhahn commented 2 years ago

The issue here is that with -O3 LLVM unrolls the 50 loop iterations and after that there are too many stores between 2 stores to b that it cannot be removed, due to running into a limit on the number of steps for walking MemorySSA.

By increasing this limit (using -mllvm -dse-memoryssa-walklimit=300) we get the same result as with -O2: https://clang.godbolt.org/z/Gbe4r53K7

But just increasing the limit is not the proper solution to fix this unfortunately.