xref: /freebsd/contrib/llvm-project/llvm/lib/IR/IntrinsicInst.cpp (revision 3a9a9c0ca44ec535dcf73fe8462bee458e54814b)
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 FCmpInst::Predicate ConstrainedFPCmpIntrinsic::getPredicate() const {
240   Metadata *MD = cast<MetadataAsValue>(getArgOperand(2))->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 bool ConstrainedFPIntrinsic::isUnaryOp() const {
262   switch (getIntrinsicID()) {
263   default:
264     return false;
265 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC)                         \
266   case Intrinsic::INTRINSIC:                                                   \
267     return NARG == 1;
268 #include "llvm/IR/ConstrainedOps.def"
269   }
270 }
271 
272 bool ConstrainedFPIntrinsic::isTernaryOp() const {
273   switch (getIntrinsicID()) {
274   default:
275     return false;
276 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC)                         \
277   case Intrinsic::INTRINSIC:                                                   \
278     return NARG == 3;
279 #include "llvm/IR/ConstrainedOps.def"
280   }
281 }
282 
283 bool ConstrainedFPIntrinsic::classof(const IntrinsicInst *I) {
284   switch (I->getIntrinsicID()) {
285 #define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC)                        \
286   case Intrinsic::INTRINSIC:
287 #include "llvm/IR/ConstrainedOps.def"
288     return true;
289   default:
290     return false;
291   }
292 }
293 
294 ElementCount VPIntrinsic::getStaticVectorLength() const {
295   auto GetVectorLengthOfType = [](const Type *T) -> ElementCount {
296     const auto *VT = cast<VectorType>(T);
297     auto ElemCount = VT->getElementCount();
298     return ElemCount;
299   };
300 
301   Value *VPMask = getMaskParam();
302   assert(VPMask && "No mask param?");
303   return GetVectorLengthOfType(VPMask->getType());
304 }
305 
306 Value *VPIntrinsic::getMaskParam() const {
307   if (auto MaskPos = getMaskParamPos(getIntrinsicID()))
308     return getArgOperand(MaskPos.getValue());
309   return nullptr;
310 }
311 
312 void VPIntrinsic::setMaskParam(Value *NewMask) {
313   auto MaskPos = getMaskParamPos(getIntrinsicID());
314   setArgOperand(*MaskPos, NewMask);
315 }
316 
317 Value *VPIntrinsic::getVectorLengthParam() const {
318   if (auto EVLPos = getVectorLengthParamPos(getIntrinsicID()))
319     return getArgOperand(EVLPos.getValue());
320   return nullptr;
321 }
322 
323 void VPIntrinsic::setVectorLengthParam(Value *NewEVL) {
324   auto EVLPos = getVectorLengthParamPos(getIntrinsicID());
325   setArgOperand(*EVLPos, NewEVL);
326 }
327 
328 Optional<unsigned> VPIntrinsic::getMaskParamPos(Intrinsic::ID IntrinsicID) {
329   switch (IntrinsicID) {
330   default:
331     return None;
332 
333 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS)                    \
334   case Intrinsic::VPID:                                                        \
335     return MASKPOS;
336 #include "llvm/IR/VPIntrinsics.def"
337   }
338 }
339 
340 Optional<unsigned>
341 VPIntrinsic::getVectorLengthParamPos(Intrinsic::ID IntrinsicID) {
342   switch (IntrinsicID) {
343   default:
344     return None;
345 
346 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS)                    \
347   case Intrinsic::VPID:                                                        \
348     return VLENPOS;
349 #include "llvm/IR/VPIntrinsics.def"
350   }
351 }
352 
353 /// \return the alignment of the pointer used by this load/store/gather or
354 /// scatter.
355 MaybeAlign VPIntrinsic::getPointerAlignment() const {
356   Optional<unsigned> PtrParamOpt = getMemoryPointerParamPos(getIntrinsicID());
357   assert(PtrParamOpt.hasValue() && "no pointer argument!");
358   return getParamAlign(PtrParamOpt.getValue());
359 }
360 
361 /// \return The pointer operand of this load,store, gather or scatter.
362 Value *VPIntrinsic::getMemoryPointerParam() const {
363   if (auto PtrParamOpt = getMemoryPointerParamPos(getIntrinsicID()))
364     return getArgOperand(PtrParamOpt.getValue());
365   return nullptr;
366 }
367 
368 Optional<unsigned> VPIntrinsic::getMemoryPointerParamPos(Intrinsic::ID VPID) {
369   switch (VPID) {
370   default:
371     break;
372 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
373 #define VP_PROPERTY_MEMOP(POINTERPOS, ...) return POINTERPOS;
374 #define END_REGISTER_VP_INTRINSIC(VPID) break;
375 #include "llvm/IR/VPIntrinsics.def"
376   }
377   return None;
378 }
379 
380 /// \return The data (payload) operand of this store or scatter.
381 Value *VPIntrinsic::getMemoryDataParam() const {
382   auto DataParamOpt = getMemoryDataParamPos(getIntrinsicID());
383   if (!DataParamOpt.hasValue())
384     return nullptr;
385   return getArgOperand(DataParamOpt.getValue());
386 }
387 
388 Optional<unsigned> VPIntrinsic::getMemoryDataParamPos(Intrinsic::ID VPID) {
389   switch (VPID) {
390   default:
391     break;
392 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
393 #define VP_PROPERTY_MEMOP(POINTERPOS, DATAPOS) return DATAPOS;
394 #define END_REGISTER_VP_INTRINSIC(VPID) break;
395 #include "llvm/IR/VPIntrinsics.def"
396   }
397   return None;
398 }
399 
400 bool VPIntrinsic::isVPIntrinsic(Intrinsic::ID ID) {
401   switch (ID) {
402   default:
403     break;
404 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS)                    \
405   case Intrinsic::VPID:                                                        \
406     return true;
407 #include "llvm/IR/VPIntrinsics.def"
408   }
409   return false;
410 }
411 
412 // Equivalent non-predicated opcode
413 Optional<unsigned> VPIntrinsic::getFunctionalOpcodeForVP(Intrinsic::ID ID) {
414   switch (ID) {
415   default:
416     break;
417 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
418 #define VP_PROPERTY_FUNCTIONAL_OPC(OPC) return Instruction::OPC;
419 #define END_REGISTER_VP_INTRINSIC(VPID) break;
420 #include "llvm/IR/VPIntrinsics.def"
421   }
422   return None;
423 }
424 
425 Intrinsic::ID VPIntrinsic::getForOpcode(unsigned IROPC) {
426   switch (IROPC) {
427   default:
428     break;
429 
430 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) break;
431 #define VP_PROPERTY_FUNCTIONAL_OPC(OPC) case Instruction::OPC:
432 #define END_REGISTER_VP_INTRINSIC(VPID) return Intrinsic::VPID;
433 #include "llvm/IR/VPIntrinsics.def"
434   }
435   return Intrinsic::not_intrinsic;
436 }
437 
438 bool VPIntrinsic::canIgnoreVectorLengthParam() const {
439   using namespace PatternMatch;
440 
441   ElementCount EC = getStaticVectorLength();
442 
443   // No vlen param - no lanes masked-off by it.
444   auto *VLParam = getVectorLengthParam();
445   if (!VLParam)
446     return true;
447 
448   // Note that the VP intrinsic causes undefined behavior if the Explicit Vector
449   // Length parameter is strictly greater-than the number of vector elements of
450   // the operation. This function returns true when this is detected statically
451   // in the IR.
452 
453   // Check whether "W == vscale * EC.getKnownMinValue()"
454   if (EC.isScalable()) {
455     // Undig the DL
456     const auto *ParMod = this->getModule();
457     if (!ParMod)
458       return false;
459     const auto &DL = ParMod->getDataLayout();
460 
461     // Compare vscale patterns
462     uint64_t VScaleFactor;
463     if (match(VLParam, m_c_Mul(m_ConstantInt(VScaleFactor), m_VScale(DL))))
464       return VScaleFactor >= EC.getKnownMinValue();
465     return (EC.getKnownMinValue() == 1) && match(VLParam, m_VScale(DL));
466   }
467 
468   // standard SIMD operation
469   const auto *VLConst = dyn_cast<ConstantInt>(VLParam);
470   if (!VLConst)
471     return false;
472 
473   uint64_t VLNum = VLConst->getZExtValue();
474   if (VLNum >= EC.getKnownMinValue())
475     return true;
476 
477   return false;
478 }
479 
480 Function *VPIntrinsic::getDeclarationForParams(Module *M, Intrinsic::ID VPID,
481                                                Type *ReturnType,
482                                                ArrayRef<Value *> Params) {
483   assert(isVPIntrinsic(VPID) && "not a VP intrinsic");
484   Function *VPFunc;
485   switch (VPID) {
486   default: {
487     Type *OverloadTy = Params[0]->getType();
488     if (VPReductionIntrinsic::isVPReduction(VPID))
489       OverloadTy =
490           Params[*VPReductionIntrinsic::getVectorParamPos(VPID)]->getType();
491 
492     VPFunc = Intrinsic::getDeclaration(M, VPID, OverloadTy);
493     break;
494   }
495   case Intrinsic::vp_merge:
496   case Intrinsic::vp_select:
497     VPFunc = Intrinsic::getDeclaration(M, VPID, {Params[1]->getType()});
498     break;
499   case Intrinsic::vp_load:
500     VPFunc = Intrinsic::getDeclaration(
501         M, VPID, {ReturnType, Params[0]->getType()});
502     break;
503   case Intrinsic::vp_gather:
504     VPFunc = Intrinsic::getDeclaration(
505         M, VPID, {ReturnType, Params[0]->getType()});
506     break;
507   case Intrinsic::vp_store:
508     VPFunc = Intrinsic::getDeclaration(
509         M, VPID, {Params[0]->getType(), Params[1]->getType()});
510     break;
511   case Intrinsic::vp_scatter:
512     VPFunc = Intrinsic::getDeclaration(
513         M, VPID, {Params[0]->getType(), Params[1]->getType()});
514     break;
515   }
516   assert(VPFunc && "Could not declare VP intrinsic");
517   return VPFunc;
518 }
519 
520 bool VPReductionIntrinsic::isVPReduction(Intrinsic::ID ID) {
521   switch (ID) {
522   default:
523     break;
524 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
525 #define VP_PROPERTY_REDUCTION(STARTPOS, ...) return true;
526 #define END_REGISTER_VP_INTRINSIC(VPID) break;
527 #include "llvm/IR/VPIntrinsics.def"
528   }
529   return false;
530 }
531 
532 unsigned VPReductionIntrinsic::getVectorParamPos() const {
533   return *VPReductionIntrinsic::getVectorParamPos(getIntrinsicID());
534 }
535 
536 unsigned VPReductionIntrinsic::getStartParamPos() const {
537   return *VPReductionIntrinsic::getStartParamPos(getIntrinsicID());
538 }
539 
540 Optional<unsigned> VPReductionIntrinsic::getVectorParamPos(Intrinsic::ID ID) {
541   switch (ID) {
542 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
543 #define VP_PROPERTY_REDUCTION(STARTPOS, VECTORPOS) return VECTORPOS;
544 #define END_REGISTER_VP_INTRINSIC(VPID) break;
545 #include "llvm/IR/VPIntrinsics.def"
546   default:
547     break;
548   }
549   return None;
550 }
551 
552 Optional<unsigned> VPReductionIntrinsic::getStartParamPos(Intrinsic::ID ID) {
553   switch (ID) {
554 #define BEGIN_REGISTER_VP_INTRINSIC(VPID, ...) case Intrinsic::VPID:
555 #define VP_PROPERTY_REDUCTION(STARTPOS, VECTORPOS) return STARTPOS;
556 #define END_REGISTER_VP_INTRINSIC(VPID) break;
557 #include "llvm/IR/VPIntrinsics.def"
558   default:
559     break;
560   }
561   return None;
562 }
563 
564 Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const {
565   switch (getIntrinsicID()) {
566   case Intrinsic::uadd_with_overflow:
567   case Intrinsic::sadd_with_overflow:
568   case Intrinsic::uadd_sat:
569   case Intrinsic::sadd_sat:
570     return Instruction::Add;
571   case Intrinsic::usub_with_overflow:
572   case Intrinsic::ssub_with_overflow:
573   case Intrinsic::usub_sat:
574   case Intrinsic::ssub_sat:
575     return Instruction::Sub;
576   case Intrinsic::umul_with_overflow:
577   case Intrinsic::smul_with_overflow:
578     return Instruction::Mul;
579   default:
580     llvm_unreachable("Invalid intrinsic");
581   }
582 }
583 
584 bool BinaryOpIntrinsic::isSigned() const {
585   switch (getIntrinsicID()) {
586   case Intrinsic::sadd_with_overflow:
587   case Intrinsic::ssub_with_overflow:
588   case Intrinsic::smul_with_overflow:
589   case Intrinsic::sadd_sat:
590   case Intrinsic::ssub_sat:
591     return true;
592   default:
593     return false;
594   }
595 }
596 
597 unsigned BinaryOpIntrinsic::getNoWrapKind() const {
598   if (isSigned())
599     return OverflowingBinaryOperator::NoSignedWrap;
600   else
601     return OverflowingBinaryOperator::NoUnsignedWrap;
602 }
603 
604 const GCStatepointInst *GCProjectionInst::getStatepoint() const {
605   const Value *Token = getArgOperand(0);
606 
607   // This takes care both of relocates for call statepoints and relocates
608   // on normal path of invoke statepoint.
609   if (!isa<LandingPadInst>(Token))
610     return cast<GCStatepointInst>(Token);
611 
612   // This relocate is on exceptional path of an invoke statepoint
613   const BasicBlock *InvokeBB =
614     cast<Instruction>(Token)->getParent()->getUniquePredecessor();
615 
616   assert(InvokeBB && "safepoints should have unique landingpads");
617   assert(InvokeBB->getTerminator() &&
618          "safepoint block should be well formed");
619 
620   return cast<GCStatepointInst>(InvokeBB->getTerminator());
621 }
622 
623 Value *GCRelocateInst::getBasePtr() const {
624   if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live))
625     return *(Opt->Inputs.begin() + getBasePtrIndex());
626   return *(getStatepoint()->arg_begin() + getBasePtrIndex());
627 }
628 
629 Value *GCRelocateInst::getDerivedPtr() const {
630   if (auto Opt = getStatepoint()->getOperandBundle(LLVMContext::OB_gc_live))
631     return *(Opt->Inputs.begin() + getDerivedPtrIndex());
632   return *(getStatepoint()->arg_begin() + getDerivedPtrIndex());
633 }
634