mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
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:
parent
f1519e8361
commit
27acd3a999
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
13
test/CodeGen/Generic/GC/badreadproto.ll
Normal file
13
test/CodeGen/Generic/GC/badreadproto.ll
Normal 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
|
||||
}
|
13
test/CodeGen/Generic/GC/badrootproto.ll
Normal file
13
test/CodeGen/Generic/GC/badrootproto.ll
Normal 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)
|
||||
}
|
22
test/CodeGen/Generic/GC/badwriteproto.ll
Normal file
22
test/CodeGen/Generic/GC/badwriteproto.ll
Normal 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)
|
@ -1,6 +1,6 @@
|
||||
; RUN: llvm-as < %s | llc
|
||||
|
||||
%Env = type opaque*
|
||||
%Env = type i8*
|
||||
|
||||
define void @.main(%Env) {
|
||||
%Root = alloca %Env
|
||||
|
Loading…
Reference in New Issue
Block a user