llvm / llvm-project

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

Wrong code at -O1 on x86_64-linux_gnu (InstComine) #64259

Closed shao-hua-li closed 1 year ago

shao-hua-li commented 1 year ago

This is a recent regression. Clang at -O1 produces the wrong code.

Bisect to https://github.com/llvm/llvm-project/commit/ad7f02010f32bff28fec139e103ad0240e160aa9, which was committed by @nikic

Compiler explorer: https://godbolt.org/z/ze8b3KcKs

% cat a.c
int printf(const char *, ...);
int a, b, d, f, h;
static int c = 8;
static int e = 1;
char g;
void l(int *m) {
  if (f) {
    e = 0;
    for (;;) {
      h = 0;
      for (; h;)
        ;
    }
  }
}
int main() {
  int *i = &c;
  l(i);
  if (c)
  j:
  k:;
    else {
      ;
      if (e)
        goto j;
    }
  g = b;
  if (b)
    goto k;
  printf("%d\n", a);
}
%
% clang -O0 a.c &&./a.out
0
% clang -O1 a.c &&./a.out
%
nikic commented 1 year ago

Reduced:

define void @test() {
entry:
  br i1 false, label %loop2, label %loop1

loop1:
  br label %loop2

loop2:
  br i1 true, label %exit, label %loop1

exit:
  call void @dummy()
  ret void
}

declare void @dummy()

Presumably the LiveBlocks logic isn't correct for irreducable loops.