Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(719)

Side by Side Diff: lib/Analysis/NaCl/PNaClABIVerifyFunctions.cpp

Issue 221693002: PNaCl: Add support for GCC/LLVM vector extensions (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Remove TODOs that were done. Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698