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