Reproducer: void f() { __try { f(); } __except (1) { return; } __try { f(); } __except (1) { } } clang-cl.exe -O2 -clang:-fprofile-generate -c test.cpp Here's the stack though I'm not sure how much it helps, given the inlining in my release build: 00 clang!`anonymous namespace'::PruneEH::runOnSCC 01 clang!`anonymous namespace'::CGPassManager::runOnModule 02 clang!llvm::legacy::PassManagerImpl::run 03 clang!clang::EmitBackendOutput 04 clang!clang::BackendConsumer::HandleTranslationUnit 05 clang!clang::ParseAST I wonder if this is the PGO-analogue to the SEH gcov crash in bug 34833.
Created attachment 22012 [details] Test case for IR-level instrumentation failure.
For reference, the Rust compiler is running into the same (or at least similar) problem when compiling with IR-level instrumentation. Compiling the following for `x86_64-pc-windows-msvc` as well as `i686-pc-windows-msvc` ``` fn main() { panic!() } ``` runs into the following LLVM assertion in PGOInstrumentation.cpp: https://github.com/llvm/llvm-project/blob/release/8.x/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp#L714 The resulting LLVM IR is rather verbose unfortunately, and I was not able to reduce it with `bugpoint`. I'm attaching it anyway. The Rust compiler's LLVM version is 8.0.
Another data point that might be interesting. Compiling David Major's test case with a Clang/LLVM (8.0) with assertions enabled runs into the following assertions, both for `i686-pc-windows-gnu` and `x86_64-pc-windows-gnu`: https://github.com/llvm/llvm-project/blob/release/8.x/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp#L714
> runs into the following LLVM assertion in PGOInstrumentation.cpp: > > https://github.com/llvm/llvm-project/blob/release/8.x/llvm/lib/Transforms/ > Instrumentation/PGOInstrumentation.cpp#L714 Adding some people who may be interested in this assertion.
Rong, can you take a look why the critical edge split fails?
We call llvm::SplitCriticalEdge() to split a critical edge so we can instrument the edge on BB. llvm::SplitCriticalEdge() does not currently handle the edge to an EHPad block. This is a known issue and that why I put an assert there. The complete fix is to do a customized critical edges splitting. But I'm not sure the cost is justified. An alternative fix is to not instrument this critical edge if it cannot be split. I will send a patch following this idea for review.
sent https://reviews.llvm.org/D62439 for review.
I see that the linked review landed, but I re-tried the example from the initial report, and the assert on 1509 still fires: void f() { __try { f(); } __except (1) { return; } __try { f(); } __except (1) { } } This assert is failing: for (auto *InstrBB : InstrumentBBs) { IRBuilder<> Builder(InstrBB, InstrBB->getFirstInsertionPt()); assert(Builder.GetInsertPoint() != InstrBB->end() && "Cannot get the Instrumentation point"); Builder.CreateCall( Intrinsic::getDeclaration(M, Intrinsic::instrprof_increment), {ConstantExpr::getBitCast(FuncInfo.FuncNameVar, I8PtrTy), Builder.getInt64(FuncInfo.FunctionHash), Builder.getInt32(NumCounters), Builder.getInt32(I++)}); } The assert will fail for catchswitch blocks where the getFirstInsertionPt returns the end iterator.
Sorry for the double comment, I think I hit "enter enter" because I wanted to add... Thanks for looking into this, the fix appears to be quite involved, and it would've been hard for a non-PGO expert to come up with as good of a fix.
(In reply to Reid Kleckner from comment #10) > Sorry for the double comment, I think I hit "enter enter" because I wanted > to add... Thanks for looking into this, the fix appears to be quite > involved, and it would've been hard for a non-PGO expert to come up with as > good of a fix. Thanks for verifying this. Could you give me the IR file? I did try the reproducer in the comment #1. But I did not have a windows environment and could not reproduce the error in linux. I was thinking the assertion is the same as in comment #2. But now, it seems to be different issue.
Created attachment 22051 [details] catchswitch example Here's the IR. When I compile this with `clang -c t.ll -fprofile-generate`, it reproduces the assertion in PGO instrumentation relating to insertion points.
Thanks Reid for the IR reproducer. The reason for the failure in the original report is that we want to instrument the fellowing BB: catch.dispatch4: ; preds = %__try.cont %3 = catchswitch within none [label %__except5] unwind to caller catchswitch needs to be the first instruction for a BB. So the instrumentation pt returned is the end of BB. I don't think we can instrument this BB. The fix is probably to filter this kind of BBs. I will sent a patch for review shortly.
https://reviews.llvm.org/D62700 is out for review.
According to Russel, r362995 fixed this issue.