llvm.org GIT mirror llvm / f84a650
[Verifier] Verify invokes of intrinsics We support invoking a subset of llvm's intrinsics, but the verifier didn't account for this. We had previously added a special case to verify invokes of statepoints. By generalizing the code in terms of CallSite, we can verify invokes of other intrinsics as well. Interestingly, this found one test case which was invalid. Note: I'm deliberately leaving the naming change from CI to CS to a follow up change. That will happen shortly, I just wanted to reduce the diff to make it clear what was happening with this one. Differential Revision: http://reviews.llvm.org/D10118 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240836 91177308-0d34-0410-b5e6-96231b3b80d8 Philip Reames 4 years ago
3 changed file(s) with 40 addition(s) and 23 deletion(s). Raw diff Collapse all Expand all
3737 class InvokeInst;
3838
3939 template
40 typename BBTy = const BasicBlock,
4041 typename ValTy = const Value,
4142 typename UserTy = const User,
4243 typename InstrTy = const Instruction,
8182 InstrTy *operator->() const { return I.getPointer(); }
8283 explicit operator bool() const { return I.getPointer(); }
8384
85 /// Get the basic block containing the call site
86 BBTy* getParent() const { return getInstruction()->getParent(); }
87
8488 /// getCalledValue - Return the pointer to function that is being called.
8589 ///
8690 ValTy *getCalledValue() const {
187191 cast(II)->METHOD; \
188192 else \
189193 cast(II)->METHOD
194
195 unsigned getNumArgOperands() const {
196 CALLSITE_DELEGATE_GETTER(getNumArgOperands());
197 }
198
199 Value *getArgOperand(unsigned i) const {
200 CALLSITE_DELEGATE_GETTER(getArgOperand(i));
201 }
202
203 bool isInlineAsm() const {
204 if (isCall())
205 return cast(getInstruction())->isInlineAsm();
206 return false;
207 }
190208
191209 /// getCallingConv/setCallingConv - get or set the calling convention of the
192210 /// call.
365383 }
366384 };
367385
368 class CallSite : public CallSiteBase
369 CallInst, InvokeInst, User::op_iterator> {
386 class CallSite : public CallSiteBase
387 Instruction, CallInst, InvokeInst,
388 User::op_iterator> {
370389 public:
371390 CallSite() {}
372391 CallSite(CallSiteBase B) : CallSiteBase(B) {}
101101 OS << '\n';
102102 }
103103 }
104 void Write(const CallSite *CS) {
105 if (!CS)
106 return;
107 Write(CS->getInstruction());
108 }
104109
105110 void Write(const Metadata *MD) {
106111 if (!MD)
366371 void visitSelectInst(SelectInst &SI);
367372 void visitUserOp1(Instruction &I);
368373 void visitUserOp2(Instruction &I) { visitUserOp1(I); }
369 void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
374 void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallSite CS);
370375 template
371376 void visitDbgIntrinsic(StringRef Kind, DbgIntrinsicTy &DII);
372377 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &CXI);
22882293 "Function has metadata parameter but isn't an intrinsic", I);
22892294 }
22902295
2296 if (Function *F = CS.getCalledFunction())
2297 if (Intrinsic::ID ID = (Intrinsic::ID)F->getIntrinsicID())
2298 visitIntrinsicFunctionCall(ID, CS);
2299
22912300 visitInstruction(*I);
22922301 }
22932302
23832392
23842393 if (CI.isMustTailCall())
23852394 verifyMustTailCall(CI);
2386
2387 if (Function *F = CI.getCalledFunction())
2388 if (Intrinsic::ID ID = F->getIntrinsicID())
2389 visitIntrinsicFunctionCall(ID, CI);
23902395 }
23912396
23922397 void Verifier::visitInvokeInst(InvokeInst &II) {
23962401 // instruction of the 'unwind' destination.
23972402 Assert(II.getUnwindDest()->isLandingPad(),
23982403 "The unwind destination does not have a landingpad instruction!", &II);
2399
2400 if (Function *F = II.getCalledFunction())
2401 // TODO: Ideally we should use visitIntrinsicFunction here. But it uses
2402 // CallInst as an input parameter. It not woth updating this whole
2403 // function only to support statepoint verification.
2404 if (F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint)
2405 VerifyStatepoint(ImmutableCallSite(&II));
24062404
24072405 visitTerminatorInst(II);
24082406 }
31453143
31463144 /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
31473145 ///
3148 void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
3146 void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallSite CI) {
31493147 Function *IF = CI.getCalledFunction();
31503148 Assert(IF->isDeclaration(), "Intrinsic functions should never be defined!",
31513149 IF);
32073205 case Intrinsic::dbg_declare: // llvm.dbg.declare
32083206 Assert(isa(CI.getArgOperand(0)),
32093207 "invalid llvm.dbg.declare intrinsic call 1", &CI);
3210 visitDbgIntrinsic("declare", cast(CI));
3208 visitDbgIntrinsic("declare", cast(*CI.getInstruction()));
32113209 break;
32123210 case Intrinsic::dbg_value: // llvm.dbg.value
3213 visitDbgIntrinsic("value", cast(CI));
3211 visitDbgIntrinsic("value", cast(*CI.getInstruction()));
32143212 break;
32153213 case Intrinsic::memcpy:
32163214 case Intrinsic::memmove:
32813279 "llvm.frameescape used outside of entry block", &CI);
32823280 Assert(!SawFrameEscape,
32833281 "multiple calls to llvm.frameescape in one function", &CI);
3284 for (Value *Arg : CI.arg_operands()) {
3282 for (Value *Arg : CI.args()) {
32853283 if (isa(Arg))
32863284 continue; // Null values are allowed as placeholders.
32873285 auto *AI = dyn_cast(Arg->stripPointerCasts());
33143312 Assert(CI.getParent()->getParent()->hasGC(),
33153313 "Enclosing function does not use GC.", &CI);
33163314
3317 VerifyStatepoint(ImmutableCallSite(&CI));
3315 VerifyStatepoint(ImmutableCallSite(CI));
33183316 break;
33193317 case Intrinsic::experimental_gc_result_int:
33203318 case Intrinsic::experimental_gc_result_float:
33763374
33773375 // Verify rest of the relocate arguments
33783376
3379 GCRelocateOperands Ops(&CI);
3377 GCRelocateOperands Ops(CI);
33803378 ImmutableCallSite StatepointCS(Ops.getStatepoint());
33813379
33823380 // Both the base and derived must be piped through the safepoint
34323430 // Relocated value must be a pointer type, but gc_relocate does not need to return the
34333431 // same pointer type as the relocated pointer. It can be casted to the correct type later
34343432 // if it's desired. However, they must have the same address space.
3435 GCRelocateOperands Operands(&CI);
3433 GCRelocateOperands Operands(CI);
34363434 Assert(Operands.getDerivedPtr()->getType()->isPointerTy(),
34373435 "gc.relocate: relocated value must be a gc pointer", &CI);
34383436
6060 %.i8 = call i8* @llvm.framerecover(i8* bitcast (void ()* @"\01?f@@YAXXZ" to i8*), i8* %1, i32 1)
6161 %2 = bitcast i8* %.i8 to double*
6262 %3 = bitcast double* %2 to i8*
63 invoke void (...) @llvm.donothing()
63 invoke void () @llvm.donothing()
6464 to label %done unwind label %lpad
6565
6666 done:
200200 ; Function Attrs: nounwind readnone
201201 declare i8* @llvm.framerecover(i8*, i8*, i32) #2
202202
203 declare void @llvm.donothing(...)
203 declare void @llvm.donothing()
204204
205205 attributes #0 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" "wineh-parent"="?f@@YAXXZ" }
206206 attributes #1 = { "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }