]>
git.proxmox.com Git - rustc.git/blob - src/llvm/include/llvm/Transforms/Utils/VectorUtils.h
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
;