1 //===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- C++ -*-=====//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines some vectorizer utilities.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
15 #define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
17 #include "llvm/IR/Intrinsics.h"
18 #include "llvm/IR/IntrinsicInst.h"
19 #include "llvm/Target/TargetLibraryInfo.h"
23 /// \brief Identify if the intrinsic is trivially vectorizable.
25 /// This method returns true if the intrinsic's argument types are all
26 /// scalars for the scalar form of the intrinsic and all vectors for
27 /// the vector form of the intrinsic.
28 static inline bool isTriviallyVectorizable(Intrinsic::ID ID) {
36 case Intrinsic::log10:
39 case Intrinsic::minnum:
40 case Intrinsic::maxnum:
41 case Intrinsic::copysign:
42 case Intrinsic::floor:
44 case Intrinsic::trunc:
46 case Intrinsic::nearbyint:
47 case Intrinsic::round:
48 case Intrinsic::bswap:
49 case Intrinsic::ctpop:
52 case Intrinsic::fmuladd:
62 static bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
63 unsigned ScalarOpdIdx) {
68 return (ScalarOpdIdx == 1);
74 static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
75 Intrinsic::ID ValidIntrinsicID) {
76 if (I.getNumArgOperands() != 1 ||
77 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
78 I.getType() != I.getArgOperand(0)->getType() ||
80 return Intrinsic::not_intrinsic;
82 return ValidIntrinsicID;
85 static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
86 Intrinsic::ID ValidIntrinsicID) {
87 if (I.getNumArgOperands() != 2 ||
88 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
89 !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
90 I.getType() != I.getArgOperand(0)->getType() ||
91 I.getType() != I.getArgOperand(1)->getType() ||
93 return Intrinsic::not_intrinsic;
95 return ValidIntrinsicID;
99 getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
100 // If we have an intrinsic call, check if it is trivially vectorizable.
101 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
102 Intrinsic::ID ID = II->getIntrinsicID();
103 if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
104 ID == Intrinsic::lifetime_end || ID == Intrinsic::assume)
107 return Intrinsic::not_intrinsic;
111 return Intrinsic::not_intrinsic;
114 Function *F = CI->getCalledFunction();
115 // We're going to make assumptions on the semantics of the functions, check
116 // that the target knows that it's available in this environment and it does
117 // not have local linkage.
118 if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
119 return Intrinsic::not_intrinsic;
121 // Otherwise check if we have a call to a function that can be turned into a
129 return checkUnaryFloatSignature(*CI, Intrinsic::sin);
133 return checkUnaryFloatSignature(*CI, Intrinsic::cos);
137 return checkUnaryFloatSignature(*CI, Intrinsic::exp);
141 return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
145 return checkUnaryFloatSignature(*CI, Intrinsic::log);
147 case LibFunc::log10f:
148 case LibFunc::log10l:
149 return checkUnaryFloatSignature(*CI, Intrinsic::log10);
153 return checkUnaryFloatSignature(*CI, Intrinsic::log2);
157 return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
161 return checkBinaryFloatSignature(*CI, Intrinsic::minnum);
165 return checkBinaryFloatSignature(*CI, Intrinsic::maxnum);
166 case LibFunc::copysign:
167 case LibFunc::copysignf:
168 case LibFunc::copysignl:
169 return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
171 case LibFunc::floorf:
172 case LibFunc::floorl:
173 return checkUnaryFloatSignature(*CI, Intrinsic::floor);
177 return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
179 case LibFunc::truncf:
180 case LibFunc::truncl:
181 return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
185 return checkUnaryFloatSignature(*CI, Intrinsic::rint);
186 case LibFunc::nearbyint:
187 case LibFunc::nearbyintf:
188 case LibFunc::nearbyintl:
189 return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
191 case LibFunc::roundf:
192 case LibFunc::roundl:
193 return checkUnaryFloatSignature(*CI, Intrinsic::round);
197 return checkBinaryFloatSignature(*CI, Intrinsic::pow);
200 return Intrinsic::not_intrinsic;