OLD | NEW |
---|---|
1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules ---------------===// | 1 //===- PNaClABIVerifyFunctions.cpp - Verify PNaCl ABI rules ---------------===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // Verify function-level PNaCl ABI requirements. | 10 // Verify function-level PNaCl ABI requirements. |
11 // | 11 // |
12 // | 12 // |
13 //===----------------------------------------------------------------------===// | 13 //===----------------------------------------------------------------------===// |
14 | 14 |
15 #include "llvm/ADT/Twine.h" | 15 #include "llvm/ADT/Twine.h" |
16 #include "llvm/Analysis/NaCl.h" | 16 #include "llvm/Analysis/NaCl.h" |
17 #include "llvm/IR/Function.h" | 17 #include "llvm/IR/Function.h" |
18 #include "llvm/IR/Instructions.h" | 18 #include "llvm/IR/Instructions.h" |
19 #include "llvm/IR/IntrinsicInst.h" | 19 #include "llvm/IR/IntrinsicInst.h" |
20 #include "llvm/IR/LLVMContext.h" | 20 #include "llvm/IR/LLVMContext.h" |
21 #include "llvm/IR/Metadata.h" | 21 #include "llvm/IR/Metadata.h" |
22 #include "llvm/IR/NaClIntrinsics.h" | |
22 #include "llvm/IR/Operator.h" | 23 #include "llvm/IR/Operator.h" |
23 #include "llvm/Pass.h" | 24 #include "llvm/Pass.h" |
24 #include "llvm/Support/raw_ostream.h" | 25 #include "llvm/Support/raw_ostream.h" |
25 | 26 |
26 #include "PNaClABITypeChecker.h" | 27 #include "PNaClABITypeChecker.h" |
27 using namespace llvm; | 28 using namespace llvm; |
28 | 29 |
29 namespace { | 30 namespace { |
30 | 31 |
31 // Checks that examine anything in the function body should be in | 32 // Checks that examine anything in the function body should be in |
(...skipping 14 matching lines...) Expand all Loading... | |
46 initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry()); | 47 initializePNaClABIVerifyFunctionsPass(*PassRegistry::getPassRegistry()); |
47 } | 48 } |
48 ~PNaClABIVerifyFunctions() { | 49 ~PNaClABIVerifyFunctions() { |
49 if (ReporterIsOwned) | 50 if (ReporterIsOwned) |
50 delete Reporter; | 51 delete Reporter; |
51 } | 52 } |
52 bool runOnFunction(Function &F); | 53 bool runOnFunction(Function &F); |
53 virtual void print(raw_ostream &O, const Module *M) const; | 54 virtual void print(raw_ostream &O, const Module *M) const; |
54 private: | 55 private: |
55 bool IsWhitelistedMetadata(unsigned MDKind); | 56 bool IsWhitelistedMetadata(unsigned MDKind); |
56 const char *checkInstruction(const Instruction *Inst); | 57 const char *checkInstruction(LLVMContext &C, const NaCl::AtomicIntrinsics &AI, |
58 const Instruction *Inst); | |
57 PNaClABIErrorReporter *Reporter; | 59 PNaClABIErrorReporter *Reporter; |
58 bool ReporterIsOwned; | 60 bool ReporterIsOwned; |
59 }; | 61 }; |
60 | 62 |
61 } // and anonymous namespace | 63 } // and anonymous namespace |
62 | 64 |
63 // There's no built-in way to get the name of an MDNode, so use a | 65 // There's no built-in way to get the name of an MDNode, so use a |
64 // string ostream to print it. | 66 // string ostream to print it. |
65 static std::string getMDNodeString(unsigned Kind, | 67 static std::string getMDNodeString(unsigned Kind, |
66 const SmallVectorImpl<StringRef> &MDNames) { | 68 const SmallVectorImpl<StringRef> &MDNames) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val)) | 133 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val)) |
132 return true; | 134 return true; |
133 | 135 |
134 // Allow some Constants. Note that this excludes ConstantExprs. | 136 // Allow some Constants. Note that this excludes ConstantExprs. |
135 return PNaClABITypeChecker::isValidScalarType(Val->getType()) && | 137 return PNaClABITypeChecker::isValidScalarType(Val->getType()) && |
136 (isa<ConstantInt>(Val) || | 138 (isa<ConstantInt>(Val) || |
137 isa<ConstantFP>(Val) || | 139 isa<ConstantFP>(Val) || |
138 isa<UndefValue>(Val)); | 140 isa<UndefValue>(Val)); |
139 } | 141 } |
140 | 142 |
141 static bool isAllowedAlignment(unsigned Alignment, Type *Ty, bool IsAtomic) { | 143 static bool isAllowedAlignment(unsigned Alignment, Type *Ty) { |
142 if (IsAtomic) { | |
143 // For atomic operations, the alignment must match the size of the type. | |
144 if (Ty->isIntegerTy()) { | |
145 unsigned Bits = Ty->getIntegerBitWidth(); | |
146 return Bits % 8 == 0 && Alignment == Bits / 8; | |
147 } | |
148 return (Ty->isDoubleTy() && Alignment == 8) || | |
149 (Ty->isFloatTy() && Alignment == 4); | |
150 } | |
151 // Non-atomic integer operations must always use "align 1", since we | 144 // Non-atomic integer operations must always use "align 1", since we |
152 // do not want the backend to generate code with non-portable | 145 // do not want the backend to generate code with non-portable |
153 // undefined behaviour (such as misaligned access faults) if user | 146 // undefined behaviour (such as misaligned access faults) if user |
154 // code specifies "align 4" but uses a misaligned pointer. As a | 147 // code specifies "align 4" but uses a misaligned pointer. As a |
155 // concession to performance, we allow larger alignment values for | 148 // concession to performance, we allow larger alignment values for |
156 // floating point types. | 149 // floating point types. |
157 // | 150 // |
158 // To reduce the set of alignment values that need to be encoded in | 151 // To reduce the set of alignment values that need to be encoded in |
159 // pexes, we disallow other alignment values. We require alignments | 152 // pexes, we disallow other alignment values. We require alignments |
160 // to be explicit by disallowing Alignment == 0. | 153 // to be explicit by disallowing Alignment == 0. |
161 return Alignment == 1 || | 154 return Alignment == 1 || |
162 (Ty->isDoubleTy() && Alignment == 8) || | 155 (Ty->isDoubleTy() && Alignment == 8) || |
163 (Ty->isFloatTy() && Alignment == 4); | 156 (Ty->isFloatTy() && Alignment == 4); |
164 } | 157 } |
165 | 158 |
159 static bool hasAllowedAtomicRMWOperation( | |
160 NaCl::AtomicIntrinsics::const_iterator AI, const CallInst *Call) { | |
161 for (size_t P = 0; P != NaCl::MaxAtomicIntrinsicsParameters; ++P) { | |
162 if (AI->ParamType[P] != NaCl::AtomicIntrinsics::RMW) | |
163 continue; | |
164 | |
165 const Value *Operation = Call->getOperand(P); | |
166 if (!Operation) | |
167 return false; | |
168 const Constant *C = dyn_cast<Constant>(Operation); | |
169 if (!C) | |
170 return false; | |
171 const APInt &I = C->getUniqueInteger(); | |
172 if (I.ule(NaCl::AtomicInvalid) || I.uge(NaCl::AtomicNum)) | |
173 return false; | |
174 } | |
175 return true; | |
176 } | |
177 | |
178 static bool hasAllowedAtomicMemoryOrder( | |
179 NaCl::AtomicIntrinsics::const_iterator AI, const CallInst *Call) { | |
180 for (size_t P = 0; P != NaCl::MaxAtomicIntrinsicsParameters; ++P) { | |
181 if (AI->ParamType[P] != NaCl::AtomicIntrinsics::Mem) | |
182 continue; | |
183 | |
184 const Value *MemoryOrder = Call->getOperand(P); | |
185 if (!MemoryOrder) | |
186 return false; | |
187 const Constant *C = dyn_cast<Constant>(MemoryOrder); | |
188 if (!C) | |
189 return false; | |
190 const APInt &I = C->getUniqueInteger(); | |
191 if (I.ule(NaCl::MemoryOrderInvalid) || I.uge(NaCl::MemoryOrderNum)) | |
192 return false; | |
193 // TODO For now only sequential consistency is allowed. When more | |
194 // are allowed we need to validate that the memory order is | |
195 // allowed on the specific atomic operation (e.g. no store | |
196 // acquire, and relationship between success/failure memory | |
197 // order on compare exchange). | |
198 if (I != NaCl::MemoryOrderSequentiallyConsistent) | |
199 return false; | |
200 } | |
201 return true; | |
202 } | |
203 | |
166 // Check the instruction's opcode and its operands. The operands may | 204 // Check the instruction's opcode and its operands. The operands may |
167 // require opcode-specific checking. | 205 // require opcode-specific checking. |
168 // | 206 // |
169 // This returns an error string if the instruction is rejected, or | 207 // This returns an error string if the instruction is rejected, or |
170 // NULL if the instruction is allowed. | 208 // NULL if the instruction is allowed. |
171 const char *PNaClABIVerifyFunctions::checkInstruction(const Instruction *Inst) { | 209 const char *PNaClABIVerifyFunctions::checkInstruction(LLVMContext &C, |
210 const NaCl::AtomicIntrinsics &AI, const Instruction *Inst) { | |
172 // If the instruction has a single pointer operand, PtrOperandIndex is | 211 // If the instruction has a single pointer operand, PtrOperandIndex is |
173 // set to its operand index. | 212 // set to its operand index. |
174 unsigned PtrOperandIndex = -1; | 213 unsigned PtrOperandIndex = -1; |
175 | 214 |
176 switch (Inst->getOpcode()) { | 215 switch (Inst->getOpcode()) { |
177 // Disallowed instructions. Default is to disallow. | 216 // Disallowed instructions. Default is to disallow. |
178 // We expand GetElementPtr out into arithmetic. | 217 // We expand GetElementPtr out into arithmetic. |
179 case Instruction::GetElementPtr: | 218 case Instruction::GetElementPtr: |
180 // VAArg is expanded out by ExpandVarArgs. | 219 // VAArg is expanded out by ExpandVarArgs. |
181 case Instruction::VAArg: | 220 case Instruction::VAArg: |
182 // Zero-cost C++ exception handling is not supported yet. | 221 // Zero-cost C++ exception handling is not supported yet. |
183 case Instruction::Invoke: | 222 case Instruction::Invoke: |
184 case Instruction::LandingPad: | 223 case Instruction::LandingPad: |
185 case Instruction::Resume: | 224 case Instruction::Resume: |
186 // indirectbr may interfere with streaming | 225 // indirectbr may interfere with streaming |
187 case Instruction::IndirectBr: | 226 case Instruction::IndirectBr: |
188 // No vector instructions yet | 227 // No vector instructions yet |
189 case Instruction::ExtractElement: | 228 case Instruction::ExtractElement: |
190 case Instruction::InsertElement: | 229 case Instruction::InsertElement: |
191 case Instruction::ShuffleVector: | 230 case Instruction::ShuffleVector: |
192 // ExtractValue and InsertValue operate on struct values. | 231 // ExtractValue and InsertValue operate on struct values. |
193 case Instruction::ExtractValue: | 232 case Instruction::ExtractValue: |
194 case Instruction::InsertValue: | 233 case Instruction::InsertValue: |
234 // Atomics should become NaCl intrinsics. | |
235 case Instruction::AtomicCmpXchg: | |
236 case Instruction::AtomicRMW: | |
237 case Instruction::Fence: | |
195 return "bad instruction opcode"; | 238 return "bad instruction opcode"; |
196 default: | 239 default: |
197 return "unknown instruction opcode"; | 240 return "unknown instruction opcode"; |
198 | 241 |
199 // Terminator instructions | 242 // Terminator instructions |
200 case Instruction::Ret: | 243 case Instruction::Ret: |
201 case Instruction::Br: | 244 case Instruction::Br: |
202 case Instruction::Unreachable: | 245 case Instruction::Unreachable: |
203 // Binary operations | 246 // Binary operations |
204 case Instruction::Add: | 247 case Instruction::Add: |
205 case Instruction::FAdd: | 248 case Instruction::FAdd: |
206 case Instruction::Sub: | 249 case Instruction::Sub: |
207 case Instruction::FSub: | 250 case Instruction::FSub: |
208 case Instruction::Mul: | 251 case Instruction::Mul: |
209 case Instruction::FMul: | 252 case Instruction::FMul: |
210 case Instruction::UDiv: | 253 case Instruction::UDiv: |
211 case Instruction::SDiv: | 254 case Instruction::SDiv: |
212 case Instruction::FDiv: | 255 case Instruction::FDiv: |
213 case Instruction::URem: | 256 case Instruction::URem: |
214 case Instruction::SRem: | 257 case Instruction::SRem: |
215 case Instruction::FRem: | 258 case Instruction::FRem: |
216 // Bitwise binary operations | 259 // Bitwise binary operations |
217 case Instruction::Shl: | 260 case Instruction::Shl: |
218 case Instruction::LShr: | 261 case Instruction::LShr: |
219 case Instruction::AShr: | 262 case Instruction::AShr: |
220 case Instruction::And: | 263 case Instruction::And: |
221 case Instruction::Or: | 264 case Instruction::Or: |
222 case Instruction::Xor: | 265 case Instruction::Xor: |
223 // Memory instructions | |
224 case Instruction::Fence: | |
225 // Conversion operations | 266 // Conversion operations |
226 case Instruction::Trunc: | 267 case Instruction::Trunc: |
227 case Instruction::ZExt: | 268 case Instruction::ZExt: |
228 case Instruction::SExt: | 269 case Instruction::SExt: |
229 case Instruction::FPTrunc: | 270 case Instruction::FPTrunc: |
230 case Instruction::FPExt: | 271 case Instruction::FPExt: |
231 case Instruction::FPToUI: | 272 case Instruction::FPToUI: |
232 case Instruction::FPToSI: | 273 case Instruction::FPToSI: |
233 case Instruction::UIToFP: | 274 case Instruction::UIToFP: |
234 case Instruction::SIToFP: | 275 case Instruction::SIToFP: |
235 // Other operations | 276 // Other operations |
236 case Instruction::ICmp: | 277 case Instruction::ICmp: |
237 case Instruction::FCmp: | 278 case Instruction::FCmp: |
238 case Instruction::PHI: | 279 case Instruction::PHI: |
239 case Instruction::Select: | 280 case Instruction::Select: |
240 break; | 281 break; |
241 | 282 |
242 // Memory accesses. | 283 // Memory accesses. |
243 case Instruction::Load: { | 284 case Instruction::Load: { |
244 const LoadInst *Load = cast<LoadInst>(Inst); | 285 const LoadInst *Load = cast<LoadInst>(Inst); |
286 PtrOperandIndex = Load->getPointerOperandIndex(); | |
287 if (Load->isAtomic()) | |
288 return "atomic"; | |
289 if (Load->isVolatile()) | |
290 return "volatile"; | |
245 if (!isAllowedAlignment(Load->getAlignment(), | 291 if (!isAllowedAlignment(Load->getAlignment(), |
246 Load->getType(), | 292 Load->getType())) |
247 Load->isAtomic())) | |
248 return "bad alignment"; | 293 return "bad alignment"; |
249 PtrOperandIndex = 0; | |
250 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 294 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
251 return "bad pointer"; | 295 return "bad pointer"; |
252 break; | 296 break; |
253 } | 297 } |
254 case Instruction::Store: { | 298 case Instruction::Store: { |
255 const StoreInst *Store = cast<StoreInst>(Inst); | 299 const StoreInst *Store = cast<StoreInst>(Inst); |
300 PtrOperandIndex = Store->getPointerOperandIndex(); | |
301 if (Store->isAtomic()) | |
302 return "atomic"; | |
303 if (Store->isVolatile()) | |
304 return "volatile"; | |
256 if (!isAllowedAlignment(Store->getAlignment(), | 305 if (!isAllowedAlignment(Store->getAlignment(), |
257 Store->getValueOperand()->getType(), | 306 Store->getValueOperand()->getType())) |
258 Store->isAtomic())) | |
259 return "bad alignment"; | 307 return "bad alignment"; |
260 PtrOperandIndex = 1; | |
261 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 308 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
262 return "bad pointer"; | 309 return "bad pointer"; |
263 break; | 310 break; |
264 } | 311 } |
265 case Instruction::AtomicCmpXchg: | |
266 case Instruction::AtomicRMW: | |
267 PtrOperandIndex = 0; | |
268 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | |
269 return "bad pointer"; | |
270 break; | |
271 | 312 |
272 // Casts. | 313 // Casts. |
273 case Instruction::BitCast: | 314 case Instruction::BitCast: |
274 if (Inst->getType()->isPointerTy()) { | 315 if (Inst->getType()->isPointerTy()) { |
275 PtrOperandIndex = 0; | 316 PtrOperandIndex = 0; |
276 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex))) | 317 if (!isInherentPtr(Inst->getOperand(PtrOperandIndex))) |
277 return "operand not InherentPtr"; | 318 return "operand not InherentPtr"; |
278 } | 319 } |
279 break; | 320 break; |
280 case Instruction::IntToPtr: | 321 case Instruction::IntToPtr: |
(...skipping 27 matching lines...) Expand all Loading... | |
308 // metadata arguments, so handle them specially. | 349 // metadata arguments, so handle them specially. |
309 if (const IntrinsicInst *Call = dyn_cast<IntrinsicInst>(Inst)) { | 350 if (const IntrinsicInst *Call = dyn_cast<IntrinsicInst>(Inst)) { |
310 for (unsigned ArgNum = 0, E = Call->getNumArgOperands(); | 351 for (unsigned ArgNum = 0, E = Call->getNumArgOperands(); |
311 ArgNum < E; ++ArgNum) { | 352 ArgNum < E; ++ArgNum) { |
312 const Value *Arg = Call->getArgOperand(ArgNum); | 353 const Value *Arg = Call->getArgOperand(ArgNum); |
313 if (!(isValidScalarOperand(Arg) || | 354 if (!(isValidScalarOperand(Arg) || |
314 isNormalizedPtr(Arg) || | 355 isNormalizedPtr(Arg) || |
315 isa<MDNode>(Arg))) | 356 isa<MDNode>(Arg))) |
316 return "bad intrinsic operand"; | 357 return "bad intrinsic operand"; |
317 } | 358 } |
359 | |
318 // Disallow alignments other than 1 on memcpy() etc., for the | 360 // Disallow alignments other than 1 on memcpy() etc., for the |
319 // same reason that we disallow them on integer loads and | 361 // same reason that we disallow them on integer loads and |
320 // stores. | 362 // stores. |
321 if (const MemIntrinsic *MemOp = dyn_cast<MemIntrinsic>(Call)) { | 363 if (const MemIntrinsic *MemOp = dyn_cast<MemIntrinsic>(Call)) { |
322 // Avoid the getAlignment() method here because it aborts if | 364 // Avoid the getAlignment() method here because it aborts if |
323 // the alignment argument is not a Constant. | 365 // the alignment argument is not a Constant. |
324 Value *AlignArg = MemOp->getArgOperand(3); | 366 Value *AlignArg = MemOp->getArgOperand(3); |
325 if (!isa<ConstantInt>(AlignArg) || | 367 if (!isa<ConstantInt>(AlignArg) || |
326 cast<ConstantInt>(AlignArg)->getZExtValue() != 1) { | 368 cast<ConstantInt>(AlignArg)->getZExtValue() != 1) { |
327 return "bad alignment"; | 369 return "bad alignment"; |
328 } | 370 } |
329 } | 371 } |
372 | |
373 // Disallow NaCl atomic intrinsics which don't have valid | |
374 // constant NaCl::AtomicOperation and NaCl::MemoryOrder | |
375 // parameters. | |
376 switch (Call->getIntrinsicID()) { | |
Mark Seaborn
2013/07/02 19:16:02
Fix indentation: reduce by 2
JF
2013/07/02 23:14:54
This is inconsistent with the rest of the file.
Mark Seaborn
2013/07/02 23:34:10
This 'switch' statement doesn't line up with the c
JF
2013/07/02 23:49:04
Done.
| |
377 default: break; // Non-atomic intrinsic. | |
378 case Intrinsic::nacl_atomic_load: | |
379 case Intrinsic::nacl_atomic_store: | |
380 case Intrinsic::nacl_atomic_rmw: | |
381 case Intrinsic::nacl_atomic_cmpxchg: | |
382 case Intrinsic::nacl_atomic_fence: { | |
383 NaCl::AtomicIntrinsics::const_iterator I = | |
384 AI.find(Call->getIntrinsicID(), Type::getInt32Ty(C)); | |
385 if (!hasAllowedAtomicMemoryOrder(I, Call)) | |
386 return "invalid memory order"; | |
387 if (!hasAllowedAtomicRMWOperation(I, Call)) | |
388 return "invalid atomicRMW operation"; | |
389 } break; | |
Mark Seaborn
2013/07/02 19:16:02
"break" should go inside the {} block.
JF
2013/07/02 23:14:54
There's enough code this way in the code base, and
| |
390 } | |
391 | |
330 // Allow the instruction and skip the later checks. | 392 // Allow the instruction and skip the later checks. |
331 return NULL; | 393 return NULL; |
332 } | 394 } |
333 | 395 |
334 // The callee is the last operand. | 396 // The callee is the last operand. |
335 PtrOperandIndex = Inst->getNumOperands() - 1; | 397 PtrOperandIndex = Inst->getNumOperands() - 1; |
336 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 398 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
337 return "bad function callee operand"; | 399 return "bad function callee operand"; |
338 break; | 400 break; |
339 } | 401 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 if (Op->isExact()) | 450 if (Op->isExact()) |
389 return "has \"exact\" attribute"; | 451 return "has \"exact\" attribute"; |
390 } | 452 } |
391 | 453 |
392 // Allow the instruction. | 454 // Allow the instruction. |
393 return NULL; | 455 return NULL; |
394 } | 456 } |
395 | 457 |
396 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { | 458 bool PNaClABIVerifyFunctions::runOnFunction(Function &F) { |
397 SmallVector<StringRef, 8> MDNames; | 459 SmallVector<StringRef, 8> MDNames; |
398 F.getContext().getMDKindNames(MDNames); | 460 LLVMContext &C = F.getContext(); |
Mark Seaborn
2013/07/02 19:16:02
Nit: 'C' -> 'Context'. This isn't used often enou
JF
2013/07/02 23:14:54
It's pretty much split in the middle on C versus C
| |
461 C.getMDKindNames(MDNames); | |
462 | |
463 NaCl::AtomicIntrinsics AI(C); | |
399 | 464 |
400 for (Function::const_iterator FI = F.begin(), FE = F.end(); | 465 for (Function::const_iterator FI = F.begin(), FE = F.end(); |
401 FI != FE; ++FI) { | 466 FI != FE; ++FI) { |
402 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); | 467 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); |
403 BBI != BBE; ++BBI) { | 468 BBI != BBE; ++BBI) { |
404 const Instruction *Inst = BBI; | 469 const Instruction *Inst = BBI; |
405 // Check the instruction opcode first. This simplifies testing, | 470 // Check the instruction opcode first. This simplifies testing, |
406 // because some instruction opcodes must be rejected out of hand | 471 // because some instruction opcodes must be rejected out of hand |
407 // (regardless of the instruction's result type) and the tests | 472 // (regardless of the instruction's result type) and the tests |
408 // check the reason for rejection. | 473 // check the reason for rejection. |
409 const char *Error = checkInstruction(BBI); | 474 const char *Error = checkInstruction(C, AI, BBI); |
410 // Check the instruction's result type. | 475 // Check the instruction's result type. |
411 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) || | 476 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) || |
412 isNormalizedPtr(Inst) || | 477 isNormalizedPtr(Inst) || |
413 isa<AllocaInst>(Inst))) { | 478 isa<AllocaInst>(Inst))) { |
414 Error = "bad result type"; | 479 Error = "bad result type"; |
415 } | 480 } |
416 if (Error) { | 481 if (Error) { |
417 Reporter->addError() << "Function " << F.getName() << | 482 Reporter->addError() << "Function " << F.getName() << |
418 " disallowed: " << Error << ": " << *BBI << "\n"; | 483 " disallowed: " << Error << ": " << *BBI << "\n"; |
419 } | 484 } |
(...skipping 27 matching lines...) Expand all Loading... | |
447 } | 512 } |
448 | 513 |
449 char PNaClABIVerifyFunctions::ID = 0; | 514 char PNaClABIVerifyFunctions::ID = 0; |
450 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", | 515 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", |
451 "Verify functions for PNaCl", false, true) | 516 "Verify functions for PNaCl", false, true) |
452 | 517 |
453 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( | 518 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( |
454 PNaClABIErrorReporter *Reporter) { | 519 PNaClABIErrorReporter *Reporter) { |
455 return new PNaClABIVerifyFunctions(Reporter); | 520 return new PNaClABIVerifyFunctions(Reporter); |
456 } | 521 } |
OLD | NEW |