Skip to content

"Invalidated the current SCC" assertion failure after #79712 #107139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
smeenai opened this issue Sep 3, 2024 · 4 comments · Fixed by #107935
Closed

"Invalidated the current SCC" assertion failure after #79712 #107139

smeenai opened this issue Sep 3, 2024 · 4 comments · Fixed by #107935
Assignees
Labels
coroutines C++20 coroutines crash Prefer [crash-on-valid] or [crash-on-invalid] llvm:transforms

Comments

@smeenai
Copy link
Collaborator

smeenai commented Sep 3, 2024

For the source file in https://gist.github.com/smeenai/fcd14380467e813a28f1ef8c5484b775 (reduced from a large example that uses libunifex; it's probably possible to reduce this further but I'm not at all familiar with coroutines), the following command succeeds with Clang 18 but fails with Clang 19 and trunk:

$ clang -c -o /dev/null coroutine_crash.cpp -std=c++20 -w
clang: llvm/lib/Analysis/CGSCCPassManager.cpp:1167: LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph &, LazyCallGraph::SCC &, LazyCallGraph::Node &, llvm::CGSCCAnalysisManager &, llvm::CGSCCUpdateResult &, llvm::FunctionAnalysisManager &, bool): Assertion `!UR.InvalidatedSCCs.count(C) && "Invalidated the current SCC!"' failed.

I bisected this to #79712. CC @fpasserby, @ChuanqiXu9, and @yuxuanchen1997

@yuxuanchen1997
Copy link
Member

I took a look at this and I think it was due to incorrect call graph updates. updateCGAndAnalysisManagerFor(CGSCC|Function)Pass seems to return an updated SCC but we discarded the updated SCC.

See example usage: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/CGSCCPassManager.cpp#L561-L562
See implementation: https://github.com/llvm/llvm-project/blob/main/llvm/lib/Analysis/CGSCCPassManager.cpp#L1170-L1175

I have a patch #107935 but still need some time for a test case.

@yuxuanchen1997
Copy link
Member

This happens when foo has is not a single node SCC:

define void @foo() presplitcoroutine personality ptr null {
entry:
  %0 = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
  %1 = call ptr @llvm.coro.begin(token %0, ptr null)
  %2 = call token @llvm.coro.save(ptr null)
  %3 = call i8 @llvm.coro.suspend(token none, i1 false)
  %4 = call token @llvm.coro.save(ptr null)
  call void @llvm.coro.await.suspend.void(ptr null, ptr null, ptr @bar)
  ret void
}

define void @bar(ptr %0, ptr %1) {
entry:
  call void @foo()
  ret void
}

declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #0
declare ptr @llvm.coro.begin(token, ptr writeonly) nounwind
declare token @llvm.coro.save(ptr) nomerge nounwind
declare void @llvm.coro.await.suspend.void(ptr, ptr, ptr)
declare i8 @llvm.coro.suspend(token, i1) nounwind

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: read) }

Repro the crash with clang -O0 bad.ll.

@yuxuanchen1997
Copy link
Member

The 3rd argument to @llvm.coro.await.suspend is the await_suspend function in C++. This happens when await_suspend() calls the same coroutine from its body.

@llvmbot
Copy link
Member

llvmbot commented Sep 12, 2024

@llvm/issue-subscribers-coroutines

Author: Shoaib Meenai (smeenai)

For the source file in https://gist.github.com/smeenai/fcd14380467e813a28f1ef8c5484b775 (reduced from a large example that uses libunifex; it's probably possible to reduce this further but I'm not at all familiar with coroutines), the following command succeeds with Clang 18 but fails with Clang 19 and trunk:
$ clang -c -o /dev/null coroutine_crash.cpp -std=c++20 -w
clang: llvm/lib/Analysis/CGSCCPassManager.cpp:1167: LazyCallGraph::SCC &updateCGAndAnalysisManagerForPass(llvm::LazyCallGraph &, LazyCallGraph::SCC &, LazyCallGraph::Node &, llvm::CGSCCAnalysisManager &, llvm::CGSCCUpdateResult &, llvm::FunctionAnalysisManager &, bool): Assertion `!UR.InvalidatedSCCs.count(C) && "Invalidated the current SCC!"' failed.

I bisected this to #79712. CC @fpasserby, @ChuanqiXu9, and @yuxuanchen1997

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
coroutines C++20 coroutines crash Prefer [crash-on-valid] or [crash-on-invalid] llvm:transforms
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants