1 //===----------- VectorUtils.cpp - Vectorizer utility functions -----------===// 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 vectorizer utilities. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Analysis/VectorUtils.h" 15 16 /// \brief Identify if the intrinsic is trivially vectorizable. 17 /// This method returns true if the intrinsic's argument types are all 18 /// scalars for the scalar form of the intrinsic and all vectors for 19 /// the vector form of the intrinsic. 20 bool llvm::isTriviallyVectorizable(Intrinsic::ID ID) { 21 switch (ID) { 22 case Intrinsic::sqrt: 23 case Intrinsic::sin: 24 case Intrinsic::cos: 25 case Intrinsic::exp: 26 case Intrinsic::exp2: 27 case Intrinsic::log: 28 case Intrinsic::log10: 29 case Intrinsic::log2: 30 case Intrinsic::fabs: 31 case Intrinsic::minnum: 32 case Intrinsic::maxnum: 33 case Intrinsic::copysign: 34 case Intrinsic::floor: 35 case Intrinsic::ceil: 36 case Intrinsic::trunc: 37 case Intrinsic::rint: 38 case Intrinsic::nearbyint: 39 case Intrinsic::round: 40 case Intrinsic::bswap: 41 case Intrinsic::ctpop: 42 case Intrinsic::pow: 43 case Intrinsic::fma: 44 case Intrinsic::fmuladd: 45 case Intrinsic::ctlz: 46 case Intrinsic::cttz: 47 case Intrinsic::powi: 48 return true; 49 default: 50 return false; 51 } 52 } 53 54 /// \brief Identifies if the intrinsic has a scalar operand. It check for 55 /// ctlz,cttz and powi special intrinsics whose argument is scalar. 56 bool llvm::hasVectorInstrinsicScalarOpd(Intrinsic::ID ID, 57 unsigned ScalarOpdIdx) { 58 switch (ID) { 59 case Intrinsic::ctlz: 60 case Intrinsic::cttz: 61 case Intrinsic::powi: 62 return (ScalarOpdIdx == 1); 63 default: 64 return false; 65 } 66 } 67 68 /// \brief Check call has a unary float signature 69 /// It checks following: 70 /// a) call should have a single argument 71 /// b) argument type should be floating point type 72 /// c) call instruction type and argument type should be same 73 /// d) call should only reads memory. 74 /// If all these condition is met then return ValidIntrinsicID 75 /// else return not_intrinsic. 76 llvm::Intrinsic::ID 77 llvm::checkUnaryFloatSignature(const CallInst &I, 78 Intrinsic::ID ValidIntrinsicID) { 79 if (I.getNumArgOperands() != 1 || 80 !I.getArgOperand(0)->getType()->isFloatingPointTy() || 81 I.getType() != I.getArgOperand(0)->getType() || !I.onlyReadsMemory()) 82 return Intrinsic::not_intrinsic; 83 84 return ValidIntrinsicID; 85 } 86 87 /// \brief Check call has a binary float signature 88 /// It checks following: 89 /// a) call should have 2 arguments. 90 /// b) arguments type should be floating point type 91 /// c) call instruction type and arguments type should be same 92 /// d) call should only reads memory. 93 /// If all these condition is met then return ValidIntrinsicID 94 /// else return not_intrinsic. 95 llvm::Intrinsic::ID 96 llvm::checkBinaryFloatSignature(const CallInst &I, 97 Intrinsic::ID ValidIntrinsicID) { 98 if (I.getNumArgOperands() != 2 || 99 !I.getArgOperand(0)->getType()->isFloatingPointTy() || 100 !I.getArgOperand(1)->getType()->isFloatingPointTy() || 101 I.getType() != I.getArgOperand(0)->getType() || 102 I.getType() != I.getArgOperand(1)->getType() || !I.onlyReadsMemory()) 103 return Intrinsic::not_intrinsic; 104 105 return ValidIntrinsicID; 106 } 107 108 /// \brief Returns intrinsic ID for call. 109 /// For the input call instruction it finds mapping intrinsic and returns 110 /// its ID, in case it does not found it return not_intrinsic. 111 llvm::Intrinsic::ID llvm::getIntrinsicIDForCall(CallInst *CI, 112 const TargetLibraryInfo *TLI) { 113 // If we have an intrinsic call, check if it is trivially vectorizable. 114 if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) { 115 Intrinsic::ID ID = II->getIntrinsicID(); 116 if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start || 117 ID == Intrinsic::lifetime_end || ID == Intrinsic::assume) 118 return ID; 119 return Intrinsic::not_intrinsic; 120 } 121 122 if (!TLI) 123 return Intrinsic::not_intrinsic; 124 125 LibFunc::Func Func; 126 Function *F = CI->getCalledFunction(); 127 // We're going to make assumptions on the semantics of the functions, check 128 // that the target knows that it's available in this environment and it does 129 // not have local linkage. 130 if (!F || F->hasLocalLinkage() || !TLI->getLibFunc(F->getName(), Func)) 131 return Intrinsic::not_intrinsic; 132 133 // Otherwise check if we have a call to a function that can be turned into a 134 // vector intrinsic. 135 switch (Func) { 136 default: 137 break; 138 case LibFunc::sin: 139 case LibFunc::sinf: 140 case LibFunc::sinl: 141 return checkUnaryFloatSignature(*CI, Intrinsic::sin); 142 case LibFunc::cos: 143 case LibFunc::cosf: 144 case LibFunc::cosl: 145 return checkUnaryFloatSignature(*CI, Intrinsic::cos); 146 case LibFunc::exp: 147 case LibFunc::expf: 148 case LibFunc::expl: 149 return checkUnaryFloatSignature(*CI, Intrinsic::exp); 150 case LibFunc::exp2: 151 case LibFunc::exp2f: 152 case LibFunc::exp2l: 153 return checkUnaryFloatSignature(*CI, Intrinsic::exp2); 154 case LibFunc::log: 155 case LibFunc::logf: 156 case LibFunc::logl: 157 return checkUnaryFloatSignature(*CI, Intrinsic::log); 158 case LibFunc::log10: 159 case LibFunc::log10f: 160 case LibFunc::log10l: 161 return checkUnaryFloatSignature(*CI, Intrinsic::log10); 162 case LibFunc::log2: 163 case LibFunc::log2f: 164 case LibFunc::log2l: 165 return checkUnaryFloatSignature(*CI, Intrinsic::log2); 166 case LibFunc::fabs: 167 case LibFunc::fabsf: 168 case LibFunc::fabsl: 169 return checkUnaryFloatSignature(*CI, Intrinsic::fabs); 170 case LibFunc::fmin: 171 case LibFunc::fminf: 172 case LibFunc::fminl: 173 return checkBinaryFloatSignature(*CI, Intrinsic::minnum); 174 case LibFunc::fmax: 175 case LibFunc::fmaxf: 176 case LibFunc::fmaxl: 177 return checkBinaryFloatSignature(*CI, Intrinsic::maxnum); 178 case LibFunc::copysign: 179 case LibFunc::copysignf: 180 case LibFunc::copysignl: 181 return checkBinaryFloatSignature(*CI, Intrinsic::copysign); 182 case LibFunc::floor: 183 case LibFunc::floorf: 184 case LibFunc::floorl: 185 return checkUnaryFloatSignature(*CI, Intrinsic::floor); 186 case LibFunc::ceil: 187 case LibFunc::ceilf: 188 case LibFunc::ceill: 189 return checkUnaryFloatSignature(*CI, Intrinsic::ceil); 190 case LibFunc::trunc: 191 case LibFunc::truncf: 192 case LibFunc::truncl: 193 return checkUnaryFloatSignature(*CI, Intrinsic::trunc); 194 case LibFunc::rint: 195 case LibFunc::rintf: 196 case LibFunc::rintl: 197 return checkUnaryFloatSignature(*CI, Intrinsic::rint); 198 case LibFunc::nearbyint: 199 case LibFunc::nearbyintf: 200 case LibFunc::nearbyintl: 201 return checkUnaryFloatSignature(*CI, Intrinsic::nearbyint); 202 case LibFunc::round: 203 case LibFunc::roundf: 204 case LibFunc::roundl: 205 return checkUnaryFloatSignature(*CI, Intrinsic::round); 206 case LibFunc::pow: 207 case LibFunc::powf: 208 case LibFunc::powl: 209 return checkBinaryFloatSignature(*CI, Intrinsic::pow); 210 } 211 212 return Intrinsic::not_intrinsic; 213 } 214