1 //===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the IntrinsicLowering class.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/CodeGen/IntrinsicLowering.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/DataLayout.h"
17 #include "llvm/IR/DerivedTypes.h"
18 #include "llvm/IR/IRBuilder.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/IR/Type.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/raw_ostream.h"
25 /// This function is used when we want to lower an intrinsic call to a call of
26 /// an external function. This handles hard cases such as when there was already
27 /// a prototype for the external function, but that prototype doesn't match the
28 /// arguments we expect to pass in.
29 template <class ArgIt
>
30 static CallInst
*ReplaceCallWith(const char *NewFn
, CallInst
*CI
,
31 ArgIt ArgBegin
, ArgIt ArgEnd
,
33 // If we haven't already looked up this function, check to see if the
34 // program already contains a function with this name.
35 Module
*M
= CI
->getModule();
36 // Get or insert the definition now.
37 std::vector
<Type
*> ParamTys
;
38 for (ArgIt I
= ArgBegin
; I
!= ArgEnd
; ++I
)
39 ParamTys
.push_back((*I
)->getType());
40 FunctionCallee FCache
=
41 M
->getOrInsertFunction(NewFn
, FunctionType::get(RetTy
, ParamTys
, false));
43 IRBuilder
<> Builder(CI
->getParent(), CI
->getIterator());
44 SmallVector
<Value
*, 8> Args(ArgBegin
, ArgEnd
);
45 CallInst
*NewCI
= Builder
.CreateCall(FCache
, Args
);
46 NewCI
->setName(CI
->getName());
48 CI
->replaceAllUsesWith(NewCI
);
52 /// Emit the code to lower bswap of V before the specified instruction IP.
53 static Value
*LowerBSWAP(LLVMContext
&Context
, Value
*V
, Instruction
*IP
) {
54 assert(V
->getType()->isIntOrIntVectorTy() && "Can't bswap a non-integer type!");
56 unsigned BitSize
= V
->getType()->getScalarSizeInBits();
58 IRBuilder
<> Builder(IP
);
61 default: llvm_unreachable("Unhandled type size of value to byteswap!");
63 Value
*Tmp1
= Builder
.CreateShl(V
, ConstantInt::get(V
->getType(), 8),
65 Value
*Tmp2
= Builder
.CreateLShr(V
, ConstantInt::get(V
->getType(), 8),
67 V
= Builder
.CreateOr(Tmp1
, Tmp2
, "bswap.i16");
71 Value
*Tmp4
= Builder
.CreateShl(V
, ConstantInt::get(V
->getType(), 24),
73 Value
*Tmp3
= Builder
.CreateShl(V
, ConstantInt::get(V
->getType(), 8),
75 Value
*Tmp2
= Builder
.CreateLShr(V
, ConstantInt::get(V
->getType(), 8),
77 Value
*Tmp1
= Builder
.CreateLShr(V
,ConstantInt::get(V
->getType(), 24),
79 Tmp3
= Builder
.CreateAnd(Tmp3
,
80 ConstantInt::get(V
->getType(), 0xFF0000),
82 Tmp2
= Builder
.CreateAnd(Tmp2
,
83 ConstantInt::get(V
->getType(), 0xFF00),
85 Tmp4
= Builder
.CreateOr(Tmp4
, Tmp3
, "bswap.or1");
86 Tmp2
= Builder
.CreateOr(Tmp2
, Tmp1
, "bswap.or2");
87 V
= Builder
.CreateOr(Tmp4
, Tmp2
, "bswap.i32");
91 Value
*Tmp8
= Builder
.CreateShl(V
, ConstantInt::get(V
->getType(), 56),
93 Value
*Tmp7
= Builder
.CreateShl(V
, ConstantInt::get(V
->getType(), 40),
95 Value
*Tmp6
= Builder
.CreateShl(V
, ConstantInt::get(V
->getType(), 24),
97 Value
*Tmp5
= Builder
.CreateShl(V
, ConstantInt::get(V
->getType(), 8),
99 Value
* Tmp4
= Builder
.CreateLShr(V
, ConstantInt::get(V
->getType(), 8),
101 Value
* Tmp3
= Builder
.CreateLShr(V
,
102 ConstantInt::get(V
->getType(), 24),
104 Value
* Tmp2
= Builder
.CreateLShr(V
,
105 ConstantInt::get(V
->getType(), 40),
107 Value
* Tmp1
= Builder
.CreateLShr(V
,
108 ConstantInt::get(V
->getType(), 56),
110 Tmp7
= Builder
.CreateAnd(Tmp7
,
111 ConstantInt::get(V
->getType(),
112 0xFF000000000000ULL
),
114 Tmp6
= Builder
.CreateAnd(Tmp6
,
115 ConstantInt::get(V
->getType(),
118 Tmp5
= Builder
.CreateAnd(Tmp5
,
119 ConstantInt::get(V
->getType(),
122 Tmp4
= Builder
.CreateAnd(Tmp4
,
123 ConstantInt::get(V
->getType(),
126 Tmp3
= Builder
.CreateAnd(Tmp3
,
127 ConstantInt::get(V
->getType(),
130 Tmp2
= Builder
.CreateAnd(Tmp2
,
131 ConstantInt::get(V
->getType(),
134 Tmp8
= Builder
.CreateOr(Tmp8
, Tmp7
, "bswap.or1");
135 Tmp6
= Builder
.CreateOr(Tmp6
, Tmp5
, "bswap.or2");
136 Tmp4
= Builder
.CreateOr(Tmp4
, Tmp3
, "bswap.or3");
137 Tmp2
= Builder
.CreateOr(Tmp2
, Tmp1
, "bswap.or4");
138 Tmp8
= Builder
.CreateOr(Tmp8
, Tmp6
, "bswap.or5");
139 Tmp4
= Builder
.CreateOr(Tmp4
, Tmp2
, "bswap.or6");
140 V
= Builder
.CreateOr(Tmp8
, Tmp4
, "bswap.i64");
147 /// Emit the code to lower ctpop of V before the specified instruction IP.
148 static Value
*LowerCTPOP(LLVMContext
&Context
, Value
*V
, Instruction
*IP
) {
149 assert(V
->getType()->isIntegerTy() && "Can't ctpop a non-integer type!");
151 static const uint64_t MaskValues
[6] = {
152 0x5555555555555555ULL
, 0x3333333333333333ULL
,
153 0x0F0F0F0F0F0F0F0FULL
, 0x00FF00FF00FF00FFULL
,
154 0x0000FFFF0000FFFFULL
, 0x00000000FFFFFFFFULL
157 IRBuilder
<> Builder(IP
);
159 unsigned BitSize
= V
->getType()->getPrimitiveSizeInBits();
160 unsigned WordSize
= (BitSize
+ 63) / 64;
161 Value
*Count
= ConstantInt::get(V
->getType(), 0);
163 for (unsigned n
= 0; n
< WordSize
; ++n
) {
164 Value
*PartValue
= V
;
165 for (unsigned i
= 1, ct
= 0; i
< (BitSize
>64 ? 64 : BitSize
);
167 Value
*MaskCst
= ConstantInt::get(V
->getType(), MaskValues
[ct
]);
168 Value
*LHS
= Builder
.CreateAnd(PartValue
, MaskCst
, "cppop.and1");
169 Value
*VShift
= Builder
.CreateLShr(PartValue
,
170 ConstantInt::get(V
->getType(), i
),
172 Value
*RHS
= Builder
.CreateAnd(VShift
, MaskCst
, "cppop.and2");
173 PartValue
= Builder
.CreateAdd(LHS
, RHS
, "ctpop.step");
175 Count
= Builder
.CreateAdd(PartValue
, Count
, "ctpop.part");
177 V
= Builder
.CreateLShr(V
, ConstantInt::get(V
->getType(), 64),
186 /// Emit the code to lower ctlz of V before the specified instruction IP.
187 static Value
*LowerCTLZ(LLVMContext
&Context
, Value
*V
, Instruction
*IP
) {
189 IRBuilder
<> Builder(IP
);
191 unsigned BitSize
= V
->getType()->getPrimitiveSizeInBits();
192 for (unsigned i
= 1; i
< BitSize
; i
<<= 1) {
193 Value
*ShVal
= ConstantInt::get(V
->getType(), i
);
194 ShVal
= Builder
.CreateLShr(V
, ShVal
, "ctlz.sh");
195 V
= Builder
.CreateOr(V
, ShVal
, "ctlz.step");
198 V
= Builder
.CreateNot(V
);
199 return LowerCTPOP(Context
, V
, IP
);
202 static void ReplaceFPIntrinsicWithCall(CallInst
*CI
, const char *Fname
,
204 const char *LDname
) {
205 switch (CI
->getArgOperand(0)->getType()->getTypeID()) {
206 default: llvm_unreachable("Invalid type in intrinsic");
207 case Type::FloatTyID
:
208 ReplaceCallWith(Fname
, CI
, CI
->arg_begin(), CI
->arg_end(),
209 Type::getFloatTy(CI
->getContext()));
211 case Type::DoubleTyID
:
212 ReplaceCallWith(Dname
, CI
, CI
->arg_begin(), CI
->arg_end(),
213 Type::getDoubleTy(CI
->getContext()));
215 case Type::X86_FP80TyID
:
216 case Type::FP128TyID
:
217 case Type::PPC_FP128TyID
:
218 ReplaceCallWith(LDname
, CI
, CI
->arg_begin(), CI
->arg_end(),
219 CI
->getArgOperand(0)->getType());
224 void IntrinsicLowering::LowerIntrinsicCall(CallInst
*CI
) {
225 IRBuilder
<> Builder(CI
);
226 LLVMContext
&Context
= CI
->getContext();
228 const Function
*Callee
= CI
->getCalledFunction();
229 assert(Callee
&& "Cannot lower an indirect call!");
231 switch (Callee
->getIntrinsicID()) {
232 case Intrinsic::not_intrinsic
:
233 report_fatal_error("Cannot lower a call to a non-intrinsic function '"+
234 Callee
->getName() + "'!");
236 report_fatal_error("Code generator does not support intrinsic function '"+
237 Callee
->getName()+"'!");
239 case Intrinsic::expect
:
240 case Intrinsic::expect_with_probability
: {
241 // Just replace __builtin_expect(exp, c) and
242 // __builtin_expect_with_probability(exp, c, p) with EXP.
243 Value
*V
= CI
->getArgOperand(0);
244 CI
->replaceAllUsesWith(V
);
248 case Intrinsic::allow_runtime_check
:
249 case Intrinsic::allow_ubsan_check
:
250 CI
->replaceAllUsesWith(ConstantInt::getTrue(CI
->getType()));
253 case Intrinsic::ctpop
:
254 CI
->replaceAllUsesWith(LowerCTPOP(Context
, CI
->getArgOperand(0), CI
));
257 case Intrinsic::bswap
:
258 CI
->replaceAllUsesWith(LowerBSWAP(Context
, CI
->getArgOperand(0), CI
));
261 case Intrinsic::ctlz
:
262 CI
->replaceAllUsesWith(LowerCTLZ(Context
, CI
->getArgOperand(0), CI
));
265 case Intrinsic::cttz
: {
266 // cttz(x) -> ctpop(~X & (X-1))
267 Value
*Src
= CI
->getArgOperand(0);
268 Value
*NotSrc
= Builder
.CreateNot(Src
);
269 NotSrc
->setName(Src
->getName() + ".not");
270 Value
*SrcM1
= ConstantInt::get(Src
->getType(), 1);
271 SrcM1
= Builder
.CreateSub(Src
, SrcM1
);
272 Src
= LowerCTPOP(Context
, Builder
.CreateAnd(NotSrc
, SrcM1
), CI
);
273 CI
->replaceAllUsesWith(Src
);
277 case Intrinsic::stacksave
:
278 case Intrinsic::stackrestore
: {
280 errs() << "WARNING: this target does not support the llvm.stack"
281 << (Callee
->getIntrinsicID() == Intrinsic::stacksave
?
282 "save" : "restore") << " intrinsic.\n";
284 if (Callee
->getIntrinsicID() == Intrinsic::stacksave
)
285 CI
->replaceAllUsesWith(Constant::getNullValue(CI
->getType()));
289 case Intrinsic::get_dynamic_area_offset
:
290 errs() << "WARNING: this target does not support the custom llvm.get."
291 "dynamic.area.offset. It is being lowered to a constant 0\n";
292 // Just lower it to a constant 0 because for most targets
293 // @llvm.get.dynamic.area.offset is lowered to zero.
294 CI
->replaceAllUsesWith(ConstantInt::get(CI
->getType(), 0));
296 case Intrinsic::returnaddress
:
297 case Intrinsic::frameaddress
:
298 errs() << "WARNING: this target does not support the llvm."
299 << (Callee
->getIntrinsicID() == Intrinsic::returnaddress
?
300 "return" : "frame") << "address intrinsic.\n";
301 CI
->replaceAllUsesWith(
302 ConstantPointerNull::get(cast
<PointerType
>(CI
->getType())));
304 case Intrinsic::addressofreturnaddress
:
305 errs() << "WARNING: this target does not support the "
306 "llvm.addressofreturnaddress intrinsic.\n";
307 CI
->replaceAllUsesWith(
308 ConstantPointerNull::get(cast
<PointerType
>(CI
->getType())));
311 case Intrinsic::prefetch
:
312 break; // Simply strip out prefetches on unsupported architectures
314 case Intrinsic::pcmarker
:
315 break; // Simply strip out pcmarker on unsupported architectures
316 case Intrinsic::readcyclecounter
: {
317 errs() << "WARNING: this target does not support the llvm.readcyclecoun"
318 << "ter intrinsic. It is being lowered to a constant 0\n";
319 CI
->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context
), 0));
322 case Intrinsic::readsteadycounter
: {
323 errs() << "WARNING: this target does not support the llvm.readsteadycounter"
324 << " intrinsic. It is being lowered to a constant 0\n";
325 CI
->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context
), 0));
329 case Intrinsic::dbg_declare
:
330 case Intrinsic::dbg_label
:
331 break; // Simply strip out debugging intrinsics
333 case Intrinsic::eh_typeid_for
:
334 // Return something different to eh_selector.
335 CI
->replaceAllUsesWith(ConstantInt::get(CI
->getType(), 1));
338 case Intrinsic::annotation
:
339 case Intrinsic::ptr_annotation
:
340 // Just drop the annotation, but forward the value
341 CI
->replaceAllUsesWith(CI
->getOperand(0));
344 case Intrinsic::assume
:
345 case Intrinsic::experimental_noalias_scope_decl
:
346 case Intrinsic::var_annotation
:
347 break; // Strip out these intrinsics
349 case Intrinsic::memcpy
: {
350 Type
*IntPtr
= DL
.getIntPtrType(Context
);
351 Value
*Size
= Builder
.CreateIntCast(CI
->getArgOperand(2), IntPtr
,
352 /* isSigned */ false);
354 Ops
[0] = CI
->getArgOperand(0);
355 Ops
[1] = CI
->getArgOperand(1);
357 ReplaceCallWith("memcpy", CI
, Ops
, Ops
+3, CI
->getArgOperand(0)->getType());
360 case Intrinsic::memmove
: {
361 Type
*IntPtr
= DL
.getIntPtrType(Context
);
362 Value
*Size
= Builder
.CreateIntCast(CI
->getArgOperand(2), IntPtr
,
363 /* isSigned */ false);
365 Ops
[0] = CI
->getArgOperand(0);
366 Ops
[1] = CI
->getArgOperand(1);
368 ReplaceCallWith("memmove", CI
, Ops
, Ops
+3, CI
->getArgOperand(0)->getType());
371 case Intrinsic::memset
: {
372 Value
*Op0
= CI
->getArgOperand(0);
373 Type
*IntPtr
= DL
.getIntPtrType(Op0
->getType());
374 Value
*Size
= Builder
.CreateIntCast(CI
->getArgOperand(2), IntPtr
,
375 /* isSigned */ false);
378 // Extend the amount to i32.
379 Ops
[1] = Builder
.CreateIntCast(CI
->getArgOperand(1),
380 Type::getInt32Ty(Context
),
381 /* isSigned */ false);
383 ReplaceCallWith("memset", CI
, Ops
, Ops
+3, CI
->getArgOperand(0)->getType());
386 case Intrinsic::sqrt
: {
387 ReplaceFPIntrinsicWithCall(CI
, "sqrtf", "sqrt", "sqrtl");
390 case Intrinsic::log
: {
391 ReplaceFPIntrinsicWithCall(CI
, "logf", "log", "logl");
394 case Intrinsic::log2
: {
395 ReplaceFPIntrinsicWithCall(CI
, "log2f", "log2", "log2l");
398 case Intrinsic::log10
: {
399 ReplaceFPIntrinsicWithCall(CI
, "log10f", "log10", "log10l");
402 case Intrinsic::exp
: {
403 ReplaceFPIntrinsicWithCall(CI
, "expf", "exp", "expl");
406 case Intrinsic::exp2
: {
407 ReplaceFPIntrinsicWithCall(CI
, "exp2f", "exp2", "exp2l");
410 case Intrinsic::pow
: {
411 ReplaceFPIntrinsicWithCall(CI
, "powf", "pow", "powl");
414 case Intrinsic::sin
: {
415 ReplaceFPIntrinsicWithCall(CI
, "sinf", "sin", "sinl");
418 case Intrinsic::cos
: {
419 ReplaceFPIntrinsicWithCall(CI
, "cosf", "cos", "cosl");
422 case Intrinsic::floor
: {
423 ReplaceFPIntrinsicWithCall(CI
, "floorf", "floor", "floorl");
426 case Intrinsic::ceil
: {
427 ReplaceFPIntrinsicWithCall(CI
, "ceilf", "ceil", "ceill");
430 case Intrinsic::trunc
: {
431 ReplaceFPIntrinsicWithCall(CI
, "truncf", "trunc", "truncl");
434 case Intrinsic::round
: {
435 ReplaceFPIntrinsicWithCall(CI
, "roundf", "round", "roundl");
438 case Intrinsic::roundeven
: {
439 ReplaceFPIntrinsicWithCall(CI
, "roundevenf", "roundeven", "roundevenl");
442 case Intrinsic::copysign
: {
443 ReplaceFPIntrinsicWithCall(CI
, "copysignf", "copysign", "copysignl");
446 case Intrinsic::get_rounding
:
447 // Lower to "round to the nearest"
448 if (!CI
->getType()->isVoidTy())
449 CI
->replaceAllUsesWith(ConstantInt::get(CI
->getType(), 1));
451 case Intrinsic::invariant_start
:
452 case Intrinsic::lifetime_start
:
453 // Discard region information.
454 CI
->replaceAllUsesWith(PoisonValue::get(CI
->getType()));
456 case Intrinsic::invariant_end
:
457 case Intrinsic::lifetime_end
:
458 // Discard region information.
462 assert(CI
->use_empty() &&
463 "Lowering should have eliminated any uses of the intrinsic call!");
464 CI
->eraseFromParent();
467 bool IntrinsicLowering::LowerToByteSwap(CallInst
*CI
) {
468 // Verify this is a simple bswap.
469 if (CI
->arg_size() != 1 || CI
->getType() != CI
->getArgOperand(0)->getType() ||
470 !CI
->getType()->isIntegerTy())
473 IntegerType
*Ty
= dyn_cast
<IntegerType
>(CI
->getType());
477 // Okay, we can do this xform, do so now.
478 Module
*M
= CI
->getModule();
479 Function
*Int
= Intrinsic::getOrInsertDeclaration(M
, Intrinsic::bswap
, Ty
);
481 Value
*Op
= CI
->getArgOperand(0);
482 Op
= CallInst::Create(Int
, Op
, CI
->getName(), CI
->getIterator());
484 CI
->replaceAllUsesWith(Op
);
485 CI
->eraseFromParent();