1 //===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements methods that make it really easy to deal with intrinsic
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
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.
21 //===----------------------------------------------------------------------===//
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"
33 #include "llvm/Support/raw_ostream.h"
36 //===----------------------------------------------------------------------===//
37 /// DbgVariableIntrinsic - This is the common base class for debug info
38 /// intrinsics for variables.
41 Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const {
42 Value *Op = getArgOperand(0);
43 if (AllowNullOp && !Op)
46 auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
47 if (auto *V = dyn_cast<ValueAsMetadata>(MD))
50 // When the value goes to null, it gets replaced by an empty MDNode.
51 assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
55 Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const {
56 if (auto Fragment = getExpression()->getFragmentInfo())
57 return Fragment->SizeInBits;
58 return getVariable()->getSizeInBits();
61 int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
63 assert(Name.startswith("llvm."));
65 // Do successive binary searches of the dotted name components. For
66 // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
67 // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
68 // "llvm.gc.experimental.statepoint", and then we will stop as the range is
69 // size 1. During the search, we can skip the prefix that we already know is
70 // identical. By using strncmp we consider names with differing suffixes to
71 // be part of the equal range.
72 size_t CmpEnd = 4; // Skip the "llvm" component.
73 const char *const *Low = NameTable.begin();
74 const char *const *High = NameTable.end();
75 const char *const *LastLow = Low;
76 while (CmpEnd < Name.size() && High - Low > 0) {
77 size_t CmpStart = CmpEnd;
78 CmpEnd = Name.find('.', CmpStart + 1);
79 CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd;
80 auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
81 return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
84 std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
89 if (LastLow == NameTable.end())
91 StringRef NameFound = *LastLow;
92 if (Name == NameFound ||
93 (Name.startswith(NameFound) && Name[NameFound.size()] == '.'))
94 return LastLow - NameTable.begin();
98 Value *InstrProfIncrementInst::getStep() const {
99 if (InstrProfIncrementInstStep::classof(this)) {
100 return const_cast<Value *>(getArgOperand(4));
102 const Module *M = getModule();
103 LLVMContext &Context = M->getContext();
104 return ConstantInt::get(Type::getInt64Ty(Context), 1);
107 Optional<RoundingMode> ConstrainedFPIntrinsic::getRoundingMode() const {
108 unsigned NumOperands = getNumArgOperands();
110 cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
111 if (!MD || !isa<MDString>(MD))
113 return StrToRoundingMode(cast<MDString>(MD)->getString());
116 Optional<fp::ExceptionBehavior>
117 ConstrainedFPIntrinsic::getExceptionBehavior() const {
118 unsigned NumOperands = getNumArgOperands();
120 cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata();
121 if (!MD || !isa<MDString>(MD))
123 return StrToExceptionBehavior(cast<MDString>(MD)->getString());
126 FCmpInst::Predicate ConstrainedFPCmpIntrinsic::getPredicate() const {
127 Metadata *MD = cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
128 if (!MD || !isa<MDString>(MD))
129 return FCmpInst::BAD_FCMP_PREDICATE;
130 return StringSwitch<FCmpInst::Predicate>(cast<MDString>(MD)->getString())
131 .Case("oeq", FCmpInst::FCMP_OEQ)
132 .Case("ogt", FCmpInst::FCMP_OGT)
133 .Case("oge", FCmpInst::FCMP_OGE)
134 .Case("olt", FCmpInst::FCMP_OLT)
135 .Case("ole", FCmpInst::FCMP_OLE)
136 .Case("one", FCmpInst::FCMP_ONE)
137 .Case("ord", FCmpInst::FCMP_ORD)
138 .Case("uno", FCmpInst::FCMP_UNO)
139 .Case("ueq", FCmpInst::FCMP_UEQ)
140 .Case("ugt", FCmpInst::FCMP_UGT)
141 .Case("uge", FCmpInst::FCMP_UGE)
142 .Case("ult", FCmpInst::FCMP_ULT)
143 .Case("ule", FCmpInst::FCMP_ULE)
144 .Case("une", FCmpInst::FCMP_UNE)
145 .Default(FCmpInst::BAD_FCMP_PREDICATE);
148 bool ConstrainedFPIntrinsic::isUnaryOp() const {
149 switch (getIntrinsicID()) {
152 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
153 case Intrinsic::INTRINSIC: \
155 #include "llvm/IR/ConstrainedOps.def"
159 bool ConstrainedFPIntrinsic::isTernaryOp() const {
160 switch (getIntrinsicID()) {
163 #define INSTRUCTION(NAME, NARG, ROUND_MODE, INTRINSIC) \
164 case Intrinsic::INTRINSIC: \
166 #include "llvm/IR/ConstrainedOps.def"
170 bool ConstrainedFPIntrinsic::classof(const IntrinsicInst *I) {
171 switch (I->getIntrinsicID()) {
172 #define INSTRUCTION(NAME, NARGS, ROUND_MODE, INTRINSIC) \
173 case Intrinsic::INTRINSIC:
174 #include "llvm/IR/ConstrainedOps.def"
181 ElementCount VPIntrinsic::getStaticVectorLength() const {
182 auto GetVectorLengthOfType = [](const Type *T) -> ElementCount {
183 auto VT = cast<VectorType>(T);
184 auto ElemCount = VT->getElementCount();
188 auto VPMask = getMaskParam();
189 return GetVectorLengthOfType(VPMask->getType());
192 Value *VPIntrinsic::getMaskParam() const {
193 auto maskPos = GetMaskParamPos(getIntrinsicID());
195 return getArgOperand(maskPos.getValue());
199 Value *VPIntrinsic::getVectorLengthParam() const {
200 auto vlenPos = GetVectorLengthParamPos(getIntrinsicID());
202 return getArgOperand(vlenPos.getValue());
206 Optional<int> VPIntrinsic::GetMaskParamPos(Intrinsic::ID IntrinsicID) {
207 switch (IntrinsicID) {
211 #define REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
212 case Intrinsic::VPID: \
214 #include "llvm/IR/VPIntrinsics.def"
218 Optional<int> VPIntrinsic::GetVectorLengthParamPos(Intrinsic::ID IntrinsicID) {
219 switch (IntrinsicID) {
223 #define REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
224 case Intrinsic::VPID: \
226 #include "llvm/IR/VPIntrinsics.def"
230 bool VPIntrinsic::IsVPIntrinsic(Intrinsic::ID ID) {
235 #define REGISTER_VP_INTRINSIC(VPID, MASKPOS, VLENPOS) \
236 case Intrinsic::VPID: \
238 #include "llvm/IR/VPIntrinsics.def"
243 // Equivalent non-predicated opcode
244 unsigned VPIntrinsic::GetFunctionalOpcodeForVP(Intrinsic::ID ID) {
247 return Instruction::Call;
249 #define HANDLE_VP_TO_OC(VPID, OC) \
250 case Intrinsic::VPID: \
251 return Instruction::OC;
252 #include "llvm/IR/VPIntrinsics.def"
256 Intrinsic::ID VPIntrinsic::GetForOpcode(unsigned OC) {
259 return Intrinsic::not_intrinsic;
261 #define HANDLE_VP_TO_OC(VPID, OC) \
262 case Instruction::OC: \
263 return Intrinsic::VPID;
264 #include "llvm/IR/VPIntrinsics.def"
268 bool VPIntrinsic::canIgnoreVectorLengthParam() const {
269 using namespace PatternMatch;
271 ElementCount EC = getStaticVectorLength();
273 // No vlen param - no lanes masked-off by it.
274 auto *VLParam = getVectorLengthParam();
278 // Note that the VP intrinsic causes undefined behavior if the Explicit Vector
279 // Length parameter is strictly greater-than the number of vector elements of
280 // the operation. This function returns true when this is detected statically
283 // Check whether "W == vscale * EC.Min"
286 auto ParMod = this->getModule();
289 const auto &DL = ParMod->getDataLayout();
291 // Compare vscale patterns
292 uint64_t VScaleFactor;
293 if (match(VLParam, m_c_Mul(m_ConstantInt(VScaleFactor), m_VScale(DL))))
294 return VScaleFactor >= EC.Min;
295 return (EC.Min == 1) && match(VLParam, m_VScale(DL));
298 // standard SIMD operation
299 auto VLConst = dyn_cast<ConstantInt>(VLParam);
303 uint64_t VLNum = VLConst->getZExtValue();
310 Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const {
311 switch (getIntrinsicID()) {
312 case Intrinsic::uadd_with_overflow:
313 case Intrinsic::sadd_with_overflow:
314 case Intrinsic::uadd_sat:
315 case Intrinsic::sadd_sat:
316 return Instruction::Add;
317 case Intrinsic::usub_with_overflow:
318 case Intrinsic::ssub_with_overflow:
319 case Intrinsic::usub_sat:
320 case Intrinsic::ssub_sat:
321 return Instruction::Sub;
322 case Intrinsic::umul_with_overflow:
323 case Intrinsic::smul_with_overflow:
324 return Instruction::Mul;
326 llvm_unreachable("Invalid intrinsic");
330 bool BinaryOpIntrinsic::isSigned() const {
331 switch (getIntrinsicID()) {
332 case Intrinsic::sadd_with_overflow:
333 case Intrinsic::ssub_with_overflow:
334 case Intrinsic::smul_with_overflow:
335 case Intrinsic::sadd_sat:
336 case Intrinsic::ssub_sat:
343 unsigned BinaryOpIntrinsic::getNoWrapKind() const {
345 return OverflowingBinaryOperator::NoSignedWrap;
347 return OverflowingBinaryOperator::NoUnsignedWrap;