Flip on vectorization of bswap intrinsics.
[oota-llvm.git] / include / llvm / Transforms / Utils / VectorUtils.h
1 //===- llvm/Transforms/Utils/VectorUtils.h - Vector utilities -*- C++ -*-=====//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines some vectorizer utilities.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
15 #define LLVM_TRANSFORMS_UTILS_VECTORUTILS_H
16
17 #include "llvm/IR/Intrinsics.h"
18 #include "llvm/IR/IntrinsicInst.h"
19 #include "llvm/Target/TargetLibraryInfo.h"
20
21 namespace llvm {
22
23 /// \brief Identify if the intrinsic is trivially vectorizable.
24 ///
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) {
29   switch (ID) {
30   case Intrinsic::sqrt:
31   case Intrinsic::sin:
32   case Intrinsic::cos:
33   case Intrinsic::exp:
34   case Intrinsic::exp2:
35   case Intrinsic::log:
36   case Intrinsic::log10:
37   case Intrinsic::log2:
38   case Intrinsic::fabs:
39   case Intrinsic::copysign:
40   case Intrinsic::floor:
41   case Intrinsic::ceil:
42   case Intrinsic::trunc:
43   case Intrinsic::rint:
44   case Intrinsic::nearbyint:
45   case Intrinsic::round:
46   case Intrinsic::bswap:
47   case Intrinsic::ctpop:
48   case Intrinsic::pow:
49   case Intrinsic::fma:
50   case Intrinsic::fmuladd:
51     return true;
52   default:
53     return false;
54   }
55 }
56
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() ||
62       !I.onlyReadsMemory())
63     return Intrinsic::not_intrinsic;
64
65   return ValidIntrinsicID;
66 }
67
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() ||
75       !I.onlyReadsMemory())
76     return Intrinsic::not_intrinsic;
77
78   return ValidIntrinsicID;
79 }
80
81 static Intrinsic::ID
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)
88       return ID;
89     else
90       return Intrinsic::not_intrinsic;
91   }
92
93   if (!TLI)
94     return Intrinsic::not_intrinsic;
95
96   LibFunc::Func Func;
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;
103
104   // Otherwise check if we have a call to a function that can be turned into a
105   // vector intrinsic.
106   switch (Func) {
107   default:
108     break;
109   case LibFunc::sin:
110   case LibFunc::sinf:
111   case LibFunc::sinl:
112     return checkUnaryFloatSignature(*CI, Intrinsic::sin);
113   case LibFunc::cos:
114   case LibFunc::cosf:
115   case LibFunc::cosl:
116     return checkUnaryFloatSignature(*CI, Intrinsic::cos);
117   case LibFunc::exp:
118   case LibFunc::expf:
119   case LibFunc::expl:
120     return checkUnaryFloatSignature(*CI, Intrinsic::exp);
121   case LibFunc::exp2:
122   case LibFunc::exp2f:
123   case LibFunc::exp2l:
124     return checkUnaryFloatSignature(*CI, Intrinsic::exp2);
125   case LibFunc::log:
126   case LibFunc::logf:
127   case LibFunc::logl:
128     return checkUnaryFloatSignature(*CI, Intrinsic::log);
129   case LibFunc::log10:
130   case LibFunc::log10f:
131   case LibFunc::log10l:
132     return checkUnaryFloatSignature(*CI, Intrinsic::log10);
133   case LibFunc::log2:
134   case LibFunc::log2f:
135   case LibFunc::log2l:
136     return checkUnaryFloatSignature(*CI, Intrinsic::log2);
137   case LibFunc::fabs:
138   case LibFunc::fabsf:
139   case LibFunc::fabsl:
140     return checkUnaryFloatSignature(*CI, Intrinsic::fabs);
141   case LibFunc::copysign:
142   case LibFunc::copysignf:
143   case LibFunc::copysignl:
144     return checkBinaryFloatSignature(*CI, Intrinsic::copysign);
145   case LibFunc::floor:
146   case LibFunc::floorf:
147   case LibFunc::floorl:
148     return checkUnaryFloatSignature(*CI, Intrinsic::floor);
149   case LibFunc::ceil:
150   case LibFunc::ceilf:
151   case LibFunc::ceill:
152     return checkUnaryFloatSignature(*CI, Intrinsic::ceil);
153   case LibFunc::trunc:
154   case LibFunc::truncf:
155   case LibFunc::truncl:
156     return checkUnaryFloatSignature(*CI, Intrinsic::trunc);
157   case LibFunc::rint:
158   case LibFunc::rintf:
159   case LibFunc::rintl:
160     return checkUnaryFloatSignature(*CI, Intrinsic::rint);
161   case LibFunc::nearbyint:
162   case LibFunc::nearbyintf:
163   case LibFunc::nearbyintl:
164     return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint);
165   case LibFunc::round:
166   case LibFunc::roundf:
167   case LibFunc::roundl:
168     return checkUnaryFloatSignature(*CI, Intrinsic::round);
169   case LibFunc::pow:
170   case LibFunc::powf:
171   case LibFunc::powl:
172     return checkBinaryFloatSignature(*CI, Intrinsic::pow);
173   }
174
175   return Intrinsic::not_intrinsic;
176 }
177
178 } // llvm namespace
179
180 #endif