Index: llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -780,19 +780,23 @@ if (DestBB == nullptr) return SrcBB; + auto canInstrument = [this](BasicBlock *BB) -> BasicBlock * { + if (BB->getFirstInsertionPt() == BB->end()) { + LLVM_DEBUG(dbgs() << "Cannot instrument BB index=" << getBBInfo(BB).Index + << "\n"); + return nullptr; + } + return BB; + }; + // Instrument the SrcBB if it has a single successor, // otherwise, the DestBB if this is not a critical edge. Instruction *TI = SrcBB->getTerminator(); if (TI->getNumSuccessors() <= 1) - return SrcBB; + return canInstrument(SrcBB); if (!E->IsCritical) - return DestBB; + return canInstrument(DestBB); - // For a critical edge, we have to split. Instrument the newly - // created BB. - IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++; - LLVM_DEBUG(dbgs() << "Split critical edge: " << getBBInfo(SrcBB).Index - << " --> " << getBBInfo(DestBB).Index << "\n"); unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB); BasicBlock *InstrBB = SplitCriticalEdge(TI, SuccNum); if (!InstrBB) { @@ -800,6 +804,11 @@ dbgs() << "Fail to split critical edge: not instrument this edge.\n"); return nullptr; } + // For a critical edge, we have to split. Instrument the newly + // created BB. + IsCS ? NumOfCSPGOSplit++ : NumOfPGOSplit++; + LLVM_DEBUG(dbgs() << "Split critical edge: " << getBBInfo(SrcBB).Index + << " --> " << getBBInfo(DestBB).Index << "\n"); // Need to add two new edges. First one: Add new edge of SrcBB->InstrBB. MST.addEdge(SrcBB, InstrBB, 0); // Second one: Add new edge of InstrBB->DestBB. @@ -807,7 +816,7 @@ NewEdge1.InMST = true; E->Removed = true; - return InstrBB; + return canInstrument(InstrBB); } // Visit all edge and instrument the edges not in MST, and do value profiling. Index: llvm/test/Transforms/PGOProfile/PR41279_2.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/PGOProfile/PR41279_2.ll @@ -0,0 +1,59 @@ +; Test that instrumentaiton works fine for the case of catchswitch stmts. +; RUN: opt < %s -pgo-instr-gen -S | FileCheck %s --check-prefix=GEN +; RUN: opt < %s -passes=pgo-instr-gen -S | FileCheck %s --check-prefix=GEN + +define dso_local void @f() personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) { +entry: + %__exception_code = alloca i32, align 4 + %__exception_code2 = alloca i32, align 4 + invoke void @f() #2 + to label %invoke.cont unwind label %catch.dispatch + +catch.dispatch: + %0 = catchswitch within none [label %__except] unwind to caller + +__except: + %1 = catchpad within %0 [i8* null] + catchret from %1 to label %__except1 + +__except1: + %2 = call i32 @llvm.eh.exceptioncode(token %1) + store i32 %2, i32* %__exception_code, align 4 + br label %__try.cont7 +;GEN: _except1: +;GEN: call void @llvm.instrprof.increment(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__profn_f, i32 0, i32 0), i64 62077759478, i32 2, i32 1) + +invoke.cont: + br label %__try.cont + +__try.cont: + invoke void @f() + to label %invoke.cont3 unwind label %catch.dispatch4 + +catch.dispatch4: + %3 = catchswitch within none [label %__except5] unwind to caller +; GEN: catch.dispatch4: +; GEN-NOT: call void @llvm.instrprof.increment + +__except5: + %4 = catchpad within %3 [i8* null] + catchret from %4 to label %__except6 + +__except6: + %5 = call i32 @llvm.eh.exceptioncode(token %4) + store i32 %5, i32* %__exception_code2, align 4 + br label %__try.cont7 + +__try.cont7: + ret void + +invoke.cont3: + br label %__try.cont7 +;GEN: invoke.cont3: +;GEN: call void @llvm.instrprof.increment(i8* getelementptr inbounds ([1 x i8], [1 x i8]* @__profn_f, i32 0, i32 0), i64 62077759478, i32 2, i32 0) + +} + +declare dso_local i32 @__C_specific_handler(...) + +declare i32 @llvm.eh.exceptioncode(token)