Adjusting verification of "llvm.gc*" intrinsic prototypes to match

LangRef.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45349 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Gordon Henriksen 2007-12-25 02:02:10 +00:00
parent f1519e8361
commit 27acd3a999
5 changed files with 82 additions and 27 deletions

View File

@ -1153,12 +1153,6 @@ void Verifier::visitInstruction(Instruction &I) {
InstsInThisBlock.insert(&I);
}
static bool HasPtrPtrType(Value *Val) {
if (const PointerType *PtrTy = dyn_cast<PointerType>(Val->getType()))
return isa<PointerType>(PtrTy->getElementType());
return false;
}
/// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
///
void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
@ -1173,30 +1167,43 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
switch (ID) {
default:
break;
case Intrinsic::gcroot:
Assert1(HasPtrPtrType(CI.getOperand(1)),
"llvm.gcroot parameter #1 must be a pointer to a pointer.", &CI);
Assert1(isa<AllocaInst>(IntrinsicInst::StripPointerCasts(CI.getOperand(1))),
"llvm.gcroot parameter #1 must be an alloca (or a bitcast of one).",
&CI);
Assert1(isa<Constant>(CI.getOperand(2)),
"llvm.gcroot parameter #2 must be a constant.", &CI);
break;
case Intrinsic::gcwrite:
Assert1(CI.getOperand(3)->getType()
== PointerType::getUnqual(CI.getOperand(1)->getType()),
"Call to llvm.gcwrite must be with type 'void (%ty*, %ty2*, %ty**)'.",
&CI);
break;
case Intrinsic::gcread:
Assert1(CI.getOperand(2)->getType() == PointerType::getUnqual(CI.getType()),
"Call to llvm.gcread must be with type '%ty* (%ty2*, %ty**).'",
&CI);
break;
case Intrinsic::gcroot: {
Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
*PtrPtrTy = PointerType::getUnqual(PtrTy);
Assert1(CI.getOperand(1)->getType() == PtrPtrTy,
"Intrinsic parameter #1 is not i8**.", &CI);
Assert1(CI.getOperand(2)->getType() == PtrTy,
"Intrinsic parameter #2 is not i8*.", &CI);
Assert1(
isa<AllocaInst>(IntrinsicInst::StripPointerCasts(CI.getOperand(1))),
"llvm.gcroot parameter #1 must be an alloca.",
&CI);
Assert1(isa<Constant>(CI.getOperand(2)),
"llvm.gcroot parameter #2 must be a constant.", &CI);
} break;
case Intrinsic::gcwrite: {
Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
*PtrPtrTy = PointerType::getUnqual(PtrTy);
Assert1(CI.getOperand(1)->getType() == PtrTy,
"Intrinsic parameter #1 is not a i8*.", &CI);
Assert1(CI.getOperand(2)->getType() == PtrTy,
"Intrinsic parameter #2 is not a i8*.", &CI);
Assert1(CI.getOperand(3)->getType() == PtrPtrTy,
"Intrinsic parameter #3 is not a i8**.", &CI);
} break;
case Intrinsic::gcread: {
Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
*PtrPtrTy = PointerType::getUnqual(PtrTy);
Assert1(CI.getOperand(1)->getType() == PtrTy,
"Intrinsic parameter #1 is not a i8*.", &CI);
Assert1(CI.getOperand(2)->getType() == PtrPtrTy,
"Intrinsic parameter #2 is not a i8**.", &CI);
} break;
case Intrinsic::init_trampoline:
Assert1(isa<Function>(IntrinsicInst::StripPointerCasts(CI.getOperand(2))),
"llvm.init_trampoline parameter #2 must resolve to a function.",
&CI);
break;
}
}

View File

@ -0,0 +1,13 @@
; RUN: not llvm-as < %s
%list = type { i32, %list* }
; This usage is invalid now; instead, objects must be bitcast to i8* for input
; to the gc intrinsics.
declare %list* @llvm.gcread(%list*, %list**)
define %list* @tl(%list* %l) gc "example" {
%hd.ptr = getelementptr %list* %l, i32 0, i32 0
%hd = call %list* @llvm.gcread(%list* %l, %list** %hd.ptr)
ret i32 %tmp
}

View File

@ -0,0 +1,13 @@
; RUN: not llvm-as < %s
%list = type { i32, %list* }
%meta = type opaque
; This usage is invalid now; instead, objects must be bitcast to i8* for input
; to the gc intrinsics.
declare void @llvm.gcroot(%list*, %meta*)
define void @root() gc "example" {
%x.var = alloca i8*
call void @llvm.gcroot(i8** %x.var, %meta* null)
}

View File

@ -0,0 +1,22 @@
; RUN: not llvm-as < %s
%list = type { i32, %list* }
; This usage is invalid now; instead, objects must be bitcast to i8* for input
; to the gc intrinsics.
declare void @llvm.gcwrite(%list*, %list*, %list**)
define %list* @cons(i32 %hd, %list* %tl) gc "example" {
%tmp = call i8* @gcalloc(i32 bitcast(%list* getelementptr(%list* null, i32 1) to i32))
%cell = bitcast i8* %tmp to %list*
%hd.ptr = getelementptr %list* %cell, i32 0, i32 0
store i32 %hd, i32* %hd.ptr
%tl.ptr = getelementptr %list* %cell, i32 0, i32 0
call void @llvm.gcwrite(%list* %tl, %list* %cell, %list** %tl.ptr)
ret %cell.2
}
declare i8* @gcalloc(i32)

View File

@ -1,6 +1,6 @@
; RUN: llvm-as < %s | llc
%Env = type opaque*
%Env = type i8*
define void @.main(%Env) {
%Root = alloca %Env