Index: llvm/include/llvm/Transforms/Utils/CodeExtractor.h =================================================================== --- llvm/include/llvm/Transforms/Utils/CodeExtractor.h +++ llvm/include/llvm/Transforms/Utils/CodeExtractor.h @@ -106,6 +106,11 @@ /// returns false. Function *extractCodeRegion(); + /// Verify if args to the new function are valid. + /// Returns false when any argument is invalid. + /// + static bool validInputs(const ValueSet &inputs); + /// Test whether this code extractor is eligible. /// /// Based on the blocks used when constructing the code extractor, Index: llvm/lib/Transforms/IPO/HotColdSplitting.cpp =================================================================== --- llvm/lib/Transforms/IPO/HotColdSplitting.cpp +++ llvm/lib/Transforms/IPO/HotColdSplitting.cpp @@ -340,6 +340,11 @@ // splitting. SetVector Inputs, Outputs, Sinks; CE.findInputsOutputs(Inputs, Outputs, Sinks); + Function *OrigF = Region[0]->getParent(); + + if (!CE.validInputs(Inputs)) + return nullptr; + int OutliningBenefit = getOutliningBenefit(Region, TTI); int OutliningPenalty = getOutliningPenalty(Region, Inputs.size(), Outputs.size()); @@ -348,7 +353,6 @@ if (OutliningBenefit <= OutliningPenalty) return nullptr; - Function *OrigF = Region[0]->getParent(); if (Function *OutF = CE.extractCodeRegion()) { User *U = *OutF->user_begin(); CallInst *CI = cast(U); Index: llvm/lib/Transforms/Utils/CodeExtractor.cpp =================================================================== --- llvm/lib/Transforms/Utils/CodeExtractor.cpp +++ llvm/lib/Transforms/Utils/CodeExtractor.cpp @@ -1563,5 +1563,16 @@ }); LLVM_DEBUG(if (verifyFunction(*oldFunction)) report_fatal_error("verification of oldFunction failed!")); + LLVM_DEBUG(if (!validInputs(inputs)) + report_fatal_error("verification of newFunction args failed!")); return newFunction; } + +bool CodeExtractor::validInputs(const ValueSet &inputs) { + for (const Value *Arg : inputs) { + Type *Ty = Arg->getType(); + if (!Ty->isFirstClassType() || Ty->isMetadataTy() || Ty->isTokenTy()) + return false; + } + return true; +} Index: llvm/test/Transforms/HotColdSplit/token-arg.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/HotColdSplit/token-arg.ll @@ -0,0 +1,27 @@ +; RUN: opt -S %s -hotcoldsplit -o /dev/null +define void @zot() personality i8* bitcast (i32 (...)* @bar to i8*) { +bb: + invoke void @barney() + to label %bb1 unwind label %bb2 + +bb1: ; preds = %bb + ret void + +bb2: ; preds = %bb + %tmp = cleanuppad within none [] + br label %bb3 + +bb3: ; preds = %bb2 + call void @barney() [ "funclet"(token %tmp) ] + br label %bb4 + +bb4: ; preds = %bb3 + call void @barney.1() [ "funclet"(token %tmp) ] + unreachable +} + +declare void @barney() + +declare i32 @bar(...) + +declare void @barney.1()