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::copysign:
40 case Intrinsic::floor:
42 case Intrinsic::trunc:
44 case Intrinsic::nearbyint:
45 case Intrinsic::round:
46 case Intrinsic::ctpop:
49 case Intrinsic::fmuladd:
56 static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
57 Intrinsic::ID ValidIntrinsicID) {
58 if (I.getNumArgOperands() != 1 ||
59 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
60 I.getType() != I.getArgOperand(0)->getType() ||
62 return Intrinsic::not_intrinsic;
64 return ValidIntrinsicID;
67 static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
68 Intrinsic::ID ValidIntrinsicID) {
69 if (I.getNumArgOperands() != 2 ||
70 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
71 !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
72 I.getType() != I.getArgOperand(0)->getType() ||
73 I.getType() != I.getArgOperand(1)->getType() ||
75 return Intrinsic::not_intrinsic;
77 return ValidIntrinsicID;
81 getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
82 // If we have an intrinsic call, check if it is trivially vectorizable.
83 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
84 Intrinsic::ID ID = II->getIntrinsicID();
85 if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
86 ID == Intrinsic::lifetime_end)
89 return Intrinsic::not_intrinsic;
93 return Intrinsic::not_intrinsic;
96 Function *F = CI->getCalledFunction();
97 // We're going to make assumptions on the semantics of the functions, check
98 // that the target knows that it's available in this environment and it does
99 // not have local linkage.
100 if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
101 return Intrinsic::not_intrinsic;
103 // Otherwise check if we have a call to a function that can be turned into a
111 return checkUnaryFloatSignature(*CI, Intrinsic::sin);
115 return checkUnaryFloatSignature(*CI, Intrinsic::cos);
119 return checkUnaryFloatSignature(*CI, Intrinsic::exp);
123 return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
127 return checkUnaryFloatSignature(*CI, Intrinsic::log);
129 case LibFunc::log10f:
130 case LibFunc::log10l:
131 return checkUnaryFloatSignature(*CI, Intrinsic::log10);
135 return checkUnaryFloatSignature(*CI, Intrinsic::log2);
139 return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
140 case LibFunc::copysign:
141 case LibFunc::copysignf:
142 case LibFunc::copysignl:
143 return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
145 case LibFunc::floorf:
146 case LibFunc::floorl:
147 return checkUnaryFloatSignature(*CI, Intrinsic::floor);
151 return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
153 case LibFunc::truncf:
154 case LibFunc::truncl:
155 return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
159 return checkUnaryFloatSignature(*CI, Intrinsic::rint);
160 case LibFunc::nearbyint:
161 case LibFunc::nearbyintf:
162 case LibFunc::nearbyintl:
163 return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
165 case LibFunc::roundf:
166 case LibFunc::roundl:
167 return checkUnaryFloatSignature(*CI, Intrinsic::round);
171 return checkBinaryFloatSignature(*CI, Intrinsic::pow);
174 return Intrinsic::not_intrinsic;