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

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: Address dschuff's comments. 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698