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