1
//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===//
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 implements the IntrinsicLowering class.
12
//===----------------------------------------------------------------------===//
14
#include "llvm/Constants.h"
15
#include "llvm/DerivedTypes.h"
16
#include "llvm/Module.h"
17
#include "llvm/Type.h"
18
#include "llvm/CodeGen/IntrinsicLowering.h"
19
#include "llvm/Support/ErrorHandling.h"
20
#include "llvm/Support/IRBuilder.h"
21
#include "llvm/Support/raw_ostream.h"
22
#include "llvm/Target/TargetData.h"
23
#include "llvm/ADT/SmallVector.h"
26
template <class ArgIt>
27
static void EnsureFunctionExists(Module &M, const char *Name,
28
ArgIt ArgBegin, ArgIt ArgEnd,
30
// Insert a correctly-typed definition now.
31
std::vector<const Type *> ParamTys;
32
for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
33
ParamTys.push_back(I->getType());
34
M.getOrInsertFunction(Name, FunctionType::get(RetTy, ParamTys, false));
37
static void EnsureFPIntrinsicsExist(Module &M, Function *Fn,
39
const char *DName, const char *LDName) {
40
// Insert definitions for all the floating point types.
41
switch((int)Fn->arg_begin()->getType()->getTypeID()) {
43
EnsureFunctionExists(M, FName, Fn->arg_begin(), Fn->arg_end(),
44
Type::getFloatTy(M.getContext()));
46
case Type::DoubleTyID:
47
EnsureFunctionExists(M, DName, Fn->arg_begin(), Fn->arg_end(),
48
Type::getDoubleTy(M.getContext()));
50
case Type::X86_FP80TyID:
52
case Type::PPC_FP128TyID:
53
EnsureFunctionExists(M, LDName, Fn->arg_begin(), Fn->arg_end(),
54
Fn->arg_begin()->getType());
59
/// ReplaceCallWith - This function is used when we want to lower an intrinsic
60
/// call to a call of an external function. This handles hard cases such as
61
/// when there was already a prototype for the external function, and if that
62
/// prototype doesn't match the arguments we expect to pass in.
63
template <class ArgIt>
64
static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
65
ArgIt ArgBegin, ArgIt ArgEnd,
67
// If we haven't already looked up this function, check to see if the
68
// program already contains a function with this name.
69
Module *M = CI->getParent()->getParent()->getParent();
70
// Get or insert the definition now.
71
std::vector<const Type *> ParamTys;
72
for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
73
ParamTys.push_back((*I)->getType());
74
Constant* FCache = M->getOrInsertFunction(NewFn,
75
FunctionType::get(RetTy, ParamTys, false));
77
IRBuilder<> Builder(CI->getParent(), CI);
78
SmallVector<Value *, 8> Args(ArgBegin, ArgEnd);
79
CallInst *NewCI = Builder.CreateCall(FCache, Args.begin(), Args.end());
80
NewCI->setName(CI->getName());
82
CI->replaceAllUsesWith(NewCI);
86
void IntrinsicLowering::AddPrototypes(Module &M) {
87
LLVMContext &Context = M.getContext();
88
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
89
if (I->isDeclaration() && !I->use_empty())
90
switch (I->getIntrinsicID()) {
92
case Intrinsic::setjmp:
93
EnsureFunctionExists(M, "setjmp", I->arg_begin(), I->arg_end(),
94
Type::getInt32Ty(M.getContext()));
96
case Intrinsic::longjmp:
97
EnsureFunctionExists(M, "longjmp", I->arg_begin(), I->arg_end(),
98
Type::getVoidTy(M.getContext()));
100
case Intrinsic::siglongjmp:
101
EnsureFunctionExists(M, "abort", I->arg_end(), I->arg_end(),
102
Type::getVoidTy(M.getContext()));
104
case Intrinsic::memcpy:
105
M.getOrInsertFunction("memcpy",
106
Type::getInt8PtrTy(Context),
107
Type::getInt8PtrTy(Context),
108
Type::getInt8PtrTy(Context),
109
TD.getIntPtrType(Context), (Type *)0);
111
case Intrinsic::memmove:
112
M.getOrInsertFunction("memmove",
113
Type::getInt8PtrTy(Context),
114
Type::getInt8PtrTy(Context),
115
Type::getInt8PtrTy(Context),
116
TD.getIntPtrType(Context), (Type *)0);
118
case Intrinsic::memset:
119
M.getOrInsertFunction("memset",
120
Type::getInt8PtrTy(Context),
121
Type::getInt8PtrTy(Context),
122
Type::getInt32Ty(M.getContext()),
123
TD.getIntPtrType(Context), (Type *)0);
125
case Intrinsic::sqrt:
126
EnsureFPIntrinsicsExist(M, I, "sqrtf", "sqrt", "sqrtl");
129
EnsureFPIntrinsicsExist(M, I, "sinf", "sin", "sinl");
132
EnsureFPIntrinsicsExist(M, I, "cosf", "cos", "cosl");
135
EnsureFPIntrinsicsExist(M, I, "powf", "pow", "powl");
138
EnsureFPIntrinsicsExist(M, I, "logf", "log", "logl");
140
case Intrinsic::log2:
141
EnsureFPIntrinsicsExist(M, I, "log2f", "log2", "log2l");
143
case Intrinsic::log10:
144
EnsureFPIntrinsicsExist(M, I, "log10f", "log10", "log10l");
147
EnsureFPIntrinsicsExist(M, I, "expf", "exp", "expl");
149
case Intrinsic::exp2:
150
EnsureFPIntrinsicsExist(M, I, "exp2f", "exp2", "exp2l");
155
/// LowerBSWAP - Emit the code to lower bswap of V before the specified
157
static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) {
158
assert(V->getType()->isIntegerTy() && "Can't bswap a non-integer type!");
160
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
162
IRBuilder<> Builder(IP->getParent(), IP);
165
default: llvm_unreachable("Unhandled type size of value to byteswap!");
167
Value *Tmp1 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8),
169
Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8),
171
V = Builder.CreateOr(Tmp1, Tmp2, "bswap.i16");
175
Value *Tmp4 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24),
177
Value *Tmp3 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8),
179
Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8),
181
Value *Tmp1 = Builder.CreateLShr(V,ConstantInt::get(V->getType(), 24),
183
Tmp3 = Builder.CreateAnd(Tmp3,
184
ConstantInt::get(Type::getInt32Ty(Context), 0xFF0000),
186
Tmp2 = Builder.CreateAnd(Tmp2,
187
ConstantInt::get(Type::getInt32Ty(Context), 0xFF00),
189
Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or1");
190
Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or2");
191
V = Builder.CreateOr(Tmp4, Tmp2, "bswap.i32");
195
Value *Tmp8 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 56),
197
Value *Tmp7 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 40),
199
Value *Tmp6 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24),
201
Value *Tmp5 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8),
203
Value* Tmp4 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8),
205
Value* Tmp3 = Builder.CreateLShr(V,
206
ConstantInt::get(V->getType(), 24),
208
Value* Tmp2 = Builder.CreateLShr(V,
209
ConstantInt::get(V->getType(), 40),
211
Value* Tmp1 = Builder.CreateLShr(V,
212
ConstantInt::get(V->getType(), 56),
214
Tmp7 = Builder.CreateAnd(Tmp7,
215
ConstantInt::get(Type::getInt64Ty(Context),
216
0xFF000000000000ULL),
218
Tmp6 = Builder.CreateAnd(Tmp6,
219
ConstantInt::get(Type::getInt64Ty(Context),
222
Tmp5 = Builder.CreateAnd(Tmp5,
223
ConstantInt::get(Type::getInt64Ty(Context),
226
Tmp4 = Builder.CreateAnd(Tmp4,
227
ConstantInt::get(Type::getInt64Ty(Context),
230
Tmp3 = Builder.CreateAnd(Tmp3,
231
ConstantInt::get(Type::getInt64Ty(Context),
234
Tmp2 = Builder.CreateAnd(Tmp2,
235
ConstantInt::get(Type::getInt64Ty(Context),
238
Tmp8 = Builder.CreateOr(Tmp8, Tmp7, "bswap.or1");
239
Tmp6 = Builder.CreateOr(Tmp6, Tmp5, "bswap.or2");
240
Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or3");
241
Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or4");
242
Tmp8 = Builder.CreateOr(Tmp8, Tmp6, "bswap.or5");
243
Tmp4 = Builder.CreateOr(Tmp4, Tmp2, "bswap.or6");
244
V = Builder.CreateOr(Tmp8, Tmp4, "bswap.i64");
251
/// LowerCTPOP - Emit the code to lower ctpop of V before the specified
253
static Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) {
254
assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!");
256
static const uint64_t MaskValues[6] = {
257
0x5555555555555555ULL, 0x3333333333333333ULL,
258
0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
259
0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
262
IRBuilder<> Builder(IP->getParent(), IP);
264
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
265
unsigned WordSize = (BitSize + 63) / 64;
266
Value *Count = ConstantInt::get(V->getType(), 0);
268
for (unsigned n = 0; n < WordSize; ++n) {
269
Value *PartValue = V;
270
for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize);
272
Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]);
273
Value *LHS = Builder.CreateAnd(PartValue, MaskCst, "cppop.and1");
274
Value *VShift = Builder.CreateLShr(PartValue,
275
ConstantInt::get(V->getType(), i),
277
Value *RHS = Builder.CreateAnd(VShift, MaskCst, "cppop.and2");
278
PartValue = Builder.CreateAdd(LHS, RHS, "ctpop.step");
280
Count = Builder.CreateAdd(PartValue, Count, "ctpop.part");
282
V = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 64),
291
/// LowerCTLZ - Emit the code to lower ctlz of V before the specified
293
static Value *LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP) {
295
IRBuilder<> Builder(IP->getParent(), IP);
297
unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
298
for (unsigned i = 1; i < BitSize; i <<= 1) {
299
Value *ShVal = ConstantInt::get(V->getType(), i);
300
ShVal = Builder.CreateLShr(V, ShVal, "ctlz.sh");
301
V = Builder.CreateOr(V, ShVal, "ctlz.step");
304
V = Builder.CreateNot(V);
305
return LowerCTPOP(Context, V, IP);
308
static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname,
310
const char *LDname) {
311
switch (CI->getOperand(1)->getType()->getTypeID()) {
312
default: llvm_unreachable("Invalid type in intrinsic");
313
case Type::FloatTyID:
314
ReplaceCallWith(Fname, CI, CI->op_begin() + 1, CI->op_end(),
315
Type::getFloatTy(CI->getContext()));
317
case Type::DoubleTyID:
318
ReplaceCallWith(Dname, CI, CI->op_begin() + 1, CI->op_end(),
319
Type::getDoubleTy(CI->getContext()));
321
case Type::X86_FP80TyID:
322
case Type::FP128TyID:
323
case Type::PPC_FP128TyID:
324
ReplaceCallWith(LDname, CI, CI->op_begin() + 1, CI->op_end(),
325
CI->getOperand(1)->getType());
330
void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
331
IRBuilder<> Builder(CI->getParent(), CI);
332
LLVMContext &Context = CI->getContext();
334
Function *Callee = CI->getCalledFunction();
335
assert(Callee && "Cannot lower an indirect call!");
337
switch (Callee->getIntrinsicID()) {
338
case Intrinsic::not_intrinsic:
339
llvm_report_error("Cannot lower a call to a non-intrinsic function '"+
340
Callee->getName() + "'!");
342
llvm_report_error("Code generator does not support intrinsic function '"+
343
Callee->getName()+"'!");
345
// The setjmp/longjmp intrinsics should only exist in the code if it was
346
// never optimized (ie, right out of the CFE), or if it has been hacked on
347
// by the lowerinvoke pass. In both cases, the right thing to do is to
348
// convert the call to an explicit setjmp or longjmp call.
349
case Intrinsic::setjmp: {
350
Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin() + 1, CI->op_end(),
351
Type::getInt32Ty(Context));
352
if (!CI->getType()->isVoidTy())
353
CI->replaceAllUsesWith(V);
356
case Intrinsic::sigsetjmp:
357
if (!CI->getType()->isVoidTy())
358
CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
361
case Intrinsic::longjmp: {
362
ReplaceCallWith("longjmp", CI, CI->op_begin() + 1, CI->op_end(),
363
Type::getVoidTy(Context));
367
case Intrinsic::siglongjmp: {
368
// Insert the call to abort
369
ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(),
370
Type::getVoidTy(Context));
373
case Intrinsic::ctpop:
374
CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getOperand(1), CI));
377
case Intrinsic::bswap:
378
CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getOperand(1), CI));
381
case Intrinsic::ctlz:
382
CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getOperand(1), CI));
385
case Intrinsic::cttz: {
386
// cttz(x) -> ctpop(~X & (X-1))
387
Value *Src = CI->getOperand(1);
388
Value *NotSrc = Builder.CreateNot(Src);
389
NotSrc->setName(Src->getName() + ".not");
390
Value *SrcM1 = ConstantInt::get(Src->getType(), 1);
391
SrcM1 = Builder.CreateSub(Src, SrcM1);
392
Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI);
393
CI->replaceAllUsesWith(Src);
397
case Intrinsic::stacksave:
398
case Intrinsic::stackrestore: {
400
errs() << "WARNING: this target does not support the llvm.stack"
401
<< (Callee->getIntrinsicID() == Intrinsic::stacksave ?
402
"save" : "restore") << " intrinsic.\n";
404
if (Callee->getIntrinsicID() == Intrinsic::stacksave)
405
CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
409
case Intrinsic::returnaddress:
410
case Intrinsic::frameaddress:
411
errs() << "WARNING: this target does not support the llvm."
412
<< (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
413
"return" : "frame") << "address intrinsic.\n";
414
CI->replaceAllUsesWith(ConstantPointerNull::get(
415
cast<PointerType>(CI->getType())));
418
case Intrinsic::prefetch:
419
break; // Simply strip out prefetches on unsupported architectures
421
case Intrinsic::pcmarker:
422
break; // Simply strip out pcmarker on unsupported architectures
423
case Intrinsic::readcyclecounter: {
424
errs() << "WARNING: this target does not support the llvm.readcyclecoun"
425
<< "ter intrinsic. It is being lowered to a constant 0\n";
426
CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0));
430
case Intrinsic::dbg_declare:
431
break; // Simply strip out debugging intrinsics
433
case Intrinsic::eh_exception:
434
case Intrinsic::eh_selector:
435
CI->replaceAllUsesWith(Constant::getNullValue(CI->getType()));
438
case Intrinsic::eh_typeid_for:
439
// Return something different to eh_selector.
440
CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1));
443
case Intrinsic::var_annotation:
444
break; // Strip out annotate intrinsic
446
case Intrinsic::memcpy: {
447
const IntegerType *IntPtr = TD.getIntPtrType(Context);
448
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
449
/* isSigned */ false);
451
Ops[0] = CI->getOperand(1);
452
Ops[1] = CI->getOperand(2);
454
ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getOperand(1)->getType());
457
case Intrinsic::memmove: {
458
const IntegerType *IntPtr = TD.getIntPtrType(Context);
459
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
460
/* isSigned */ false);
462
Ops[0] = CI->getOperand(1);
463
Ops[1] = CI->getOperand(2);
465
ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getOperand(1)->getType());
468
case Intrinsic::memset: {
469
const IntegerType *IntPtr = TD.getIntPtrType(Context);
470
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
471
/* isSigned */ false);
473
Ops[0] = CI->getOperand(1);
474
// Extend the amount to i32.
475
Ops[1] = Builder.CreateIntCast(CI->getOperand(2), Type::getInt32Ty(Context),
476
/* isSigned */ false);
478
ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getOperand(1)->getType());
481
case Intrinsic::sqrt: {
482
ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl");
485
case Intrinsic::log: {
486
ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl");
489
case Intrinsic::log2: {
490
ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l");
493
case Intrinsic::log10: {
494
ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l");
497
case Intrinsic::exp: {
498
ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl");
501
case Intrinsic::exp2: {
502
ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l");
505
case Intrinsic::pow: {
506
ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl");
509
case Intrinsic::flt_rounds:
510
// Lower to "round to the nearest"
511
if (!CI->getType()->isVoidTy())
512
CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1));
514
case Intrinsic::invariant_start:
515
case Intrinsic::lifetime_start:
516
// Discard region information.
517
CI->replaceAllUsesWith(UndefValue::get(CI->getType()));
519
case Intrinsic::invariant_end:
520
case Intrinsic::lifetime_end:
521
// Discard region information.
525
assert(CI->use_empty() &&
526
"Lowering should have eliminated any uses of the intrinsic call!");
527
CI->eraseFromParent();