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:
57 static Intrinsic::ID checkUnaryFloatSignature(const CallInst &I,
58 Intrinsic::ID ValidIntrinsicID) {
59 if (I.getNumArgOperands() != 1 ||
60 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
61 I.getType() != I.getArgOperand(0)->getType() ||
63 return Intrinsic::not_intrinsic;
65 return ValidIntrinsicID;
68 static Intrinsic::ID checkBinaryFloatSignature(const CallInst &I,
69 Intrinsic::ID ValidIntrinsicID) {
70 if (I.getNumArgOperands() != 2 ||
71 !I.getArgOperand(0)->getType()->isFloatingPointTy() ||
72 !I.getArgOperand(1)->getType()->isFloatingPointTy() ||
73 I.getType() != I.getArgOperand(0)->getType() ||
74 I.getType() != I.getArgOperand(1)->getType() ||
76 return Intrinsic::not_intrinsic;
78 return ValidIntrinsicID;
82 getIntrinsicIDForCall(CallInst *CI, const TargetLibraryInfo *TLI) {
83 // If we have an intrinsic call, check if it is trivially vectorizable.
84 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
85 Intrinsic::ID ID = II->getIntrinsicID();
86 if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
87 ID == Intrinsic::lifetime_end)
90 return Intrinsic::not_intrinsic;
94 return Intrinsic::not_intrinsic;
97 Function *F = CI->getCalledFunction();
98 // We're going to make assumptions on the semantics of the functions, check
99 // that the target knows that it's available in this environment and it does
100 // not have local linkage.
101 if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func))
102 return Intrinsic::not_intrinsic;
104 // Otherwise check if we have a call to a function that can be turned into a
112 return checkUnaryFloatSignature(*CI, Intrinsic::sin);
116 return checkUnaryFloatSignature(*CI, Intrinsic::cos);
120 return checkUnaryFloatSignature(*CI, Intrinsic::exp);
124 return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
128 return checkUnaryFloatSignature(*CI, Intrinsic::log);
130 case LibFunc::log10f:
131 case LibFunc::log10l:
132 return checkUnaryFloatSignature(*CI, Intrinsic::log10);
136 return checkUnaryFloatSignature(*CI, Intrinsic::log2);
140 return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
141 case LibFunc::copysign:
142 case LibFunc::copysignf:
143 case LibFunc::copysignl:
144 return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
146 case LibFunc::floorf:
147 case LibFunc::floorl:
148 return checkUnaryFloatSignature(*CI, Intrinsic::floor);
152 return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
154 case LibFunc::truncf:
155 case LibFunc::truncl:
156 return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
160 return checkUnaryFloatSignature(*CI, Intrinsic::rint);
161 case LibFunc::nearbyint:
162 case LibFunc::nearbyintf:
163 case LibFunc::nearbyintl:
164 return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
166 case LibFunc::roundf:
167 case LibFunc::roundl:
168 return checkUnaryFloatSignature(*CI, Intrinsic::round);
172 return checkBinaryFloatSignature(*CI, Intrinsic::pow);
175 return Intrinsic::not_intrinsic;