llvm.org GIT mirror llvm / 27acd3a
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 Gordon Henriksen 12 years ago
5 changed file(s) with 82 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
11521152 InstsInThisBlock.insert(&I);
11531153 }
11541154
1155 static bool HasPtrPtrType(Value *Val) {
1156 if (const PointerType *PtrTy = dyn_cast(Val->getType()))
1157 return isa(PtrTy->getElementType());
1158 return false;
1159 }
1160
11611155 /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
11621156 ///
11631157 void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
11721166 switch (ID) {
11731167 default:
11741168 break;
1175 case Intrinsic::gcroot:
1176 Assert1(HasPtrPtrType(CI.getOperand(1)),
1177 "llvm.gcroot parameter #1 must be a pointer to a pointer.", &CI);
1178 Assert1(isa(IntrinsicInst::StripPointerCasts(CI.getOperand(1))),
1179 "llvm.gcroot parameter #1 must be an alloca (or a bitcast of one).",
1180 &CI);
1181 Assert1(isa(CI.getOperand(2)),
1182 "llvm.gcroot parameter #2 must be a constant.", &CI);
1183 break;
1184 case Intrinsic::gcwrite:
1185 Assert1(CI.getOperand(3)->getType()
1186 == PointerType::getUnqual(CI.getOperand(1)->getType()),
1187 "Call to llvm.gcwrite must be with type 'void (%ty*, %ty2*, %ty**)'.",
1188 &CI);
1189 break;
1190 case Intrinsic::gcread:
1191 Assert1(CI.getOperand(2)->getType() == PointerType::getUnqual(CI.getType()),
1192 "Call to llvm.gcread must be with type '%ty* (%ty2*, %ty**).'",
1193 &CI);
1194 break;
1169 case Intrinsic::gcroot: {
1170 Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
1171 *PtrPtrTy = PointerType::getUnqual(PtrTy);
1172 Assert1(CI.getOperand(1)->getType() == PtrPtrTy,
1173 "Intrinsic parameter #1 is not i8**.", &CI);
1174 Assert1(CI.getOperand(2)->getType() == PtrTy,
1175 "Intrinsic parameter #2 is not i8*.", &CI);
1176 Assert1(
1177 isa(IntrinsicInst::StripPointerCasts(CI.getOperand(1))),
1178 "llvm.gcroot parameter #1 must be an alloca.",
1179 &CI);
1180 Assert1(isa(CI.getOperand(2)),
1181 "llvm.gcroot parameter #2 must be a constant.", &CI);
1182 } break;
1183 case Intrinsic::gcwrite: {
1184 Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
1185 *PtrPtrTy = PointerType::getUnqual(PtrTy);
1186 Assert1(CI.getOperand(1)->getType() == PtrTy,
1187 "Intrinsic parameter #1 is not a i8*.", &CI);
1188 Assert1(CI.getOperand(2)->getType() == PtrTy,
1189 "Intrinsic parameter #2 is not a i8*.", &CI);
1190 Assert1(CI.getOperand(3)->getType() == PtrPtrTy,
1191 "Intrinsic parameter #3 is not a i8**.", &CI);
1192 } break;
1193 case Intrinsic::gcread: {
1194 Type *PtrTy = PointerType::getUnqual(Type::Int8Ty),
1195 *PtrPtrTy = PointerType::getUnqual(PtrTy);
1196 Assert1(CI.getOperand(1)->getType() == PtrTy,
1197 "Intrinsic parameter #1 is not a i8*.", &CI);
1198 Assert1(CI.getOperand(2)->getType() == PtrPtrTy,
1199 "Intrinsic parameter #2 is not a i8**.", &CI);
1200 } break;
11951201 case Intrinsic::init_trampoline:
11961202 Assert1(isa(IntrinsicInst::StripPointerCasts(CI.getOperand(2))),
11971203 "llvm.init_trampoline parameter #2 must resolve to a function.",
11981204 &CI);
1205 break;
11991206 }
12001207 }
12011208
0 ; RUN: not llvm-as < %s
1
2 %list = type { i32, %list* }
3
4 ; This usage is invalid now; instead, objects must be bitcast to i8* for input
5 ; to the gc intrinsics.
6 declare %list* @llvm.gcread(%list*, %list**)
7
8 define %list* @tl(%list* %l) gc "example" {
9 %hd.ptr = getelementptr %list* %l, i32 0, i32 0
10 %hd = call %list* @llvm.gcread(%list* %l, %list** %hd.ptr)
11 ret i32 %tmp
12 }
0 ; RUN: not llvm-as < %s
1
2 %list = type { i32, %list* }
3 %meta = type opaque
4
5 ; This usage is invalid now; instead, objects must be bitcast to i8* for input
6 ; to the gc intrinsics.
7 declare void @llvm.gcroot(%list*, %meta*)
8
9 define void @root() gc "example" {
10 %x.var = alloca i8*
11 call void @llvm.gcroot(i8** %x.var, %meta* null)
12 }
0 ; RUN: not llvm-as < %s
1
2 %list = type { i32, %list* }
3
4 ; This usage is invalid now; instead, objects must be bitcast to i8* for input
5 ; to the gc intrinsics.
6 declare void @llvm.gcwrite(%list*, %list*, %list**)
7
8 define %list* @cons(i32 %hd, %list* %tl) gc "example" {
9 %tmp = call i8* @gcalloc(i32 bitcast(%list* getelementptr(%list* null, i32 1) to i32))
10 %cell = bitcast i8* %tmp to %list*
11
12 %hd.ptr = getelementptr %list* %cell, i32 0, i32 0
13 store i32 %hd, i32* %hd.ptr
14
15 %tl.ptr = getelementptr %list* %cell, i32 0, i32 0
16 call void @llvm.gcwrite(%list* %tl, %list* %cell, %list** %tl.ptr)
17
18 ret %cell.2
19 }
20
21 declare i8* @gcalloc(i32)
0 ; RUN: llvm-as < %s | llc
11
2 %Env = type opaque*
2 %Env = type i8*
33
44 define void @.main(%Env) {
55 %Root = alloca %Env