Index: llvm/include/llvm/IR/InstVisitor.h =================================================================== --- llvm/include/llvm/IR/InstVisitor.h +++ llvm/include/llvm/IR/InstVisitor.h @@ -156,6 +156,8 @@ RetTy visit##OPCODE(CLASS &I) { \ if (NUM == Instruction::Call) \ return delegateCallInst(I); \ + else if (NUM == Instruction::Invoke) \ + return delegateInvokeInst(I); \ else \ DELEGATE(CLASS); \ } @@ -215,7 +217,12 @@ RetTy visitVAStartInst(VAStartInst &I) { DELEGATE(IntrinsicInst); } RetTy visitVAEndInst(VAEndInst &I) { DELEGATE(IntrinsicInst); } RetTy visitVACopyInst(VACopyInst &I) { DELEGATE(IntrinsicInst); } - RetTy visitIntrinsicInst(IntrinsicInst &I) { DELEGATE(CallInst); } + RetTy visitIntrinsicInst(IntrinsicInst &I) { + if (auto *CI = dyn_cast(&I)) + return static_cast(this)->visitCallInst(*CI); + else + return static_cast(this)->visitInvokeInst(cast(I)); + } RetTy visitCallInst(CallInst &I) { DELEGATE(CallBase); } RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(CallBase); } RetTy visitCallBrInst(CallBrInst &I) { DELEGATE(CallBase); } @@ -279,31 +286,41 @@ void visitInstruction(Instruction &I) {} // Ignore unhandled instructions private: - // Special helper function to delegate to CallInst subclass visitors. - RetTy delegateCallInst(CallInst &I) { - if (const Function *F = I.getCalledFunction()) { - switch (F->getIntrinsicID()) { - default: DELEGATE(IntrinsicInst); - case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst); - case Intrinsic::dbg_value: DELEGATE(DbgValueInst); - case Intrinsic::dbg_label: DELEGATE(DbgLabelInst); - case Intrinsic::memcpy: DELEGATE(MemCpyInst); - case Intrinsic::memmove: DELEGATE(MemMoveInst); - case Intrinsic::memset: DELEGATE(MemSetInst); - case Intrinsic::vastart: DELEGATE(VAStartInst); - case Intrinsic::vaend: DELEGATE(VAEndInst); - case Intrinsic::vacopy: DELEGATE(VACopyInst); - case Intrinsic::not_intrinsic: break; - } + // Special helper functions to delegate to CallInst subclass visitors. + RetTy delegateIntrinsicInst(IntrinsicInst &I) { + switch (I.getIntrinsicID()) { + default: DELEGATE(IntrinsicInst); + case Intrinsic::dbg_declare: DELEGATE(DbgDeclareInst); + case Intrinsic::dbg_value: DELEGATE(DbgValueInst); + case Intrinsic::dbg_label: DELEGATE(DbgLabelInst); + case Intrinsic::memcpy: DELEGATE(MemCpyInst); + case Intrinsic::memmove: DELEGATE(MemMoveInst); + case Intrinsic::memset: DELEGATE(MemSetInst); + case Intrinsic::vastart: DELEGATE(VAStartInst); + case Intrinsic::vaend: DELEGATE(VAEndInst); + case Intrinsic::vacopy: DELEGATE(VACopyInst); } + } + + RetTy delegateCallInst(CallInst &I) { + if (auto *II = dyn_cast(&I)) + return delegateIntrinsicInst(*II); DELEGATE(CallInst); } + RetTy delegateInvokeInst(InvokeInst &I) { + if (auto *II = dyn_cast(&I)) + return delegateIntrinsicInst(*II); + DELEGATE(InvokeInst); + } // An overload that will never actually be called, it is used only from dead // code in the dispatching from opcodes to instruction subclasses. RetTy delegateCallInst(Instruction &I) { llvm_unreachable("delegateCallInst called for non-CallInst"); } + RetTy delegateInvokeInst(Instruction &I) { + llvm_unreachable("delegateInvokeInst called for non-InvokeInst"); + } }; #undef DELEGATE Index: llvm/include/llvm/IR/IntrinsicInst.h =================================================================== --- llvm/include/llvm/IR/IntrinsicInst.h +++ llvm/include/llvm/IR/IntrinsicInst.h @@ -13,10 +13,10 @@ // if (MemCpyInst *MCI = dyn_cast(Inst)) // ... MCI->getDest() ... MCI->getSource() ... // -// All intrinsic function calls are instances of the call instruction, so these -// are all subclasses of the CallInst class. Note that none of these classes -// has state or virtual methods, which is an important part of this gross/neat -// hack working. +// All intrinsic function calls are instances of the call or invoke instruction, +// so these are all subclasses of the CallBase class. Note that none of these +// classes has state or virtual methods, which is an important part of this +// gross/neat hack working. // //===----------------------------------------------------------------------===// @@ -42,7 +42,7 @@ /// A wrapper class for inspecting calls to intrinsic functions. /// This allows the standard isa/dyncast/cast functionality to work with calls /// to intrinsic functions. -class IntrinsicInst : public CallInst { +class IntrinsicInst : public CallBase { public: IntrinsicInst() = delete; IntrinsicInst(const IntrinsicInst &) = delete; @@ -107,13 +107,15 @@ } // Methods for support type inquiry through isa, cast, and dyn_cast: - static bool classof(const CallInst *I) { + static bool classof(const CallBase *I) { if (const Function *CF = I->getCalledFunction()) return CF->isIntrinsic(); return false; } static bool classof(const Value *V) { - return isa(V) && classof(cast(V)); + if (auto *CB = dyn_cast(V)) + return classof(CB); + return false; } }; Index: llvm/lib/Analysis/TypeMetadataUtils.cpp =================================================================== --- llvm/lib/Analysis/TypeMetadataUtils.cpp +++ llvm/lib/Analysis/TypeMetadataUtils.cpp @@ -83,7 +83,7 @@ // Find llvm.assume intrinsics for this llvm.type.test call. for (const Use &CIU : CI->uses()) if (auto *Assume = dyn_cast(CIU.getUser())) - Assumes.push_back(Assume); + Assumes.push_back(cast(Assume)); // If we found any, search for virtual calls based on %p and add them to // DevirtCalls. Index: llvm/lib/CodeGen/SelectionDAG/FastISel.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -1338,15 +1338,15 @@ return true; } case Intrinsic::experimental_stackmap: - return selectStackmap(II); + return selectStackmap(cast(II)); case Intrinsic::experimental_patchpoint_void: case Intrinsic::experimental_patchpoint_i64: - return selectPatchpoint(II); + return selectPatchpoint(cast(II)); case Intrinsic::xray_customevent: - return selectXRayCustomEvent(II); + return selectXRayCustomEvent(cast(II)); case Intrinsic::xray_typedevent: - return selectXRayTypedEvent(II); + return selectXRayTypedEvent(cast(II)); } return fastLowerIntrinsicCall(II); Index: llvm/lib/CodeGen/ShadowStackGCLowering.cpp =================================================================== --- llvm/lib/CodeGen/ShadowStackGCLowering.cpp +++ llvm/lib/CodeGen/ShadowStackGCLowering.cpp @@ -244,7 +244,7 @@ if (Function *F = CI->getCalledFunction()) if (F->getIntrinsicID() == Intrinsic::gcroot) { std::pair Pair = std::make_pair( - CI, + cast(CI), cast(CI->getArgOperand(0)->stripPointerCasts())); if (IsNullValue(CI->getArgOperand(1))) Roots.push_back(Pair); Index: llvm/lib/CodeGen/StackProtector.cpp =================================================================== --- llvm/lib/CodeGen/StackProtector.cpp +++ llvm/lib/CodeGen/StackProtector.cpp @@ -255,7 +255,7 @@ for (const Instruction &I : BB) if (const auto *II = dyn_cast(&I)) if (II->getIntrinsicID() == Intrinsic::stackprotector) - return II; + return cast(II); return nullptr; } Index: llvm/lib/ExecutionEngine/Interpreter/Execution.cpp =================================================================== --- llvm/lib/ExecutionEngine/Interpreter/Execution.cpp +++ llvm/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -1143,7 +1143,7 @@ bool atBegin(Parent->begin() == Me); if (!atBegin) --Me; - IL->LowerIntrinsicCall(&I); + IL->LowerIntrinsicCall(cast(&I)); // Restore the CurInst pointer to the first instruction newly inserted, if // any. Index: llvm/lib/Target/AArch64/AArch64FastISel.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64FastISel.cpp +++ llvm/lib/Target/AArch64/AArch64FastISel.cpp @@ -3482,7 +3482,8 @@ return false; const char *IntrMemName = isa(II) ? "memcpy" : "memmove"; - return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 1); + return lowerCallTo(cast(II), IntrMemName, + II->getNumArgOperands() - 1); } case Intrinsic::memset: { const MemSetInst *MSI = cast(II); @@ -3498,7 +3499,8 @@ // address spaces. return false; - return lowerCallTo(II, "memset", II->getNumArgOperands() - 1); + return lowerCallTo(cast(II), "memset", + II->getNumArgOperands() - 1); } case Intrinsic::sin: case Intrinsic::cos: Index: llvm/lib/Target/Mips/MipsFastISel.cpp =================================================================== --- llvm/lib/Target/Mips/MipsFastISel.cpp +++ llvm/lib/Target/Mips/MipsFastISel.cpp @@ -1660,7 +1660,7 @@ if (!MTI->getLength()->getType()->isIntegerTy(32)) return false; const char *IntrMemName = isa(II) ? "memcpy" : "memmove"; - return lowerCallTo(II, IntrMemName, II->getNumArgOperands() - 1); + return lowerCallTo(cast(II), IntrMemName, II->getNumArgOperands() - 1); } case Intrinsic::memset: { const MemSetInst *MSI = cast(II); @@ -1669,7 +1669,7 @@ return false; if (!MSI->getLength()->getType()->isIntegerTy(32)) return false; - return lowerCallTo(II, "memset", II->getNumArgOperands() - 1); + return lowerCallTo(cast(II), "memset", II->getNumArgOperands() - 1); } } return false; Index: llvm/lib/Target/X86/X86FastISel.cpp =================================================================== --- llvm/lib/Target/X86/X86FastISel.cpp +++ llvm/lib/Target/X86/X86FastISel.cpp @@ -2738,7 +2738,7 @@ if (MCI->getSourceAddressSpace() > 255 || MCI->getDestAddressSpace() > 255) return false; - return lowerCallTo(II, "memcpy", II->getNumArgOperands() - 1); + return lowerCallTo(cast(II), "memcpy", II->getNumArgOperands() - 1); } case Intrinsic::memset: { const MemSetInst *MSI = cast(II); @@ -2753,7 +2753,7 @@ if (MSI->getDestAddressSpace() > 255) return false; - return lowerCallTo(II, "memset", II->getNumArgOperands() - 1); + return lowerCallTo(cast(II), "memset", II->getNumArgOperands() - 1); } case Intrinsic::stackprotector: { // Emit code to store the stack guard onto the stack. Index: llvm/lib/Transforms/InstCombine/InstCombineInternal.h =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -140,6 +140,7 @@ Instruction *visitAddrSpaceCast(AddrSpaceCastInst &CI); Instruction *foldItoFPtoI(CastInst &FI); Instruction *visitSelectInst(SelectInst &SI); + Instruction *visitCallBase(CallBase &Call); Instruction *visitCallInst(CallInst &CI); Instruction *visitInvokeInst(InvokeInst &II); Instruction *visitCallBrInst(CallBrInst &CBI); @@ -222,7 +223,6 @@ Instruction &CtxI, Value *&OperationResult, Constant *&OverflowResult); - Instruction *visitCallBase(CallBase &Call); Instruction *tryOptimizeCall(CallInst *CI); bool transformConstExprCastCall(CallBase &Call); Instruction *transformCallThroughTrampoline(CallBase &Call, Index: llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -4142,7 +4142,7 @@ Value *VAArgTLSOriginCopy = nullptr; Value *VAArgOverflowSize = nullptr; - SmallVector VAStartInstrumentationList; + SmallVector VAStartInstrumentationList; enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory }; @@ -4351,7 +4351,7 @@ // Instrument va_start. // Copy va_list shadow from the backup copy of the TLS contents. for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) { - CallInst *OrigInst = VAStartInstrumentationList[i]; + auto *OrigInst = VAStartInstrumentationList[i]; IRBuilder<> IRB(OrigInst->getNextNode()); Value *VAListTag = OrigInst->getArgOperand(0); @@ -4405,7 +4405,7 @@ Value *VAArgTLSCopy = nullptr; Value *VAArgSize = nullptr; - SmallVector VAStartInstrumentationList; + SmallVector VAStartInstrumentationList; VarArgMIPS64Helper(Function &F, MemorySanitizer &MS, MemorySanitizerVisitor &MSV) : F(F), MS(MS), MSV(MSV) {} @@ -4494,7 +4494,7 @@ // Instrument va_start. // Copy va_list shadow from the backup copy of the TLS contents. for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) { - CallInst *OrigInst = VAStartInstrumentationList[i]; + auto *OrigInst = VAStartInstrumentationList[i]; IRBuilder<> IRB(OrigInst->getNextNode()); Value *VAListTag = OrigInst->getArgOperand(0); Type *RegSaveAreaPtrTy = Type::getInt64PtrTy(*MS.C); @@ -4533,7 +4533,7 @@ Value *VAArgTLSCopy = nullptr; Value *VAArgOverflowSize = nullptr; - SmallVector VAStartInstrumentationList; + SmallVector VAStartInstrumentationList; enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory }; @@ -4688,7 +4688,7 @@ // Instrument va_start, copy va_list shadow from the backup copy of // the TLS contents. for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) { - CallInst *OrigInst = VAStartInstrumentationList[i]; + auto *OrigInst = VAStartInstrumentationList[i]; IRBuilder<> IRB(OrigInst->getNextNode()); Value *VAListTag = OrigInst->getArgOperand(0); @@ -4783,7 +4783,7 @@ Value *VAArgTLSCopy = nullptr; Value *VAArgSize = nullptr; - SmallVector VAStartInstrumentationList; + SmallVector VAStartInstrumentationList; VarArgPowerPC64Helper(Function &F, MemorySanitizer &MS, MemorySanitizerVisitor &MSV) : F(F), MS(MS), MSV(MSV) {} @@ -4932,7 +4932,7 @@ // Instrument va_start. // Copy va_list shadow from the backup copy of the TLS contents. for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) { - CallInst *OrigInst = VAStartInstrumentationList[i]; + auto *OrigInst = VAStartInstrumentationList[i]; IRBuilder<> IRB(OrigInst->getNextNode()); Value *VAListTag = OrigInst->getArgOperand(0); Type *RegSaveAreaPtrTy = Type::getInt64PtrTy(*MS.C); @@ -4972,7 +4972,7 @@ Value *VAArgTLSOriginCopy = nullptr; Value *VAArgOverflowSize = nullptr; - SmallVector VAStartInstrumentationList; + SmallVector VAStartInstrumentationList; enum class ArgKind { GeneralPurpose, @@ -5255,7 +5255,7 @@ // Copy va_list shadow from the backup copy of the TLS contents. for (size_t VaStartNo = 0, VaStartNum = VAStartInstrumentationList.size(); VaStartNo < VaStartNum; VaStartNo++) { - CallInst *OrigInst = VAStartInstrumentationList[VaStartNo]; + auto *OrigInst = VAStartInstrumentationList[VaStartNo]; IRBuilder<> IRB(OrigInst->getNextNode()); Value *VAListTag = OrigInst->getArgOperand(0); copyRegSaveArea(IRB, VAListTag);