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::bswap:
47 case Intrinsic::ctpop:
50 case Intrinsic::fmuladd:
60 static bool hasVectorInstrinsicScalarOpd(Intrinsic::ID ID,
61 unsigned ScalarOpdIdx) {
66 return (ScalarOpdIdx == 1);
72 static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
73 Intrinsic::ID ValidIntrinsicID) {
74 if (I.getNumArgOperands() != 1 ||
75 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
76 I.getType() != I.getArgOperand(0)->getType() ||
78 return Intrinsic::not_intrinsic;
80 return ValidIntrinsicID;
83 static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
84 Intrinsic::ID ValidIntrinsicID) {
85 if (I.getNumArgOperands() != 2 ||
86 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
87 !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
88 I.getType() != I.getArgOperand(0)->getType() ||
89 I.getType() != I.getArgOperand(1)->getType() ||
91 return Intrinsic::not_intrinsic;
93 return ValidIntrinsicID;
97 getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
98 // If we have an intrinsic call, check if it is trivially vectorizable.
99 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
100 Intrinsic::ID ID = II->getIntrinsicID();
101 if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
102 ID == Intrinsic::lifetime_end)
105 return Intrinsic::not_intrinsic;
109 return Intrinsic::not_intrinsic;
112 Function *F = CI->getCalledFunction();
113 // We're going to make assumptions on the semantics of the functions, check
114 // that the target knows that it's available in this environment and it does
115 // not have local linkage.
116 if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
117 return Intrinsic::not_intrinsic;
119 // Otherwise check if we have a call to a function that can be turned into a
127 return checkUnaryFloatSignature(*CI, Intrinsic::sin);
131 return checkUnaryFloatSignature(*CI, Intrinsic::cos);
135 return checkUnaryFloatSignature(*CI, Intrinsic::exp);
139 return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
143 return checkUnaryFloatSignature(*CI, Intrinsic::log);
145 case LibFunc::log10f:
146 case LibFunc::log10l:
147 return checkUnaryFloatSignature(*CI, Intrinsic::log10);
151 return checkUnaryFloatSignature(*CI, Intrinsic::log2);
155 return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
156 case LibFunc::copysign:
157 case LibFunc::copysignf:
158 case LibFunc::copysignl:
159 return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
161 case LibFunc::floorf:
162 case LibFunc::floorl:
163 return checkUnaryFloatSignature(*CI, Intrinsic::floor);
167 return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
169 case LibFunc::truncf:
170 case LibFunc::truncl:
171 return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
175 return checkUnaryFloatSignature(*CI, Intrinsic::rint);
176 case LibFunc::nearbyint:
177 case LibFunc::nearbyintf:
178 case LibFunc::nearbyintl:
179 return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
181 case LibFunc::roundf:
182 case LibFunc::roundl:
183 return checkUnaryFloatSignature(*CI, Intrinsic::round);
187 return checkBinaryFloatSignature(*CI, Intrinsic::pow);
190 return Intrinsic::not_intrinsic;