1 //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the IntrinsicLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/CodeGen/IntrinsicLowering.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/IR/CallSite.h" 16 #include "llvm/IR/Constants.h" 17 #include "llvm/IR/DataLayout.h" 18 #include "llvm/IR/DerivedTypes.h" 19 #include "llvm/IR/IRBuilder.h" 20 #include "llvm/IR/Module.h" 21 #include "llvm/IR/Type.h" 22 #include "llvm/Support/ErrorHandling.h" 23 #include "llvm/Support/raw_ostream.h" 24 using namespace llvm; 25 26 /// This function is used when we want to lower an intrinsic call to a call of 27 /// an external function. This handles hard cases such as when there was already 28 /// a prototype for the external function, but that prototype doesn't match the 29 /// arguments we expect to pass in. 30 template <class ArgIt> 31 static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, 32 ArgIt ArgBegin, ArgIt ArgEnd, 33 Type *RetTy) { 34 // If we haven't already looked up this function, check to see if the 35 // program already contains a function with this name. 36 Module *M = CI->getModule(); 37 // Get or insert the definition now. 38 std::vector<Type *> ParamTys; 39 for (ArgIt I = ArgBegin; I != ArgEnd; ++I) 40 ParamTys.push_back((*I)->getType()); 41 FunctionCallee FCache = 42 M->getOrInsertFunction(NewFn, FunctionType::get(RetTy, ParamTys, false)); 43 44 IRBuilder<> Builder(CI->getParent(), CI->getIterator()); 45 SmallVector<Value *, 8> Args(ArgBegin, ArgEnd); 46 CallInst *NewCI = Builder.CreateCall(FCache, Args); 47 NewCI->setName(CI->getName()); 48 if (!CI->use_empty()) 49 CI->replaceAllUsesWith(NewCI); 50 return NewCI; 51 } 52 53 // VisualStudio defines setjmp as _setjmp 54 #if defined(_MSC_VER) && defined(setjmp) && \ 55 !defined(setjmp_undefined_for_msvc) 56 # pragma push_macro("setjmp") 57 # undef setjmp 58 # define setjmp_undefined_for_msvc 59 #endif 60 61 /// Emit the code to lower bswap of V before the specified instruction IP. 62 static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) { 63 assert(V->getType()->isIntOrIntVectorTy() && "Can't bswap a non-integer type!"); 64 65 unsigned BitSize = V->getType()->getScalarSizeInBits(); 66 67 IRBuilder<> Builder(IP); 68 69 switch(BitSize) { 70 default: llvm_unreachable("Unhandled type size of value to byteswap!"); 71 case 16: { 72 Value *Tmp1 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 73 "bswap.2"); 74 Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 75 "bswap.1"); 76 V = Builder.CreateOr(Tmp1, Tmp2, "bswap.i16"); 77 break; 78 } 79 case 32: { 80 Value *Tmp4 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 81 "bswap.4"); 82 Value *Tmp3 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 83 "bswap.3"); 84 Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 85 "bswap.2"); 86 Value *Tmp1 = Builder.CreateLShr(V,ConstantInt::get(V->getType(), 24), 87 "bswap.1"); 88 Tmp3 = Builder.CreateAnd(Tmp3, 89 ConstantInt::get(V->getType(), 0xFF0000), 90 "bswap.and3"); 91 Tmp2 = Builder.CreateAnd(Tmp2, 92 ConstantInt::get(V->getType(), 0xFF00), 93 "bswap.and2"); 94 Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or1"); 95 Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or2"); 96 V = Builder.CreateOr(Tmp4, Tmp2, "bswap.i32"); 97 break; 98 } 99 case 64: { 100 Value *Tmp8 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 56), 101 "bswap.8"); 102 Value *Tmp7 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 40), 103 "bswap.7"); 104 Value *Tmp6 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), 105 "bswap.6"); 106 Value *Tmp5 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), 107 "bswap.5"); 108 Value* Tmp4 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), 109 "bswap.4"); 110 Value* Tmp3 = Builder.CreateLShr(V, 111 ConstantInt::get(V->getType(), 24), 112 "bswap.3"); 113 Value* Tmp2 = Builder.CreateLShr(V, 114 ConstantInt::get(V->getType(), 40), 115 "bswap.2"); 116 Value* Tmp1 = Builder.CreateLShr(V, 117 ConstantInt::get(V->getType(), 56), 118 "bswap.1"); 119 Tmp7 = Builder.CreateAnd(Tmp7, 120 ConstantInt::get(V->getType(), 121 0xFF000000000000ULL), 122 "bswap.and7"); 123 Tmp6 = Builder.CreateAnd(Tmp6, 124 ConstantInt::get(V->getType(), 125 0xFF0000000000ULL), 126 "bswap.and6"); 127 Tmp5 = Builder.CreateAnd(Tmp5, 128 ConstantInt::get(V->getType(), 129 0xFF00000000ULL), 130 "bswap.and5"); 131 Tmp4 = Builder.CreateAnd(Tmp4, 132 ConstantInt::get(V->getType(), 133 0xFF000000ULL), 134 "bswap.and4"); 135 Tmp3 = Builder.CreateAnd(Tmp3, 136 ConstantInt::get(V->getType(), 137 0xFF0000ULL), 138 "bswap.and3"); 139 Tmp2 = Builder.CreateAnd(Tmp2, 140 ConstantInt::get(V->getType(), 141 0xFF00ULL), 142 "bswap.and2"); 143 Tmp8 = Builder.CreateOr(Tmp8, Tmp7, "bswap.or1"); 144 Tmp6 = Builder.CreateOr(Tmp6, Tmp5, "bswap.or2"); 145 Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or3"); 146 Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or4"); 147 Tmp8 = Builder.CreateOr(Tmp8, Tmp6, "bswap.or5"); 148 Tmp4 = Builder.CreateOr(Tmp4, Tmp2, "bswap.or6"); 149 V = Builder.CreateOr(Tmp8, Tmp4, "bswap.i64"); 150 break; 151 } 152 } 153 return V; 154 } 155 156 /// Emit the code to lower ctpop of V before the specified instruction IP. 157 static Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) { 158 assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!"); 159 160 static const uint64_t MaskValues[6] = { 161 0x5555555555555555ULL, 0x3333333333333333ULL, 162 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, 163 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL 164 }; 165 166 IRBuilder<> Builder(IP); 167 168 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 169 unsigned WordSize = (BitSize + 63) / 64; 170 Value *Count = ConstantInt::get(V->getType(), 0); 171 172 for (unsigned n = 0; n < WordSize; ++n) { 173 Value *PartValue = V; 174 for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize); 175 i <<= 1, ++ct) { 176 Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]); 177 Value *LHS = Builder.CreateAnd(PartValue, MaskCst, "cppop.and1"); 178 Value *VShift = Builder.CreateLShr(PartValue, 179 ConstantInt::get(V->getType(), i), 180 "ctpop.sh"); 181 Value *RHS = Builder.CreateAnd(VShift, MaskCst, "cppop.and2"); 182 PartValue = Builder.CreateAdd(LHS, RHS, "ctpop.step"); 183 } 184 Count = Builder.CreateAdd(PartValue, Count, "ctpop.part"); 185 if (BitSize > 64) { 186 V = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 64), 187 "ctpop.part.sh"); 188 BitSize -= 64; 189 } 190 } 191 192 return Count; 193 } 194 195 /// Emit the code to lower ctlz of V before the specified instruction IP. 196 static Value *LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP) { 197 198 IRBuilder<> Builder(IP); 199 200 unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); 201 for (unsigned i = 1; i < BitSize; i <<= 1) { 202 Value *ShVal = ConstantInt::get(V->getType(), i); 203 ShVal = Builder.CreateLShr(V, ShVal, "ctlz.sh"); 204 V = Builder.CreateOr(V, ShVal, "ctlz.step"); 205 } 206 207 V = Builder.CreateNot(V); 208 return LowerCTPOP(Context, V, IP); 209 } 210 211 static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, 212 const char *Dname, 213 const char *LDname) { 214 CallSite CS(CI); 215 switch (CI->getArgOperand(0)->getType()->getTypeID()) { 216 default: llvm_unreachable("Invalid type in intrinsic"); 217 case Type::FloatTyID: 218 ReplaceCallWith(Fname, CI, CS.arg_begin(), CS.arg_end(), 219 Type::getFloatTy(CI->getContext())); 220 break; 221 case Type::DoubleTyID: 222 ReplaceCallWith(Dname, CI, CS.arg_begin(), CS.arg_end(), 223 Type::getDoubleTy(CI->getContext())); 224 break; 225 case Type::X86_FP80TyID: 226 case Type::FP128TyID: 227 case Type::PPC_FP128TyID: 228 ReplaceCallWith(LDname, CI, CS.arg_begin(), CS.arg_end(), 229 CI->getArgOperand(0)->getType()); 230 break; 231 } 232 } 233 234 void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { 235 IRBuilder<> Builder(CI); 236 LLVMContext &Context = CI->getContext(); 237 238 const Function *Callee = CI->getCalledFunction(); 239 assert(Callee && "Cannot lower an indirect call!"); 240 241 CallSite CS(CI); 242 switch (Callee->getIntrinsicID()) { 243 case Intrinsic::not_intrinsic: 244 report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ 245 Callee->getName() + "'!"); 246 default: 247 report_fatal_error("Code generator does not support intrinsic function '"+ 248 Callee->getName()+"'!"); 249 250 case Intrinsic::expect: { 251 // Just replace __builtin_expect(exp, c) with EXP. 252 Value *V = CI->getArgOperand(0); 253 CI->replaceAllUsesWith(V); 254 break; 255 } 256 257 // The setjmp/longjmp intrinsics should only exist in the code if it was 258 // never optimized (ie, right out of the CFE), or if it has been hacked on 259 // by the lowerinvoke pass. In both cases, the right thing to do is to 260 // convert the call to an explicit setjmp or longjmp call. 261 case Intrinsic::setjmp: { 262 Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), 263 Type::getInt32Ty(Context)); 264 if (!CI->getType()->isVoidTy()) 265 CI->replaceAllUsesWith(V); 266 break; 267 } 268 case Intrinsic::sigsetjmp: 269 if (!CI->getType()->isVoidTy()) 270 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 271 break; 272 273 case Intrinsic::longjmp: { 274 ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), 275 Type::getVoidTy(Context)); 276 break; 277 } 278 279 case Intrinsic::siglongjmp: { 280 // Insert the call to abort 281 ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), 282 Type::getVoidTy(Context)); 283 break; 284 } 285 case Intrinsic::ctpop: 286 CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); 287 break; 288 289 case Intrinsic::bswap: 290 CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); 291 break; 292 293 case Intrinsic::ctlz: 294 CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); 295 break; 296 297 case Intrinsic::cttz: { 298 // cttz(x) -> ctpop(~X & (X-1)) 299 Value *Src = CI->getArgOperand(0); 300 Value *NotSrc = Builder.CreateNot(Src); 301 NotSrc->setName(Src->getName() + ".not"); 302 Value *SrcM1 = ConstantInt::get(Src->getType(), 1); 303 SrcM1 = Builder.CreateSub(Src, SrcM1); 304 Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); 305 CI->replaceAllUsesWith(Src); 306 break; 307 } 308 309 case Intrinsic::stacksave: 310 case Intrinsic::stackrestore: { 311 if (!Warned) 312 errs() << "WARNING: this target does not support the llvm.stack" 313 << (Callee->getIntrinsicID() == Intrinsic::stacksave ? 314 "save" : "restore") << " intrinsic.\n"; 315 Warned = true; 316 if (Callee->getIntrinsicID() == Intrinsic::stacksave) 317 CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); 318 break; 319 } 320 321 case Intrinsic::get_dynamic_area_offset: 322 errs() << "WARNING: this target does not support the custom llvm.get." 323 "dynamic.area.offset. It is being lowered to a constant 0\n"; 324 // Just lower it to a constant 0 because for most targets 325 // @llvm.get.dynamic.area.offset is lowered to zero. 326 CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 0)); 327 break; 328 case Intrinsic::returnaddress: 329 case Intrinsic::frameaddress: 330 errs() << "WARNING: this target does not support the llvm." 331 << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? 332 "return" : "frame") << "address intrinsic.\n"; 333 CI->replaceAllUsesWith( 334 ConstantPointerNull::get(cast<PointerType>(CI->getType()))); 335 break; 336 case Intrinsic::addressofreturnaddress: 337 errs() << "WARNING: this target does not support the " 338 "llvm.addressofreturnaddress intrinsic.\n"; 339 CI->replaceAllUsesWith( 340 ConstantPointerNull::get(cast<PointerType>(CI->getType()))); 341 break; 342 343 case Intrinsic::prefetch: 344 break; // Simply strip out prefetches on unsupported architectures 345 346 case Intrinsic::pcmarker: 347 break; // Simply strip out pcmarker on unsupported architectures 348 case Intrinsic::readcyclecounter: { 349 errs() << "WARNING: this target does not support the llvm.readcyclecoun" 350 << "ter intrinsic. It is being lowered to a constant 0\n"; 351 CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0)); 352 break; 353 } 354 355 case Intrinsic::dbg_declare: 356 case Intrinsic::dbg_label: 357 break; // Simply strip out debugging intrinsics 358 359 case Intrinsic::eh_typeid_for: 360 // Return something different to eh_selector. 361 CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 362 break; 363 364 case Intrinsic::annotation: 365 case Intrinsic::ptr_annotation: 366 // Just drop the annotation, but forward the value 367 CI->replaceAllUsesWith(CI->getOperand(0)); 368 break; 369 370 case Intrinsic::assume: 371 case Intrinsic::var_annotation: 372 break; // Strip out these intrinsics 373 374 case Intrinsic::memcpy: { 375 Type *IntPtr = DL.getIntPtrType(Context); 376 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 377 /* isSigned */ false); 378 Value *Ops[3]; 379 Ops[0] = CI->getArgOperand(0); 380 Ops[1] = CI->getArgOperand(1); 381 Ops[2] = Size; 382 ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 383 break; 384 } 385 case Intrinsic::memmove: { 386 Type *IntPtr = DL.getIntPtrType(Context); 387 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 388 /* isSigned */ false); 389 Value *Ops[3]; 390 Ops[0] = CI->getArgOperand(0); 391 Ops[1] = CI->getArgOperand(1); 392 Ops[2] = Size; 393 ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 394 break; 395 } 396 case Intrinsic::memset: { 397 Value *Op0 = CI->getArgOperand(0); 398 Type *IntPtr = DL.getIntPtrType(Op0->getType()); 399 Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, 400 /* isSigned */ false); 401 Value *Ops[3]; 402 Ops[0] = Op0; 403 // Extend the amount to i32. 404 Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), 405 Type::getInt32Ty(Context), 406 /* isSigned */ false); 407 Ops[2] = Size; 408 ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); 409 break; 410 } 411 case Intrinsic::sqrt: { 412 ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); 413 break; 414 } 415 case Intrinsic::log: { 416 ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); 417 break; 418 } 419 case Intrinsic::log2: { 420 ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l"); 421 break; 422 } 423 case Intrinsic::log10: { 424 ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l"); 425 break; 426 } 427 case Intrinsic::exp: { 428 ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl"); 429 break; 430 } 431 case Intrinsic::exp2: { 432 ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l"); 433 break; 434 } 435 case Intrinsic::pow: { 436 ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl"); 437 break; 438 } 439 case Intrinsic::sin: { 440 ReplaceFPIntrinsicWithCall(CI, "sinf", "sin", "sinl"); 441 break; 442 } 443 case Intrinsic::cos: { 444 ReplaceFPIntrinsicWithCall(CI, "cosf", "cos", "cosl"); 445 break; 446 } 447 case Intrinsic::floor: { 448 ReplaceFPIntrinsicWithCall(CI, "floorf", "floor", "floorl"); 449 break; 450 } 451 case Intrinsic::ceil: { 452 ReplaceFPIntrinsicWithCall(CI, "ceilf", "ceil", "ceill"); 453 break; 454 } 455 case Intrinsic::trunc: { 456 ReplaceFPIntrinsicWithCall(CI, "truncf", "trunc", "truncl"); 457 break; 458 } 459 case Intrinsic::round: { 460 ReplaceFPIntrinsicWithCall(CI, "roundf", "round", "roundl"); 461 break; 462 } 463 case Intrinsic::copysign: { 464 ReplaceFPIntrinsicWithCall(CI, "copysignf", "copysign", "copysignl"); 465 break; 466 } 467 case Intrinsic::flt_rounds: 468 // Lower to "round to the nearest" 469 if (!CI->getType()->isVoidTy()) 470 CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); 471 break; 472 case Intrinsic::invariant_start: 473 case Intrinsic::lifetime_start: 474 // Discard region information. 475 CI->replaceAllUsesWith(UndefValue::get(CI->getType())); 476 break; 477 case Intrinsic::invariant_end: 478 case Intrinsic::lifetime_end: 479 // Discard region information. 480 break; 481 } 482 483 assert(CI->use_empty() && 484 "Lowering should have eliminated any uses of the intrinsic call!"); 485 CI->eraseFromParent(); 486 } 487 488 bool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { 489 // Verify this is a simple bswap. 490 if (CI->getNumArgOperands() != 1 || 491 CI->getType() != CI->getArgOperand(0)->getType() || 492 !CI->getType()->isIntegerTy()) 493 return false; 494 495 IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); 496 if (!Ty) 497 return false; 498 499 // Okay, we can do this xform, do so now. 500 Module *M = CI->getModule(); 501 Function *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); 502 503 Value *Op = CI->getArgOperand(0); 504 Op = CallInst::Create(Int, Op, CI->getName(), CI); 505 506 CI->replaceAllUsesWith(Op); 507 CI->eraseFromParent(); 508 return true; 509 } 510