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. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
81 } | 81 } |
82 return N.str(); | 82 return N.str(); |
83 } | 83 } |
84 | 84 |
85 bool PNaClABIVerifyFunctions::IsWhitelistedMetadata(unsigned MDKind) { | 85 bool PNaClABIVerifyFunctions::IsWhitelistedMetadata(unsigned MDKind) { |
86 return MDKind == LLVMContext::MD_dbg && PNaClABIAllowDebugMetadata; | 86 return MDKind == LLVMContext::MD_dbg && PNaClABIAllowDebugMetadata; |
87 } | 87 } |
88 | 88 |
89 // A valid pointer type is either: | 89 // A valid pointer type is either: |
90 // * a pointer to a valid PNaCl scalar type (except i1), or | 90 // * a pointer to a valid PNaCl scalar type (except i1), or |
91 // * a pointer to a valid PNaCl vector type (except i1 vector), or | |
Mark Seaborn
2014/04/09 15:03:03
If you're not allowing loads/stores of vectors yet
JF
2014/04/15 18:22:15
Done, and I updated the corresponding tests.
| |
91 // * a function pointer (with valid argument and return types). | 92 // * a function pointer (with valid argument and return types). |
92 // | 93 // |
93 // i1 is disallowed so that all loads and stores are a whole number of | 94 // i1 is disallowed so that all loads and stores are a whole number of |
94 // bytes, and so that we do not need to define whether a store of i1 | 95 // bytes, and so that we do not need to define whether a store of i1 |
95 // zero-extends. | 96 // zero-extends. |
96 static bool isValidPointerType(Type *Ty) { | 97 static bool isValidPointerType(Type *Ty) { |
97 if (PointerType *PtrTy = dyn_cast<PointerType>(Ty)) { | 98 if (PointerType *PtrTy = dyn_cast<PointerType>(Ty)) { |
98 if (PtrTy->getAddressSpace() != 0) | 99 if (PtrTy->getAddressSpace() != 0) |
99 return false; | 100 return false; |
100 Type *EltTy = PtrTy->getElementType(); | 101 Type *EltTy = PtrTy->getElementType(); |
101 if (PNaClABITypeChecker::isValidScalarType(EltTy) && | 102 if ((PNaClABITypeChecker::isValidScalarType(EltTy) && |
102 !EltTy->isIntegerTy(1)) | 103 !EltTy->isIntegerTy(1)) || |
104 (PNaClABITypeChecker::isValidVectorType(EltTy) && | |
105 !cast<VectorType>(EltTy)->getElementType()->isIntegerTy(1))) | |
103 return true; | 106 return true; |
104 if (FunctionType *FTy = dyn_cast<FunctionType>(EltTy)) | 107 if (FunctionType *FTy = dyn_cast<FunctionType>(EltTy)) |
105 return PNaClABITypeChecker::isValidFunctionType(FTy); | 108 return PNaClABITypeChecker::isValidFunctionType(FTy); |
106 } | 109 } |
107 return false; | 110 return false; |
108 } | 111 } |
109 | 112 |
110 static bool isIntrinsicFunc(const Value *Val) { | 113 static bool isIntrinsicFunc(const Value *Val) { |
111 if (const Function *F = dyn_cast<Function>(Val)) | 114 if (const Function *F = dyn_cast<Function>(Val)) |
112 return F->isIntrinsic(); | 115 return F->isIntrinsic(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val)) | 148 if (isa<Instruction>(Val) || isa<Argument>(Val) || isa<BasicBlock>(Val)) |
146 return true; | 149 return true; |
147 | 150 |
148 // Allow some Constants. Note that this excludes ConstantExprs. | 151 // Allow some Constants. Note that this excludes ConstantExprs. |
149 return PNaClABITypeChecker::isValidScalarType(Val->getType()) && | 152 return PNaClABITypeChecker::isValidScalarType(Val->getType()) && |
150 (isa<ConstantInt>(Val) || | 153 (isa<ConstantInt>(Val) || |
151 isa<ConstantFP>(Val) || | 154 isa<ConstantFP>(Val) || |
152 isa<UndefValue>(Val)); | 155 isa<UndefValue>(Val)); |
153 } | 156 } |
154 | 157 |
158 static bool isValidVectorOperand(const Value *Val) { | |
159 // The types of Instructions and Arguments are checked elsewhere. | |
160 if (isa<Instruction>(Val) || isa<Argument>(Val)) | |
161 return true; | |
162 // Contrary to scalars, constant vector values aren't allowed on | |
163 // instructions, except for aggregate zero and undefined. | |
164 return PNaClABITypeChecker::isValidVectorType(Val->getType()) && | |
165 (isa<ConstantAggregateZero>(Val) || isa<UndefValue>(Val)); | |
166 } | |
167 | |
155 static bool isAllowedAlignment(unsigned Alignment, Type *Ty) { | 168 static bool isAllowedAlignment(unsigned Alignment, Type *Ty) { |
156 // Non-atomic integer operations must always use "align 1", since we | 169 // Non-atomic integer operations must always use "align 1", since we |
157 // do not want the backend to generate code with non-portable | 170 // do not want the backend to generate code with non-portable |
158 // undefined behaviour (such as misaligned access faults) if user | 171 // undefined behaviour (such as misaligned access faults) if user |
159 // code specifies "align 4" but uses a misaligned pointer. As a | 172 // code specifies "align 4" but uses a misaligned pointer. As a |
160 // concession to performance, we allow larger alignment values for | 173 // concession to performance, we allow larger alignment values for |
161 // floating point types. | 174 // floating point types. |
162 // | 175 // |
163 // To reduce the set of alignment values that need to be encoded in | 176 // To reduce the set of alignment values that need to be encoded in |
164 // pexes, we disallow other alignment values. We require alignments | 177 // pexes, we disallow other alignment values. We require alignments |
165 // to be explicit by disallowing Alignment == 0. | 178 // to be explicit by disallowing Alignment == 0. |
179 // | |
180 // Vector memory accesses go through their scalar elements, there is | |
181 // therefore no such thing as vector alignment. | |
166 return Alignment == 1 || | 182 return Alignment == 1 || |
167 (Ty->isDoubleTy() && Alignment == 8) || | 183 (Ty->isDoubleTy() && Alignment == 8) || |
168 (Ty->isFloatTy() && Alignment == 4); | 184 (Ty->isFloatTy() && Alignment == 4); |
169 } | 185 } |
170 | 186 |
171 static bool hasAllowedAtomicRMWOperation( | 187 static bool hasAllowedAtomicRMWOperation( |
172 const NaCl::AtomicIntrinsics::AtomicIntrinsic *I, const CallInst *Call) { | 188 const NaCl::AtomicIntrinsics::AtomicIntrinsic *I, const CallInst *Call) { |
173 for (size_t P = 0; P != I->NumParams; ++P) { | 189 for (size_t P = 0; P != I->NumParams; ++P) { |
174 if (I->ParamType[P] != NaCl::AtomicIntrinsics::RMW) | 190 if (I->ParamType[P] != NaCl::AtomicIntrinsics::RMW) |
175 continue; | 191 continue; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
246 // We expand GetElementPtr out into arithmetic. | 262 // We expand GetElementPtr out into arithmetic. |
247 case Instruction::GetElementPtr: | 263 case Instruction::GetElementPtr: |
248 // VAArg is expanded out by ExpandVarArgs. | 264 // VAArg is expanded out by ExpandVarArgs. |
249 case Instruction::VAArg: | 265 case Instruction::VAArg: |
250 // Zero-cost C++ exception handling is not supported yet. | 266 // Zero-cost C++ exception handling is not supported yet. |
251 case Instruction::Invoke: | 267 case Instruction::Invoke: |
252 case Instruction::LandingPad: | 268 case Instruction::LandingPad: |
253 case Instruction::Resume: | 269 case Instruction::Resume: |
254 // indirectbr may interfere with streaming | 270 // indirectbr may interfere with streaming |
255 case Instruction::IndirectBr: | 271 case Instruction::IndirectBr: |
256 // No vector instructions yet | 272 // TODO(jfb) Figure out ShuffleVector. |
257 case Instruction::ExtractElement: | |
258 case Instruction::InsertElement: | |
259 case Instruction::ShuffleVector: | 273 case Instruction::ShuffleVector: |
260 // ExtractValue and InsertValue operate on struct values. | 274 // ExtractValue and InsertValue operate on struct values. |
261 case Instruction::ExtractValue: | 275 case Instruction::ExtractValue: |
262 case Instruction::InsertValue: | 276 case Instruction::InsertValue: |
263 // Atomics should become NaCl intrinsics. | 277 // Atomics should become NaCl intrinsics. |
264 case Instruction::AtomicCmpXchg: | 278 case Instruction::AtomicCmpXchg: |
265 case Instruction::AtomicRMW: | 279 case Instruction::AtomicRMW: |
266 case Instruction::Fence: | 280 case Instruction::Fence: |
267 return "bad instruction opcode"; | 281 return "bad instruction opcode"; |
268 default: | 282 default: |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
305 // Binary operations | 319 // Binary operations |
306 case Instruction::Add: | 320 case Instruction::Add: |
307 case Instruction::Sub: | 321 case Instruction::Sub: |
308 case Instruction::Mul: | 322 case Instruction::Mul: |
309 case Instruction::UDiv: | 323 case Instruction::UDiv: |
310 case Instruction::SDiv: | 324 case Instruction::SDiv: |
311 case Instruction::URem: | 325 case Instruction::URem: |
312 case Instruction::SRem: | 326 case Instruction::SRem: |
313 case Instruction::Shl: | 327 case Instruction::Shl: |
314 case Instruction::LShr: | 328 case Instruction::LShr: |
315 case Instruction::AShr: | 329 case Instruction::AShr: { |
316 if (Inst->getOperand(0)->getType()->isIntegerTy(1)) | 330 Type *Op0Ty = Inst->getOperand(0)->getType(); |
331 VectorType *Op0VTy = dyn_cast<VectorType>(Op0Ty); | |
332 if (Op0Ty->isIntegerTy(1) || | |
333 (Op0VTy && Op0VTy->getElementType()->isIntegerTy(1))) | |
Jim Stichnoth
2014/04/04 23:08:17
Is it possible to reasonably restructure this in t
JF
2014/04/15 01:52:27
Done, I separated the error message to distinguish
| |
317 return "arithmetic on i1"; | 334 return "arithmetic on i1"; |
318 break; | 335 break; |
336 } | |
337 | |
338 // Vector. | |
339 case Instruction::ExtractElement: | |
340 case Instruction::InsertElement: { | |
341 // Insert and extract element are restricted to constant indices | |
342 // that are in range to prevent undefined behavior. | |
343 Value *Vec = Inst->getOperand(0); | |
344 Value *Idx = Inst->getOperand( | |
345 Instruction::InsertElement == Inst->getOpcode() ? 2 : 1); | |
346 if (!isa<ConstantInt>(Idx)) | |
347 return "non-constant vector insert/extract index"; | |
348 const APInt &I = cast<ConstantInt>(Idx)->getValue(); | |
349 unsigned NumElements = cast<VectorType>(Vec->getType())->getNumElements(); | |
350 if (!I.ult(NumElements)) | |
351 return "out of range vector insert/extract index"; | |
352 break; | |
353 } | |
319 | 354 |
320 // Memory accesses. | 355 // Memory accesses. |
321 case Instruction::Load: { | 356 case Instruction::Load: { |
322 const LoadInst *Load = cast<LoadInst>(Inst); | 357 const LoadInst *Load = cast<LoadInst>(Inst); |
323 PtrOperandIndex = Load->getPointerOperandIndex(); | 358 PtrOperandIndex = Load->getPointerOperandIndex(); |
324 if (Load->isAtomic()) | 359 if (Load->isAtomic()) |
325 return "atomic load"; | 360 return "atomic load"; |
326 if (Load->isVolatile()) | 361 if (Load->isVolatile()) |
327 return "volatile load"; | 362 return "volatile load"; |
363 if (Load->getType()->isVectorTy()) | |
364 return "vector load"; | |
328 if (!isAllowedAlignment(Load->getAlignment(), | 365 if (!isAllowedAlignment(Load->getAlignment(), |
329 Load->getType())) | 366 Load->getType())) |
330 return "bad alignment"; | 367 return "bad alignment"; |
331 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 368 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
332 return "bad pointer"; | 369 return "bad pointer"; |
333 break; | 370 break; |
334 } | 371 } |
335 case Instruction::Store: { | 372 case Instruction::Store: { |
336 const StoreInst *Store = cast<StoreInst>(Inst); | 373 const StoreInst *Store = cast<StoreInst>(Inst); |
337 PtrOperandIndex = Store->getPointerOperandIndex(); | 374 PtrOperandIndex = Store->getPointerOperandIndex(); |
338 if (Store->isAtomic()) | 375 if (Store->isAtomic()) |
339 return "atomic store"; | 376 return "atomic store"; |
340 if (Store->isVolatile()) | 377 if (Store->isVolatile()) |
341 return "volatile store"; | 378 return "volatile store"; |
379 if (Store->getValueOperand()->getType()->isVectorTy()) | |
380 return "vector store"; | |
342 if (!isAllowedAlignment(Store->getAlignment(), | 381 if (!isAllowedAlignment(Store->getAlignment(), |
343 Store->getValueOperand()->getType())) | 382 Store->getValueOperand()->getType())) |
344 return "bad alignment"; | 383 return "bad alignment"; |
345 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) | 384 if (!isNormalizedPtr(Inst->getOperand(PtrOperandIndex))) |
346 return "bad pointer"; | 385 return "bad pointer"; |
347 break; | 386 break; |
348 } | 387 } |
349 | 388 |
350 // Casts. | 389 // Casts. |
351 case Instruction::BitCast: | 390 case Instruction::BitCast: |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
385 if (Call->getCallingConv() != CallingConv::C) | 424 if (Call->getCallingConv() != CallingConv::C) |
386 return "bad calling convention"; | 425 return "bad calling convention"; |
387 | 426 |
388 // Intrinsic calls can have multiple pointer arguments and | 427 // Intrinsic calls can have multiple pointer arguments and |
389 // metadata arguments, so handle them specially. | 428 // metadata arguments, so handle them specially. |
390 if (const IntrinsicInst *Call = dyn_cast<IntrinsicInst>(Inst)) { | 429 if (const IntrinsicInst *Call = dyn_cast<IntrinsicInst>(Inst)) { |
391 for (unsigned ArgNum = 0, E = Call->getNumArgOperands(); | 430 for (unsigned ArgNum = 0, E = Call->getNumArgOperands(); |
392 ArgNum < E; ++ArgNum) { | 431 ArgNum < E; ++ArgNum) { |
393 const Value *Arg = Call->getArgOperand(ArgNum); | 432 const Value *Arg = Call->getArgOperand(ArgNum); |
394 if (!(isValidScalarOperand(Arg) || | 433 if (!(isValidScalarOperand(Arg) || |
434 isValidVectorOperand(Arg) || | |
395 isNormalizedPtr(Arg) || | 435 isNormalizedPtr(Arg) || |
396 isa<MDNode>(Arg))) | 436 isa<MDNode>(Arg))) |
397 return "bad intrinsic operand"; | 437 return "bad intrinsic operand"; |
398 } | 438 } |
399 | 439 |
400 // Disallow alignments other than 1 on memcpy() etc., for the | 440 // Disallow alignments other than 1 on memcpy() etc., for the |
401 // same reason that we disallow them on integer loads and | 441 // same reason that we disallow them on integer loads and |
402 // stores. | 442 // stores. |
403 if (const MemIntrinsic *MemOp = dyn_cast<MemIntrinsic>(Call)) { | 443 if (const MemIntrinsic *MemOp = dyn_cast<MemIntrinsic>(Call)) { |
404 // Avoid the getAlignment() method here because it aborts if | 444 // Avoid the getAlignment() method here because it aborts if |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 if (!isValidScalarOperand(Case.getCaseValue())) | 509 if (!isValidScalarOperand(Case.getCaseValue())) |
470 return "bad switch case"; | 510 return "bad switch case"; |
471 } | 511 } |
472 | 512 |
473 // Allow the instruction and skip the later checks. | 513 // Allow the instruction and skip the later checks. |
474 return NULL; | 514 return NULL; |
475 } | 515 } |
476 } | 516 } |
477 | 517 |
478 // Check the instruction's operands. We have already checked any | 518 // Check the instruction's operands. We have already checked any |
479 // pointer operands. Any remaining operands must be scalars. | 519 // pointer operands. Any remaining operands must be scalars or vectors. |
480 for (unsigned OpNum = 0, E = Inst->getNumOperands(); OpNum < E; ++OpNum) { | 520 for (unsigned OpNum = 0, E = Inst->getNumOperands(); OpNum < E; ++OpNum) { |
481 if (OpNum != PtrOperandIndex && | 521 if (OpNum != PtrOperandIndex && |
482 !isValidScalarOperand(Inst->getOperand(OpNum))) | 522 !(isValidScalarOperand(Inst->getOperand(OpNum)) || |
523 isValidVectorOperand(Inst->getOperand(OpNum)))) | |
483 return "bad operand"; | 524 return "bad operand"; |
484 } | 525 } |
485 | 526 |
486 // Check arithmetic attributes. | 527 // Check arithmetic attributes. |
487 if (const OverflowingBinaryOperator *Op = | 528 if (const OverflowingBinaryOperator *Op = |
488 dyn_cast<OverflowingBinaryOperator>(Inst)) { | 529 dyn_cast<OverflowingBinaryOperator>(Inst)) { |
489 if (Op->hasNoUnsignedWrap()) | 530 if (Op->hasNoUnsignedWrap()) |
490 return "has \"nuw\" attribute"; | 531 return "has \"nuw\" attribute"; |
491 if (Op->hasNoSignedWrap()) | 532 if (Op->hasNoSignedWrap()) |
492 return "has \"nsw\" attribute"; | 533 return "has \"nsw\" attribute"; |
(...skipping 16 matching lines...) Expand all Loading... | |
509 FI != FE; ++FI) { | 550 FI != FE; ++FI) { |
510 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); | 551 for (BasicBlock::const_iterator BBI = FI->begin(), BBE = FI->end(); |
511 BBI != BBE; ++BBI) { | 552 BBI != BBE; ++BBI) { |
512 const Instruction *Inst = BBI; | 553 const Instruction *Inst = BBI; |
513 // Check the instruction opcode first. This simplifies testing, | 554 // Check the instruction opcode first. This simplifies testing, |
514 // because some instruction opcodes must be rejected out of hand | 555 // because some instruction opcodes must be rejected out of hand |
515 // (regardless of the instruction's result type) and the tests | 556 // (regardless of the instruction's result type) and the tests |
516 // check the reason for rejection. | 557 // check the reason for rejection. |
517 const char *Error = checkInstruction(BBI); | 558 const char *Error = checkInstruction(BBI); |
518 // Check the instruction's result type. | 559 // Check the instruction's result type. |
560 bool BadResult = false; | |
519 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) || | 561 if (!Error && !(PNaClABITypeChecker::isValidScalarType(Inst->getType()) || |
562 PNaClABITypeChecker::isValidVectorType(Inst->getType()) || | |
520 isNormalizedPtr(Inst) || | 563 isNormalizedPtr(Inst) || |
521 isa<AllocaInst>(Inst))) { | 564 isa<AllocaInst>(Inst))) { |
522 Error = "bad result type"; | 565 Error = "bad result type"; |
566 BadResult = true; | |
523 } | 567 } |
524 if (Error) { | 568 if (Error) { |
525 Reporter->addError() << "Function " << F.getName() << | 569 Reporter->addError() |
526 " disallowed: " << Error << ": " << *BBI << "\n"; | 570 << "Function " << F.getName() << " disallowed: " << Error << ": " |
571 << (BadResult ? PNaClABITypeChecker::getTypeName(BBI->getType()) | |
572 : "") << " " << *BBI << "\n"; | |
527 } | 573 } |
528 | 574 |
529 // Check instruction attachment metadata. | 575 // Check instruction attachment metadata. |
530 SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst; | 576 SmallVector<std::pair<unsigned, MDNode*>, 4> MDForInst; |
531 BBI->getAllMetadata(MDForInst); | 577 BBI->getAllMetadata(MDForInst); |
532 | 578 |
533 for (unsigned i = 0, e = MDForInst.size(); i != e; i++) { | 579 for (unsigned i = 0, e = MDForInst.size(); i != e; i++) { |
534 if (!IsWhitelistedMetadata(MDForInst[i].first)) { | 580 if (!IsWhitelistedMetadata(MDForInst[i].first)) { |
535 Reporter->addError() | 581 Reporter->addError() |
536 << "Function " << F.getName() | 582 << "Function " << F.getName() |
(...skipping 18 matching lines...) Expand all Loading... | |
555 } | 601 } |
556 | 602 |
557 char PNaClABIVerifyFunctions::ID = 0; | 603 char PNaClABIVerifyFunctions::ID = 0; |
558 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", | 604 INITIALIZE_PASS(PNaClABIVerifyFunctions, "verify-pnaclabi-functions", |
559 "Verify functions for PNaCl", false, true) | 605 "Verify functions for PNaCl", false, true) |
560 | 606 |
561 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( | 607 FunctionPass *llvm::createPNaClABIVerifyFunctionsPass( |
562 PNaClABIErrorReporter *Reporter) { | 608 PNaClABIErrorReporter *Reporter) { |
563 return new PNaClABIVerifyFunctions(Reporter); | 609 return new PNaClABIVerifyFunctions(Reporter); |
564 } | 610 } |
OLD | NEW |