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