Adjusting verification of "llvm.gc*" intrinsic prototypes to match
authorGordon Henriksen <gordonhenriksen@mac.com>
Tue, 25 Dec 2007 02:02:10 +0000 (02:02 +0000)
committerGordon Henriksen <gordonhenriksen@mac.com>
Tue, 25 Dec 2007 02:02:10 +0000 (02:02 +0000)
LangRef.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45349 91177308-0d34-0410-b5e6-96231b3b80d8

lib/VMCore/Verifier.cpp
test/CodeGen/Generic/GC/badreadproto.ll [new file with mode: 0644]
test/CodeGen/Generic/GC/badrootproto.ll [new file with mode: 0644]
test/CodeGen/Generic/GC/badwriteproto.ll [new file with mode: 0644]
test/CodeGen/Generic/GC/lower_gcroot.ll

index 901a4c5..e6495a0 100644 (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;
   }
 }
 
diff --git a/test/CodeGen/Generic/GC/badreadproto.ll b/test/CodeGen/Generic/GC/badreadproto.ll
new file mode 100644 (file)
index 0000000..8568ba4
--- /dev/null
@@ -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
+}
diff --git a/test/CodeGen/Generic/GC/badrootproto.ll b/test/CodeGen/Generic/GC/badrootproto.ll
new file mode 100644 (file)
index 0000000..1b9d856
--- /dev/null
@@ -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)
+}
diff --git a/test/CodeGen/Generic/GC/badwriteproto.ll b/test/CodeGen/Generic/GC/badwriteproto.ll
new file mode 100644 (file)
index 0000000..3682fc4
--- /dev/null
@@ -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)
index 2dbbc83..4b0a174 100644 (file)
@@ -1,6 +1,6 @@
 ; RUN: llvm-as < %s | llc
 
-       %Env = type opaque*
+       %Env = type i8*
 
 define void @.main(%Env) {
        %Root = alloca %Env