1 //===-- IntrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements methods that make it really easy to deal with intrinsic 10 // functions. 11 // 12 // All intrinsic function calls are instances of the call instruction, so these 13 // are all subclasses of the CallInst class. Note that none of these classes 14 // has state or virtual methods, which is an important part of this gross/neat 15 // hack working. 16 // 17 // In some cases, arguments to intrinsics need to be generic and are defined as 18 // type pointer to empty struct { }*. To access the real item of interest the 19 // cast instruction needs to be stripped away. 20 // 21 //===----------------------------------------------------------------------===// 22 23 #include "llvm/IR/IntrinsicInst.h" 24 #include "llvm/ADT/StringSwitch.h" 25 #include "llvm/IR/Constants.h" 26 #include "llvm/IR/DebugInfoMetadata.h" 27 #include "llvm/IR/Metadata.h" 28 #include "llvm/IR/Module.h" 29 #include "llvm/IR/Operator.h" 30 #include "llvm/IR/PatternMatch.h" 31 #include "llvm/IR/Statepoint.h" 32 33 using namespace llvm; 34 35 //===----------------------------------------------------------------------===// 36 /// DbgVariableIntrinsic - This is the common base class for debug info 37 /// intrinsics for variables. 38 /// 39 40 iterator_range<DbgVariableIntrinsic::location_op_iterator> 41 DbgVariableIntrinsic::location_ops() const { 42 auto *MD = getRawLocation(); 43 assert(MD && "First operand of DbgVariableIntrinsic should be non-null."); 44 45 // If operand is ValueAsMetadata, return a range over just that operand. 46 if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) { 47 return {location_op_iterator(VAM), location_op_iterator(VAM + 1)}; 48 } 49 // If operand is DIArgList, return a range over its args. 50 if (auto *AL = dyn_cast<DIArgList>(MD)) 51 return {location_op_iterator(AL->args_begin()), 52 location_op_iterator(AL->args_end())}; 53 // Operand must be an empty metadata tuple, so return empty iterator. 54 return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), 55 location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; 56 } 57 58 Value *DbgVariableIntrinsic::getVariableLocationOp(unsigned OpIdx) const { 59 auto *MD = getRawLocation(); 60 assert(MD && "First operand of DbgVariableIntrinsic should be non-null."); 61 if (auto *AL = dyn_cast<DIArgList>(MD)) 62 return AL->getArgs()[OpIdx]->getValue(); 63 if (isa<MDNode>(MD)) 64 return nullptr; 65 assert( 66 isa<ValueAsMetadata>(MD) && 67 "Attempted to get location operand from DbgVariableIntrinsic with none."); 68 auto *V = cast<ValueAsMetadata>(MD); 69 assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " 70 "single location operand."); 71 return V->getValue(); 72 } 73 74 static ValueAsMetadata *getAsMetadata(Value *V) { 75 return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>( 76 cast<MetadataAsValue>(V)->getMetadata()) 77 : ValueAsMetadata::get(V); 78 } 79 80 void DbgVariableIntrinsic::replaceVariableLocationOp(Value *OldValue, 81 Value *NewValue) { 82 assert(NewValue && "Values must be non-null"); 83 auto Locations = location_ops(); 84 auto OldIt = find(Locations, OldValue); 85 assert(OldIt != Locations.end() && "OldValue must be a current location"); 86 if (!hasArgList()) { 87 Value *NewOperand = isa<MetadataAsValue>(NewValue) 88 ? NewValue 89 : MetadataAsValue::get( 90 getContext(), ValueAsMetadata::get(NewValue)); 91 return setArgOperand(0, NewOperand); 92 } 93 SmallVector<ValueAsMetadata *, 4> MDs; 94 ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 95 for (auto *VMD : Locations) 96 MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD)); 97 setArgOperand( 98 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); 99 } 100 void DbgVariableIntrinsic::replaceVariableLocationOp(unsigned OpIdx, 101 Value *NewValue) { 102 assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index"); 103 if (!hasArgList()) { 104 Value *NewOperand = isa<MetadataAsValue>(NewValue) 105 ? NewValue 106 : MetadataAsValue::get( 107 getContext(), ValueAsMetadata::get(NewValue)); 108 return setArgOperand(0, NewOperand); 109 } 110 SmallVector<ValueAsMetadata *, 4> MDs; 111 ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 112 for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx) 113 MDs.push_back(Idx == OpIdx ? NewOperand 114 : getAsMetadata(getVariableLocationOp(Idx))); 115 setArgOperand( 116 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); 117 } 118 119 void DbgVariableIntrinsic::addVariableLocationOps(ArrayRef<Value *> NewValues, 120 DIExpression *NewExpr) { 121 assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() + 122 NewValues.size()) && 123 "NewExpr for debug variable intrinsic does not reference every " 124 "location operand."); 125 assert(!is_contained(NewValues, nullptr) && "New values must be non-null"); 126 setArgOperand(2, MetadataAsValue::get(getContext(), NewExpr)); 127 SmallVector<ValueAsMetadata *, 4> MDs; 128 for (auto *VMD : location_ops()) 129 MDs.push_back(getAsMetadata(VMD)); 130 for (auto *VMD : NewValues) 131 MDs.push_back(getAsMetadata(VMD)); 132 setArgOperand( 133 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); 134 } 135 136 Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const { 137 if (auto Fragment = getExpression()->getFragmentInfo()) 138 return Fragment->SizeInBits; 139 return getVariable()->getSizeInBits(); 140 } 141 142 int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable, 143 StringRef Name) { 144 assert(Name.startswith("llvm.")); 145 146 // Do successive binary searches of the dotted name components. For 147 // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of 148 // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then 149 // "llvm.gc.experimental.statepoint", and then we will stop as the range is 150 // size 1. During the search, we can skip the prefix that we already know is 151 // identical. By using strncmp we consider names with differing suffixes to 152 // be part of the equal range. 153 size_t CmpEnd = 4; // Skip the "llvm" component. 154 const char *const *Low = NameTable.begin(); 155 const char *const *High = NameTable.end(); 156 const char *const *LastLow = Low; 157 while (CmpEnd < Name.size() && High - Low > 0) { 158 size_t CmpStart = CmpEnd; 159 CmpEnd = Name.find('.', CmpStart + 1); 160 CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd; 161 auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) { 162 return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0; 163 }; 164 LastLow = Low; 165 std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp); 166 } 167 if (High - Low > 0) 168 LastLow = Low; 169 170 if (LastLow == NameTable.end()) 171 return -1; 172 StringRef NameFound = *LastLow; 173 if (Name == NameFound || 174 (Name.startswith(NameFound) && Name[NameFound.size()] == '.')) 175 return LastLow - NameTable.begin(); 176 return -1; 177 } 178 179 ConstantInt *InstrProfInstBase::getNumCounters() const { 180 if (InstrProfValueProfileInst::classof(this)) 181 llvm_unreachable("InstrProfValueProfileInst does not have counters!"); 182 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 183 } 184 185 ConstantInt *InstrProfInstBase::getIndex() const { 186 if (InstrProfValueProfileInst::classof(this)) 187 llvm_unreachable("Please use InstrProfValueProfileInst::getIndex()"); 188 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 189 } 190 191 Value *InstrProfIncrementInst::getStep() const { 192 if (InstrProfIncrementInstStep::classof(this)) { 193 return const_cast<Value *>(getArgOperand(4)); 194 } 195 const Module *M = getModule(); 196 LLVMContext &Context = M->getContext(); 197 return ConstantInt::get(Type::getInt64Ty(Context), 1); 198 } 199 200 Optional<RoundingMode> ConstrainedFPIntrinsic::getRoundingMode() const { 201 unsigned NumOperands = arg_size(); 202 Metadata *MD = nullptr; 203 auto *MAV = dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 2)); 204 if (MAV) 205 MD = MAV->getMetadata(); 206 if (!MD || !isa<MDString>(MD)) 207 return None; 208 return convertStrToRoundingMode(cast<MDString>(MD)->getString()); 209 } 210 211 Optional<fp::ExceptionBehavior> 212 ConstrainedFPIntrinsic::getExceptionBehavior() const { 213 unsigned NumOperands = arg_size(); 214 Metadata *MD = nullptr; 215 auto *MAV = dyn_cast<MetadataAsValue>(getArgOperand(NumOperands - 1)); 216 if (MAV) 217 MD = MAV->getMetadata(); 218 if (!MD || !isa<MDString>(MD)) 219 return None; 220 return convertStrToExceptionBehavior(cast<MDString>(MD)->getString()); 221 } 222 223 bool ConstrainedFPIntrinsic::isDefaultFPEnvironment() const { 224 Optional<fp::ExceptionBehavior> Except = getExceptionBehavior(); 225 if (Except) { 226 if (Except.getValue() != fp::ebIgnore) 227 return false; 228 } 229 230 Optional<RoundingMode> Rounding = getRoundingMode(); 231 if (Rounding) { 232 if (Rounding.getValue() != RoundingMode::NearestTiesToEven) 233 return false; 234 } 235 236 return true; 237 } 238 239 static FCmpInst::Predicate getFPPredicateFromMD(const Value *Op) { 240 Metadata *MD = cast<MetadataAsValue>(Op)->getMetadata(); 241 if (!MD || !isa<MDString>(MD)) 242 return FCmpInst::BAD_FCMP_PREDICATE; 243 return StringSwitch<FCmpInst::Predicate>(cast<MDString>(MD)->getString()) 244 .Case("oeq", FCmpInst::FCMP_OEQ) 245 .Case("ogt", FCmpInst::FCMP_OGT) 246 .Case("oge", FCmpInst::FCMP_OGE) 247 .Case("olt", FCmpInst::FCMP_OLT) 248 .Case("ole", FCmpInst::FCMP_OLE) 249 .Case("one", FCmpInst::FCMP_ONE) 250 .Case("ord", FCmpInst::FCMP_ORD) 251 .Case("uno", FCmpInst::FCMP_UNO) 252 .Case("ueq", FCmpInst::FCMP_UEQ) 253 .Case("ugt", FCmpInst::FCMP_UGT) 254 .Case("uge", FCmpInst::FCMP_UGE) 255 .Case("ult", FCmpInst::FCMP_ULT) 256 .Case("ule", FCmpInst::FCMP_ULE) 257 .Case("une", FCmpInst::FCMP_UNE) 258 .Default(FCmpInst::BAD_FCMP_PREDICATE); 259 } 260 261 FCmpInst::Predicate ConstrainedFPCmpIntrinsic::getPredicate() const { 262 return getFPPredicateFromMD(getArgOperand(2)); 263 } 264 265 bool ConstrainedFPIntrinsic::isUnaryOp() const { 266 switch (getIntrinsicID()) { 267 default: 268 return false; 269 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ 270 case Intrinsic::INTRINSIC: \ 271 return NARG == 1; 272 #include "llvm/IR/ConstrainedOps.def" 273 } 274 } 275 276 bool ConstrainedFPIntrinsic::isTernaryOp() const { 277 switch (getIntrinsicID()) { 278 default: 279 return false; 280 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ 281 case Intrinsic::INTRINSIC: \ 282 return NARG == 3; 283 #include "llvm/IR/ConstrainedOps.def" 284 } 285 } 286 287 bool ConstrainedFPIntrinsic::classof(const IntrinsicInst *I) { 288 switch (I->getIntrinsicID()) { 289 #define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC) \ 290 case Intrinsic::INTRINSIC: 291 #include "llvm/IR/ConstrainedOps.def" 292 return true; 293 default: 294 return false; 295 } 296 } 297 298 ElementCount VPIntrinsic::getStaticVectorLength() const { 299 auto GetVectorLengthOfType = [](const Type *T) -> ElementCount { 300 const auto *VT = cast<VectorType>(T); 301 auto ElemCount = VT->getElementCount(); 302 return ElemCount; 303 }; 304 305 Value *VPMask = getMaskParam(); 306 if (!VPMask) { 307 assert((getIntrinsicID() == Intrinsic::vp_merge || 308 getIntrinsicID() == Intrinsic::vp_select) && 309 "Unexpected VP intrinsic without mask operand"); 310 return GetVectorLengthOfType(getType()); 311 } 312 return GetVectorLengthOfType(VPMask->getType()); 313 } 314 315 Value *VPIntrinsic::getMaskParam() const { 316 if (auto MaskPos = getMaskParamPos(getIntrinsicID())) 317 return getArgOperand(*MaskPos); 318 return nullptr; 319 } 320 321 void VPIntrinsic::setMaskParam(Value *NewMask) { 322 auto MaskPos = getMaskParamPos(getIntrinsicID()); 323 setArgOperand(*MaskPos, NewMask); 324 } 325 326 Value *VPIntrinsic::getVectorLengthParam() const { 327 if (auto EVLPos = getVectorLengthParamPos(getIntrinsicID())) 328 return getArgOperand(*EVLPos); 329 return nullptr; 330 } 331 332 void VPIntrinsic::setVectorLengthParam(Value *NewEVL) { 333 auto EVLPos = getVectorLengthParamPos(getIntrinsicID()); 334 setArgOperand(*EVLPos, NewEVL); 335 } 336 337 Optional<unsigned> VPIntrinsic::getMaskParamPos(Intrinsic::ID IntrinsicID) { 338 switch (IntrinsicID) { 339 default: 340 return None; 341 342 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \ 343 case Intrinsic::VPID: \ 344 return MASKPOS; 345 #include "llvm/IR/VPIntrinsics.def" 346 } 347 } 348 349 Optional<unsigned> 350 VPIntrinsic::getVectorLengthParamPos(Intrinsic::ID IntrinsicID) { 351 switch (IntrinsicID) { 352 default: 353 return None; 354 355 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \ 356 case Intrinsic::VPID: \ 357 return VLENPOS; 358 #include "llvm/IR/VPIntrinsics.def" 359 } 360 } 361 362 /// \return the alignment of the pointer used by this load/store/gather or 363 /// scatter. 364 MaybeAlign VPIntrinsic::getPointerAlignment() const { 365 Optional<unsigned> PtrParamOpt = getMemoryPointerParamPos(getIntrinsicID()); 366 assert(PtrParamOpt && "no pointer argument!"); 367 return getParamAlign(PtrParamOpt.getValue()); 368 } 369 370 /// \return The pointer operand of this load,store, gather or scatter. 371 Value *VPIntrinsic::getMemoryPointerParam() const { 372 if (auto PtrParamOpt = getMemoryPointerParamPos(getIntrinsicID())) 373 return getArgOperand(PtrParamOpt.getValue()); 374 return nullptr; 375 } 376 377 Optional<unsigned> VPIntrinsic::getMemoryPointerParamPos(Intrinsic::ID VPID) { 378 switch (VPID) { 379 default: 380 break; 381 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 382 #define VP_PROPERTY_MEMOP(POINTERPOS, ...) return POINTERPOS; 383 #define END_REGISTER_VP_INTRINSIC(VPID) break; 384 #include "llvm/IR/VPIntrinsics.def" 385 } 386 return None; 387 } 388 389 /// \return The data (payload) operand of this store or scatter. 390 Value *VPIntrinsic::getMemoryDataParam() const { 391 auto DataParamOpt = getMemoryDataParamPos(getIntrinsicID()); 392 if (!DataParamOpt) 393 return nullptr; 394 return getArgOperand(DataParamOpt.getValue()); 395 } 396 397 Optional<unsigned> VPIntrinsic::getMemoryDataParamPos(Intrinsic::ID VPID) { 398 switch (VPID) { 399 default: 400 break; 401 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 402 #define VP_PROPERTY_MEMOP(POINTERPOS, DATAPOS) return DATAPOS; 403 #define END_REGISTER_VP_INTRINSIC(VPID) break; 404 #include "llvm/IR/VPIntrinsics.def" 405 } 406 return None; 407 } 408 409 bool VPIntrinsic::isVPIntrinsic(Intrinsic::ID ID) { 410 switch (ID) { 411 default: 412 break; 413 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \ 414 case Intrinsic::VPID: \ 415 return true; 416 #include "llvm/IR/VPIntrinsics.def" 417 } 418 return false; 419 } 420 421 // Equivalent non-predicated opcode 422 Optional<unsigned> VPIntrinsic::getFunctionalOpcodeForVP(Intrinsic::ID ID) { 423 switch (ID) { 424 default: 425 break; 426 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 427 #define VP_PROPERTY_FUNCTIONAL_OPC(OPC) return Instruction::OPC; 428 #define END_REGISTER_VP_INTRINSIC(VPID) break; 429 #include "llvm/IR/VPIntrinsics.def" 430 } 431 return None; 432 } 433 434 Intrinsic::ID VPIntrinsic::getForOpcode(unsigned IROPC) { 435 switch (IROPC) { 436 default: 437 break; 438 439 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) break; 440 #define VP_PROPERTY_FUNCTIONAL_OPC(OPC) case Instruction::OPC: 441 #define END_REGISTER_VP_INTRINSIC(VPID) return Intrinsic::VPID; 442 #include "llvm/IR/VPIntrinsics.def" 443 } 444 return Intrinsic::not_intrinsic; 445 } 446 447 bool VPIntrinsic::canIgnoreVectorLengthParam() const { 448 using namespace PatternMatch; 449 450 ElementCount EC = getStaticVectorLength(); 451 452 // No vlen param - no lanes masked-off by it. 453 auto *VLParam = getVectorLengthParam(); 454 if (!VLParam) 455 return true; 456 457 // Note that the VP intrinsic causes undefined behavior if the Explicit Vector 458 // Length parameter is strictly greater-than the number of vector elements of 459 // the operation. This function returns true when this is detected statically 460 // in the IR. 461 462 // Check whether "W == vscale * EC.getKnownMinValue()" 463 if (EC.isScalable()) { 464 // Undig the DL 465 const auto *ParMod = this->getModule(); 466 if (!ParMod) 467 return false; 468 const auto &DL = ParMod->getDataLayout(); 469 470 // Compare vscale patterns 471 uint64_t VScaleFactor; 472 if (match(VLParam, m_c_Mul(m_ConstantInt(VScaleFactor), m_VScale(DL)))) 473 return VScaleFactor >= EC.getKnownMinValue(); 474 return (EC.getKnownMinValue() == 1) && match(VLParam, m_VScale(DL)); 475 } 476 477 // standard SIMD operation 478 const auto *VLConst = dyn_cast<ConstantInt>(VLParam); 479 if (!VLConst) 480 return false; 481 482 uint64_t VLNum = VLConst->getZExtValue(); 483 if (VLNum >= EC.getKnownMinValue()) 484 return true; 485 486 return false; 487 } 488 489 Function *VPIntrinsic::getDeclarationForParams(Module *M, Intrinsic::ID VPID, 490 Type *ReturnType, 491 ArrayRef<Value *> Params) { 492 assert(isVPIntrinsic(VPID) && "not a VP intrinsic"); 493 Function *VPFunc; 494 switch (VPID) { 495 default: { 496 Type *OverloadTy = Params[0]->getType(); 497 if (VPReductionIntrinsic::isVPReduction(VPID)) 498 OverloadTy = 499 Params[*VPReductionIntrinsic::getVectorParamPos(VPID)]->getType(); 500 501 VPFunc = Intrinsic::getDeclaration(M, VPID, OverloadTy); 502 break; 503 } 504 case Intrinsic::vp_trunc: 505 case Intrinsic::vp_sext: 506 case Intrinsic::vp_zext: 507 case Intrinsic::vp_fptoui: 508 case Intrinsic::vp_fptosi: 509 case Intrinsic::vp_uitofp: 510 case Intrinsic::vp_sitofp: 511 case Intrinsic::vp_fptrunc: 512 case Intrinsic::vp_fpext: 513 case Intrinsic::vp_ptrtoint: 514 case Intrinsic::vp_inttoptr: 515 VPFunc = 516 Intrinsic::getDeclaration(M, VPID, {ReturnType, Params[0]->getType()}); 517 break; 518 case Intrinsic::vp_merge: 519 case Intrinsic::vp_select: 520 VPFunc = Intrinsic::getDeclaration(M, VPID, {Params[1]->getType()}); 521 break; 522 case Intrinsic::vp_load: 523 VPFunc = Intrinsic::getDeclaration( 524 M, VPID, {ReturnType, Params[0]->getType()}); 525 break; 526 case Intrinsic::experimental_vp_strided_load: 527 VPFunc = Intrinsic::getDeclaration( 528 M, VPID, {ReturnType, Params[0]->getType(), Params[1]->getType()}); 529 break; 530 case Intrinsic::vp_gather: 531 VPFunc = Intrinsic::getDeclaration( 532 M, VPID, {ReturnType, Params[0]->getType()}); 533 break; 534 case Intrinsic::vp_store: 535 VPFunc = Intrinsic::getDeclaration( 536 M, VPID, {Params[0]->getType(), Params[1]->getType()}); 537 break; 538 case Intrinsic::experimental_vp_strided_store: 539 VPFunc = Intrinsic::getDeclaration( 540 M, VPID, 541 {Params[0]->getType(), Params[1]->getType(), Params[2]->getType()}); 542 break; 543 case Intrinsic::vp_scatter: 544 VPFunc = Intrinsic::getDeclaration( 545 M, VPID, {Params[0]->getType(), Params[1]->getType()}); 546 break; 547 } 548 assert(VPFunc && "Could not declare VP intrinsic"); 549 return VPFunc; 550 } 551 552 bool VPReductionIntrinsic::isVPReduction(Intrinsic::ID ID) { 553 switch (ID) { 554 default: 555 break; 556 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 557 #define VP_PROPERTY_REDUCTION(STARTPOS, ...) return true; 558 #define END_REGISTER_VP_INTRINSIC(VPID) break; 559 #include "llvm/IR/VPIntrinsics.def" 560 } 561 return false; 562 } 563 564 bool VPCastIntrinsic::isVPCast(Intrinsic::ID ID) { 565 switch (ID) { 566 default: 567 break; 568 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 569 #define VP_PROPERTY_CASTOP return true; 570 #define END_REGISTER_VP_INTRINSIC(VPID) break; 571 #include "llvm/IR/VPIntrinsics.def" 572 } 573 return false; 574 } 575 576 bool VPCmpIntrinsic::isVPCmp(Intrinsic::ID ID) { 577 switch (ID) { 578 default: 579 break; 580 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 581 #define VP_PROPERTY_CMP(CCPOS, ...) return true; 582 #define END_REGISTER_VP_INTRINSIC(VPID) break; 583 #include "llvm/IR/VPIntrinsics.def" 584 } 585 return false; 586 } 587 588 static ICmpInst::Predicate getIntPredicateFromMD(const Value *Op) { 589 Metadata *MD = cast<MetadataAsValue>(Op)->getMetadata(); 590 if (!MD || !isa<MDString>(MD)) 591 return ICmpInst::BAD_ICMP_PREDICATE; 592 return StringSwitch<ICmpInst::Predicate>(cast<MDString>(MD)->getString()) 593 .Case("eq", ICmpInst::ICMP_EQ) 594 .Case("ne", ICmpInst::ICMP_NE) 595 .Case("ugt", ICmpInst::ICMP_UGT) 596 .Case("uge", ICmpInst::ICMP_UGE) 597 .Case("ult", ICmpInst::ICMP_ULT) 598 .Case("ule", ICmpInst::ICMP_ULE) 599 .Case("sgt", ICmpInst::ICMP_SGT) 600 .Case("sge", ICmpInst::ICMP_SGE) 601 .Case("slt", ICmpInst::ICMP_SLT) 602 .Case("sle", ICmpInst::ICMP_SLE) 603 .Default(ICmpInst::BAD_ICMP_PREDICATE); 604 } 605 606 CmpInst::Predicate VPCmpIntrinsic::getPredicate() const { 607 bool IsFP = true; 608 Optional<unsigned> CCArgIdx; 609 switch (getIntrinsicID()) { 610 default: 611 break; 612 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 613 #define VP_PROPERTY_CMP(CCPOS, ISFP) \ 614 CCArgIdx = CCPOS; \ 615 IsFP = ISFP; \ 616 break; 617 #define END_REGISTER_VP_INTRINSIC(VPID) break; 618 #include "llvm/IR/VPIntrinsics.def" 619 } 620 assert(CCArgIdx && "Unexpected vector-predicated comparison"); 621 return IsFP ? getFPPredicateFromMD(getArgOperand(*CCArgIdx)) 622 : getIntPredicateFromMD(getArgOperand(*CCArgIdx)); 623 } 624 625 unsigned VPReductionIntrinsic::getVectorParamPos() const { 626 return *VPReductionIntrinsic::getVectorParamPos(getIntrinsicID()); 627 } 628 629 unsigned VPReductionIntrinsic::getStartParamPos() const { 630 return *VPReductionIntrinsic::getStartParamPos(getIntrinsicID()); 631 } 632 633 Optional<unsigned> VPReductionIntrinsic::getVectorParamPos(Intrinsic::ID ID) { 634 switch (ID) { 635 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 636 #define VP_PROPERTY_REDUCTION(STARTPOS, VECTORPOS) return VECTORPOS; 637 #define END_REGISTER_VP_INTRINSIC(VPID) break; 638 #include "llvm/IR/VPIntrinsics.def" 639 default: 640 break; 641 } 642 return None; 643 } 644 645 Optional<unsigned> VPReductionIntrinsic::getStartParamPos(Intrinsic::ID ID) { 646 switch (ID) { 647 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 648 #define VP_PROPERTY_REDUCTION(STARTPOS, VECTORPOS) return STARTPOS; 649 #define END_REGISTER_VP_INTRINSIC(VPID) break; 650 #include "llvm/IR/VPIntrinsics.def" 651 default: 652 break; 653 } 654 return None; 655 } 656 657 Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const { 658 switch (getIntrinsicID()) { 659 case Intrinsic::uadd_with_overflow: 660 case Intrinsic::sadd_with_overflow: 661 case Intrinsic::uadd_sat: 662 case Intrinsic::sadd_sat: 663 return Instruction::Add; 664 case Intrinsic::usub_with_overflow: 665 case Intrinsic::ssub_with_overflow: 666 case Intrinsic::usub_sat: 667 case Intrinsic::ssub_sat: 668 return Instruction::Sub; 669 case Intrinsic::umul_with_overflow: 670 case Intrinsic::smul_with_overflow: 671 return Instruction::Mul; 672 default: 673 llvm_unreachable("Invalid intrinsic"); 674 } 675 } 676 677 bool BinaryOpIntrinsic::isSigned() const { 678 switch (getIntrinsicID()) { 679 case Intrinsic::sadd_with_overflow: 680 case Intrinsic::ssub_with_overflow: 681 case Intrinsic::smul_with_overflow: 682 case Intrinsic::sadd_sat: 683 case Intrinsic::ssub_sat: 684 return true; 685 default: 686 return false; 687 } 688 } 689 690 unsigned BinaryOpIntrinsic::getNoWrapKind() const { 691 if (isSigned()) 692 return OverflowingBinaryOperator::NoSignedWrap; 693 else 694 return OverflowingBinaryOperator::NoUnsignedWrap; 695 } 696 697 const GCStatepointInst *GCProjectionInst::getStatepoint() const { 698 const Value *Token = getArgOperand(0); 699 700 // This takes care both of relocates for call statepoints and relocates 701 // on normal path of invoke statepoint. 702 if (!isa<LandingPadInst>(Token)) 703 return cast<GCStatepointInst>(Token); 704 705 // This relocate is on exceptional path of an invoke statepoint 706 const BasicBlock *InvokeBB = 707 cast<Instruction>(Token)->getParent()->getUniquePredecessor(); 708 709 assert(InvokeBB && "safepoints should have unique landingpads"); 710 assert(InvokeBB->getTerminator() && 711 "safepoint block should be well formed"); 712 713 return cast<GCStatepointInst>(InvokeBB->getTerminator()); 714 } 715 716 Value *GCRelocateInst::getBasePtr() const { 717 if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) 718 return *(Opt->Inputs.begin() + getBasePtrIndex()); 719 return *(getStatepoint()->arg_begin() + getBasePtrIndex()); 720 } 721 722 Value *GCRelocateInst::getDerivedPtr() const { 723 if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) 724 return *(Opt->Inputs.begin() + getDerivedPtrIndex()); 725 return *(getStatepoint()->arg_begin() + getDerivedPtrIndex()); 726 } 727