1 //===-- InstrinsicInst.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/GlobalVariable.h" 28 #include "llvm/IR/Metadata.h" 29 #include "llvm/IR/Module.h" 30 #include "llvm/IR/Operator.h" 31 #include "llvm/IR/PatternMatch.h" 32 #include "llvm/IR/Statepoint.h" 33 34 #include "llvm/Support/raw_ostream.h" 35 using namespace llvm; 36 37 //===----------------------------------------------------------------------===// 38 /// DbgVariableIntrinsic - This is the common base class for debug info 39 /// intrinsics for variables. 40 /// 41 42 iterator_range<DbgVariableIntrinsic::location_op_iterator> 43 DbgVariableIntrinsic::location_ops() const { 44 auto *MD = getRawLocation(); 45 assert(MD && "First operand of DbgVariableIntrinsic should be non-null."); 46 47 // If operand is ValueAsMetadata, return a range over just that operand. 48 if (auto *VAM = dyn_cast<ValueAsMetadata>(MD)) { 49 return {location_op_iterator(VAM), location_op_iterator(VAM + 1)}; 50 } 51 // If operand is DIArgList, return a range over its args. 52 if (auto *AL = dyn_cast<DIArgList>(MD)) 53 return {location_op_iterator(AL->args_begin()), 54 location_op_iterator(AL->args_end())}; 55 // Operand must be an empty metadata tuple, so return empty iterator. 56 return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)), 57 location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))}; 58 } 59 60 Value *DbgVariableIntrinsic::getVariableLocationOp(unsigned OpIdx) const { 61 auto *MD = getRawLocation(); 62 assert(MD && "First operand of DbgVariableIntrinsic should be non-null."); 63 if (auto *AL = dyn_cast<DIArgList>(MD)) 64 return AL->getArgs()[OpIdx]->getValue(); 65 if (isa<MDNode>(MD)) 66 return nullptr; 67 assert( 68 isa<ValueAsMetadata>(MD) && 69 "Attempted to get location operand from DbgVariableIntrinsic with none."); 70 auto *V = cast<ValueAsMetadata>(MD); 71 assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a " 72 "single location operand."); 73 return V->getValue(); 74 } 75 76 static ValueAsMetadata *getAsMetadata(Value *V) { 77 return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>( 78 cast<MetadataAsValue>(V)->getMetadata()) 79 : ValueAsMetadata::get(V); 80 } 81 82 void DbgVariableIntrinsic::replaceVariableLocationOp(Value *OldValue, 83 Value *NewValue) { 84 assert(NewValue && "Values must be non-null"); 85 auto Locations = location_ops(); 86 auto OldIt = find(Locations, OldValue); 87 assert(OldIt != Locations.end() && "OldValue must be a current location"); 88 if (!hasArgList()) { 89 Value *NewOperand = isa<MetadataAsValue>(NewValue) 90 ? NewValue 91 : MetadataAsValue::get( 92 getContext(), ValueAsMetadata::get(NewValue)); 93 return setArgOperand(0, NewOperand); 94 } 95 SmallVector<ValueAsMetadata *, 4> MDs; 96 ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 97 for (auto *VMD : Locations) 98 MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD)); 99 setArgOperand( 100 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); 101 } 102 void DbgVariableIntrinsic::replaceVariableLocationOp(unsigned OpIdx, 103 Value *NewValue) { 104 assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index"); 105 if (!hasArgList()) { 106 Value *NewOperand = isa<MetadataAsValue>(NewValue) 107 ? NewValue 108 : MetadataAsValue::get( 109 getContext(), ValueAsMetadata::get(NewValue)); 110 return setArgOperand(0, NewOperand); 111 } 112 SmallVector<ValueAsMetadata *, 4> MDs; 113 ValueAsMetadata *NewOperand = getAsMetadata(NewValue); 114 for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx) 115 MDs.push_back(Idx == OpIdx ? NewOperand 116 : getAsMetadata(getVariableLocationOp(Idx))); 117 setArgOperand( 118 0, MetadataAsValue::get(getContext(), DIArgList::get(getContext(), MDs))); 119 } 120 121 Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const { 122 if (auto Fragment = getExpression()->getFragmentInfo()) 123 return Fragment->SizeInBits; 124 return getVariable()->getSizeInBits(); 125 } 126 127 int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable, 128 StringRef Name) { 129 assert(Name.startswith("llvm.")); 130 131 // Do successive binary searches of the dotted name components. For 132 // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of 133 // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then 134 // "llvm.gc.experimental.statepoint", and then we will stop as the range is 135 // size 1. During the search, we can skip the prefix that we already know is 136 // identical. By using strncmp we consider names with differing suffixes to 137 // be part of the equal range. 138 size_t CmpEnd = 4; // Skip the "llvm" component. 139 const char *const *Low = NameTable.begin(); 140 const char *const *High = NameTable.end(); 141 const char *const *LastLow = Low; 142 while (CmpEnd < Name.size() && High - Low > 0) { 143 size_t CmpStart = CmpEnd; 144 CmpEnd = Name.find('.', CmpStart + 1); 145 CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd; 146 auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) { 147 return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0; 148 }; 149 LastLow = Low; 150 std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp); 151 } 152 if (High - Low > 0) 153 LastLow = Low; 154 155 if (LastLow == NameTable.end()) 156 return -1; 157 StringRef NameFound = *LastLow; 158 if (Name == NameFound || 159 (Name.startswith(NameFound) && Name[NameFound.size()] == '.')) 160 return LastLow - NameTable.begin(); 161 return -1; 162 } 163 164 Value *InstrProfIncrementInst::getStep() const { 165 if (InstrProfIncrementInstStep::classof(this)) { 166 return const_cast<Value *>(getArgOperand(4)); 167 } 168 const Module *M = getModule(); 169 LLVMContext &Context = M->getContext(); 170 return ConstantInt::get(Type::getInt64Ty(Context), 1); 171 } 172 173 Optional<RoundingMode> ConstrainedFPIntrinsic::getRoundingMode() const { 174 unsigned NumOperands = getNumArgOperands(); 175 Metadata *MD = 176 cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata(); 177 if (!MD || !isa<MDString>(MD)) 178 return None; 179 return StrToRoundingMode(cast<MDString>(MD)->getString()); 180 } 181 182 Optional<fp::ExceptionBehavior> 183 ConstrainedFPIntrinsic::getExceptionBehavior() const { 184 unsigned NumOperands = getNumArgOperands(); 185 Metadata *MD = 186 cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata(); 187 if (!MD || !isa<MDString>(MD)) 188 return None; 189 return StrToExceptionBehavior(cast<MDString>(MD)->getString()); 190 } 191 192 FCmpInst::Predicate ConstrainedFPCmpIntrinsic::getPredicate() const { 193 Metadata *MD = cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 194 if (!MD || !isa<MDString>(MD)) 195 return FCmpInst::BAD_FCMP_PREDICATE; 196 return StringSwitch<FCmpInst::Predicate>(cast<MDString>(MD)->getString()) 197 .Case("oeq", FCmpInst::FCMP_OEQ) 198 .Case("ogt", FCmpInst::FCMP_OGT) 199 .Case("oge", FCmpInst::FCMP_OGE) 200 .Case("olt", FCmpInst::FCMP_OLT) 201 .Case("ole", FCmpInst::FCMP_OLE) 202 .Case("one", FCmpInst::FCMP_ONE) 203 .Case("ord", FCmpInst::FCMP_ORD) 204 .Case("uno", FCmpInst::FCMP_UNO) 205 .Case("ueq", FCmpInst::FCMP_UEQ) 206 .Case("ugt", FCmpInst::FCMP_UGT) 207 .Case("uge", FCmpInst::FCMP_UGE) 208 .Case("ult", FCmpInst::FCMP_ULT) 209 .Case("ule", FCmpInst::FCMP_ULE) 210 .Case("une", FCmpInst::FCMP_UNE) 211 .Default(FCmpInst::BAD_FCMP_PREDICATE); 212 } 213 214 bool ConstrainedFPIntrinsic::isUnaryOp() const { 215 switch (getIntrinsicID()) { 216 default: 217 return false; 218 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ 219 case Intrinsic::INTRINSIC: \ 220 return NARG == 1; 221 #include "llvm/IR/ConstrainedOps.def" 222 } 223 } 224 225 bool ConstrainedFPIntrinsic::isTernaryOp() const { 226 switch (getIntrinsicID()) { 227 default: 228 return false; 229 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \ 230 case Intrinsic::INTRINSIC: \ 231 return NARG == 3; 232 #include "llvm/IR/ConstrainedOps.def" 233 } 234 } 235 236 bool ConstrainedFPIntrinsic::classof(const IntrinsicInst *I) { 237 switch (I->getIntrinsicID()) { 238 #define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC) \ 239 case Intrinsic::INTRINSIC: 240 #include "llvm/IR/ConstrainedOps.def" 241 return true; 242 default: 243 return false; 244 } 245 } 246 247 ElementCount VPIntrinsic::getStaticVectorLength() const { 248 auto GetVectorLengthOfType = [](const Type *T) -> ElementCount { 249 auto VT = cast<VectorType>(T); 250 auto ElemCount = VT->getElementCount(); 251 return ElemCount; 252 }; 253 254 auto VPMask = getMaskParam(); 255 return GetVectorLengthOfType(VPMask->getType()); 256 } 257 258 Value *VPIntrinsic::getMaskParam() const { 259 auto maskPos = GetMaskParamPos(getIntrinsicID()); 260 if (maskPos) 261 return getArgOperand(maskPos.getValue()); 262 return nullptr; 263 } 264 265 Value *VPIntrinsic::getVectorLengthParam() const { 266 auto vlenPos = GetVectorLengthParamPos(getIntrinsicID()); 267 if (vlenPos) 268 return getArgOperand(vlenPos.getValue()); 269 return nullptr; 270 } 271 272 Optional<int> VPIntrinsic::GetMaskParamPos(Intrinsic::ID IntrinsicID) { 273 switch (IntrinsicID) { 274 default: 275 return None; 276 277 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \ 278 case Intrinsic::VPID: \ 279 return MASKPOS; 280 #include "llvm/IR/VPIntrinsics.def" 281 } 282 } 283 284 Optional<int> VPIntrinsic::GetVectorLengthParamPos(Intrinsic::ID IntrinsicID) { 285 switch (IntrinsicID) { 286 default: 287 return None; 288 289 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \ 290 case Intrinsic::VPID: \ 291 return VLENPOS; 292 #include "llvm/IR/VPIntrinsics.def" 293 } 294 } 295 296 bool VPIntrinsic::IsVPIntrinsic(Intrinsic::ID ID) { 297 switch (ID) { 298 default: 299 return false; 300 301 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \ 302 case Intrinsic::VPID: \ 303 break; 304 #include "llvm/IR/VPIntrinsics.def" 305 } 306 return true; 307 } 308 309 // Equivalent non-predicated opcode 310 unsigned VPIntrinsic::GetFunctionalOpcodeForVP(Intrinsic::ID ID) { 311 unsigned FunctionalOC = Instruction::Call; 312 switch (ID) { 313 default: 314 break; 315 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID: 316 #define HANDLE_VP_TO_OPC(OPC) FunctionalOC = Instruction::OPC; 317 #define END_REGISTER_VP_INTRINSIC(...) break; 318 #include "llvm/IR/VPIntrinsics.def" 319 } 320 321 return FunctionalOC; 322 } 323 324 Intrinsic::ID VPIntrinsic::GetForOpcode(unsigned IROPC) { 325 switch (IROPC) { 326 default: 327 return Intrinsic::not_intrinsic; 328 329 #define HANDLE_VP_TO_OPC(OPC) case Instruction::OPC: 330 #define END_REGISTER_VP_INTRINSIC(VPID) return Intrinsic::VPID; 331 #include "llvm/IR/VPIntrinsics.def" 332 } 333 } 334 335 bool VPIntrinsic::canIgnoreVectorLengthParam() const { 336 using namespace PatternMatch; 337 338 ElementCount EC = getStaticVectorLength(); 339 340 // No vlen param - no lanes masked-off by it. 341 auto *VLParam = getVectorLengthParam(); 342 if (!VLParam) 343 return true; 344 345 // Note that the VP intrinsic causes undefined behavior if the Explicit Vector 346 // Length parameter is strictly greater-than the number of vector elements of 347 // the operation. This function returns true when this is detected statically 348 // in the IR. 349 350 // Check whether "W == vscale * EC.getKnownMinValue()" 351 if (EC.isScalable()) { 352 // Undig the DL 353 auto ParMod = this->getModule(); 354 if (!ParMod) 355 return false; 356 const auto &DL = ParMod->getDataLayout(); 357 358 // Compare vscale patterns 359 uint64_t VScaleFactor; 360 if (match(VLParam, m_c_Mul(m_ConstantInt(VScaleFactor), m_VScale(DL)))) 361 return VScaleFactor >= EC.getKnownMinValue(); 362 return (EC.getKnownMinValue() == 1) && match(VLParam, m_VScale(DL)); 363 } 364 365 // standard SIMD operation 366 auto VLConst = dyn_cast<ConstantInt>(VLParam); 367 if (!VLConst) 368 return false; 369 370 uint64_t VLNum = VLConst->getZExtValue(); 371 if (VLNum >= EC.getKnownMinValue()) 372 return true; 373 374 return false; 375 } 376 377 Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const { 378 switch (getIntrinsicID()) { 379 case Intrinsic::uadd_with_overflow: 380 case Intrinsic::sadd_with_overflow: 381 case Intrinsic::uadd_sat: 382 case Intrinsic::sadd_sat: 383 return Instruction::Add; 384 case Intrinsic::usub_with_overflow: 385 case Intrinsic::ssub_with_overflow: 386 case Intrinsic::usub_sat: 387 case Intrinsic::ssub_sat: 388 return Instruction::Sub; 389 case Intrinsic::umul_with_overflow: 390 case Intrinsic::smul_with_overflow: 391 return Instruction::Mul; 392 default: 393 llvm_unreachable("Invalid intrinsic"); 394 } 395 } 396 397 bool BinaryOpIntrinsic::isSigned() const { 398 switch (getIntrinsicID()) { 399 case Intrinsic::sadd_with_overflow: 400 case Intrinsic::ssub_with_overflow: 401 case Intrinsic::smul_with_overflow: 402 case Intrinsic::sadd_sat: 403 case Intrinsic::ssub_sat: 404 return true; 405 default: 406 return false; 407 } 408 } 409 410 unsigned BinaryOpIntrinsic::getNoWrapKind() const { 411 if (isSigned()) 412 return OverflowingBinaryOperator::NoSignedWrap; 413 else 414 return OverflowingBinaryOperator::NoUnsignedWrap; 415 } 416 417 const GCStatepointInst *GCProjectionInst::getStatepoint() const { 418 const Value *Token = getArgOperand(0); 419 420 // This takes care both of relocates for call statepoints and relocates 421 // on normal path of invoke statepoint. 422 if (!isa<LandingPadInst>(Token)) 423 return cast<GCStatepointInst>(Token); 424 425 // This relocate is on exceptional path of an invoke statepoint 426 const BasicBlock *InvokeBB = 427 cast<Instruction>(Token)->getParent()->getUniquePredecessor(); 428 429 assert(InvokeBB && "safepoints should have unique landingpads"); 430 assert(InvokeBB->getTerminator() && 431 "safepoint block should be well formed"); 432 433 return cast<GCStatepointInst>(InvokeBB->getTerminator()); 434 } 435 436 Value *GCRelocateInst::getBasePtr() const { 437 if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) 438 return *(Opt->Inputs.begin() + getBasePtrIndex()); 439 return *(getStatepoint()->arg_begin() + getBasePtrIndex()); 440 } 441 442 Value *GCRelocateInst::getDerivedPtr() const { 443 if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live)) 444 return *(Opt->Inputs.begin() + getDerivedPtrIndex()); 445 return *(getStatepoint()->arg_begin() + getDerivedPtrIndex()); 446 } 447