Hi, all. This code, s.c, is a valid program but makes Clang hung on at compile time at -O1 to -Os. $cat s.c int a; void b() { int *c = &a; int *d = &a; int **e = &d; for (*c = 7; c <= 2; *c += 1) { int **f = d; *c = 0; **e /= f ? (c ? 10 : **f) % (*c &= 6) : 0; } *d = (*d -= *c & **e != 4) && (4 != a) - **e & d == c; int g = &d; g++; } $time clang -c -w -O0 s.c real 0m0.021s user 0m0.011s sys 0m0.010s $clang -c -w -O1 test.cc //endless compiling (the same as -O2,-O3, and -Os options) $clang -v clang version 13.0.0 (https://github.com/llvm/llvm-project 22f00f61dd5483a9fdaed3b7592d392c23b3646a) Target: x86_64-unknown-linux-gnu Thread model: posix InstalledDir: /home/haoxin/haoxin-data/dut-research/compilers/llvm-project/build-20210216/bin Found candidate GCC installation: /usr/lib/gcc/i686-linux-gnu/8 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/8 Candidate multilib: .;@m64 Selected multilib: .;@m64 This problem only occurs in clang-trunk and clang-11.0.0 or clang-11.0.1, while other released versions from clang-10 downwards perform well in this case. Thanks. Haoxin
Bugpoint reduction: opt -instcombine ; ModuleID = '<stdin>' source_filename = "test.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" @a = external dso_local global i32, align 4 define dso_local void @b() local_unnamed_addr #0 { entry: br label %for.cond for.cond: ; preds = %for.body, %entry %storemerge = phi i32 [ 7, %entry ], [ %add, %for.body ] br i1 icmp uge (i32* inttoptr (i64 2 to i32*), i32* @a), label %for.body, label %for.end for.body: ; preds = %for.cond %0 = load i32, i32* @a, align 4 %div = sdiv i32 %0, undef %add = add nsw i32 %div, 1 br label %for.cond for.end: ; preds = %for.cond %cmp6 = icmp ne i32 %storemerge, 4 %conv = zext i1 %cmp6 to i32 %and7 = and i32 %storemerge, %conv %sub = sub nsw i32 %storemerge, %and7 %cmp9 = icmp ne i32 %sub, 4 %conv10 = zext i1 %cmp9 to i32 %sub11 = sub nsw i32 %conv10, %sub %and14 = and i32 %sub11, 1 %1 = select i1 false, i32 0, i32 %and14 store i32 %1, i32* @a, align 4 ret void } attributes #0 = { "tune-cpu"="generic" } !llvm.ident = !{!0} !0 = !{!"clang version 13.0.0"}
The bug appears to be in InstCombine's SimplifyDemandedBits of a select. We may have conflicting motives in changing a select's constant operands into the least set bits vs. matching a cmp's operand (another min/max hack that could disappear with canonicalization to intrinsics). So we're ping-ponging between: IC: Visiting: %sub11 = select i1 %cmp9, i32 1, i32 6 IC: Visiting: %sub11 = select i1 %cmp9, i32 1, i32 4 I think there's a small fix to avoid that - will try to reduce further and confirm.
This should fix the bug in trunk: https://reviews.llvm.org/rG9502061bcc86 I'm marking this as blocking the 12.0 release to see if we can still get it in there. As noted in the description, this was visible in the 11.0 release, but not before that. The bug was likely introduced with: https://reviews.llvm.org/rGa59cc5e128f09ec
Merged: 692808e5af83