llvm.org GIT mirror llvm / 8c33da5
Fix for PR1633: Verifier doesn't fully verify GC intrinsics LLVM now enforces the following prototypes for the write barriers: <ty>* @llvm.gcread(<ty2>*, <ty>**) void @llvm.gcwrite(<ty>*, <ty2>*, <ty>**) And for @llvm.gcroot, the first stack slot is verified to be an alloca or a bitcast of an alloca. Fixes test/CodeGen/Generic/GC/lower_gcroot.ll, which violated these. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42051 91177308-0d34-0410-b5e6-96231b3b80d8 Gordon Henriksen 13 years ago
7 changed file(s) with 108 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
10711071 InstsInThisBlock.insert(&I);
10721072 }
10731073
1074 static bool HasPtrPtrType(Value *Val) {
1075 if (const PointerType *PtrTy = dyn_cast(Val->getType()))
1076 return isa(PtrTy->getElementType());
1077 return false;
1078 }
1079
1080 static Value *StripBitCasts(Value *Val) {
1081 if (BitCastInst *CI = dyn_cast(Val))
1082 return StripBitCasts(CI->getOperand(0));
1083 return Val;
1084 }
1085
10741086 /// visitIntrinsicFunction - Allow intrinsics to be verified in different ways.
10751087 ///
10761088 void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
10811093 #define GET_INTRINSIC_VERIFIER
10821094 #include "llvm/Intrinsics.gen"
10831095 #undef GET_INTRINSIC_VERIFIER
1096
1097 switch (ID) {
1098 default:
1099 break;
1100 case Intrinsic::gcroot:
1101 Assert1(HasPtrPtrType(CI.getOperand(1)),
1102 "llvm.gcroot parameter #1 must be a pointer to a pointer.", &CI);
1103 Assert1(isa(StripBitCasts(CI.getOperand(1))),
1104 "llvm.gcroot parameter #1 must be an alloca (or a bitcast).", &CI);
1105 Assert1(isa(CI.getOperand(2)),
1106 "llvm.gcroot parameter #2 must be a constant or global.", &CI);
1107 break;
1108 case Intrinsic::gcwrite:
1109 Assert1(CI.getOperand(3)->getType()
1110 == PointerType::get(CI.getOperand(1)->getType()),
1111 "Call to llvm.gcwrite must be with type 'void (%ty*, %ty2*, %ty**)'.",
1112 &CI);
1113 break;
1114 case Intrinsic::gcread:
1115 Assert1(CI.getOperand(2)->getType() == PointerType::get(CI.getType()),
1116 "Call to llvm.gcread must be with type '%ty* (%ty2*, %ty**).'",
1117 &CI);
1118 break;
1119 }
10841120 }
10851121
10861122 /// VerifyIntrinsicPrototype - TableGen emits calls to this function into
22 %Env = type opaque*
33
44 define void @.main(%Env) {
5 call void @llvm.gcroot( %Env* null, %Env null )
5 %Root = alloca %Env
6 call void @llvm.gcroot( %Env* %Root, %Env null )
67 unreachable
78 }
89
0 ; RUN: not llvm-as < %s
1 ; PR1633
2
3 %meta = type { i8* }
4 %obj = type { %meta* }
5
6 declare %obj* @llvm.gcread(%obj*, %obj*)
7
8 define %obj* @f() {
9 entry:
10 %x = call %obj* @llvm.gcread(%obj* null, %obj* null)
11 ret %obj* %x
12 }
0 ; RUN: not llvm-as < %s
1 ; PR1633
2
3 %meta = type { i8* }
4 %obj = type { %meta* }
5
6 declare void @llvm.gcroot(%obj**, %meta*)
7
8 define void @f() {
9 entry:
10 call void @llvm.gcroot(%obj** null, %meta* null)
11
12 ret void
13 }
0 ; RUN: not llvm-as < %s
1 ; PR1633
2
3 %meta = type { i8* }
4 %obj = type { %meta* }
5
6 declare void @llvm.gcroot(%obj**, %meta*)
7
8 define void @f() {
9 entry:
10 %local.obj = alloca %obj*
11 %local.meta = alloca %meta
12 call void @llvm.gcroot(%obj** %local.obj, %meta* %local.meta)
13
14 ret void
15 }
0 ; RUN: not llvm-as < %s
1 ; PR1633
2
3 %meta = type { i8* }
4 %obj = type { %meta* }
5
6 declare void @llvm.gcroot(%obj*, %meta*)
7
8 define void @f() {
9 entry:
10 %local.obj = alloca %obj
11 call void @llvm.gcroot(%obj* %local.obj, %meta* null)
12 ret void
13 }
0 ; RUN: not llvm-as < %s
1 ; PR1633
2
3 %meta = type { i8* }
4 %obj = type { %meta* }
5
6 declare void @llvm.gcwrite(%obj*, %obj*, %obj*)
7
8 define void @f() {
9 entry:
10 call void @llvm.gcwrite(%obj* null, %obj* null, %obj* null)
11 ret void
12 }