1//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
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 contains code to emit Builtin calls as LLVM code.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGBuiltin.h"
14#include "ABIInfo.h"
15#include "CGCUDARuntime.h"
16#include "CGCXXABI.h"
17#include "CGDebugInfo.h"
18#include "CGObjCRuntime.h"
19#include "CGOpenCLRuntime.h"
20#include "CGRecordLayout.h"
21#include "CGValue.h"
22#include "CodeGenFunction.h"
23#include "CodeGenModule.h"
24#include "ConstantEmitter.h"
25#include "PatternInit.h"
26#include "TargetInfo.h"
27#include "clang/AST/OSLog.h"
28#include "clang/AST/StmtVisitor.h"
29#include "clang/Basic/DiagnosticFrontend.h"
30#include "clang/Basic/TargetInfo.h"
31#include "llvm/IR/InlineAsm.h"
32#include "llvm/IR/Instruction.h"
33#include "llvm/IR/Intrinsics.h"
34#include "llvm/IR/IntrinsicsX86.h"
35#include "llvm/IR/MatrixBuilder.h"
36#include "llvm/Support/ConvertUTF.h"
37#include "llvm/Support/ScopedPrinter.h"
38#include <optional>
39#include <utility>
40
41using namespace clang;
42using namespace CodeGen;
43using namespace llvm;
44
45/// Some builtins do not have library implementation on some targets and
46/// are instead emitted as LLVM IRs by some target builtin emitters.
47/// FIXME: Remove this when library support is added
48static bool shouldEmitBuiltinAsIR(unsigned BuiltinID,
49 const Builtin::Context &BI,
50 const CodeGenFunction &CGF) {
51 if (!CGF.CGM.getLangOpts().MathErrno &&
52 CGF.CurFPFeatures.getExceptionMode() ==
53 LangOptions::FPExceptionModeKind::FPE_Ignore &&
54 !CGF.CGM.getTargetCodeGenInfo().supportsLibCall()) {
55 switch (BuiltinID) {
56 default:
57 return false;
58 case Builtin::BIlogbf:
59 case Builtin::BI__builtin_logbf:
60 case Builtin::BIlogb:
61 case Builtin::BI__builtin_logb:
62 case Builtin::BIscalbnf:
63 case Builtin::BI__builtin_scalbnf:
64 case Builtin::BIscalbn:
65 case Builtin::BI__builtin_scalbn:
66 return true;
67 }
68 }
69 return false;
70}
71
72static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
73 unsigned BuiltinID, const CallExpr *E,
74 ReturnValueSlot ReturnValue,
75 llvm::Triple::ArchType Arch) {
76 // When compiling in HipStdPar mode we have to be conservative in rejecting
77 // target specific features in the FE, and defer the possible error to the
78 // AcceleratorCodeSelection pass, wherein iff an unsupported target builtin is
79 // referenced by an accelerator executable function, we emit an error.
80 // Returning nullptr here leads to the builtin being handled in
81 // EmitStdParUnsupportedBuiltin.
82 if (CGF->getLangOpts().HIPStdPar && CGF->getLangOpts().CUDAIsDevice &&
83 Arch != CGF->getTarget().getTriple().getArch())
84 return nullptr;
85
86 switch (Arch) {
87 case llvm::Triple::arm:
88 case llvm::Triple::armeb:
89 case llvm::Triple::thumb:
90 case llvm::Triple::thumbeb:
91 return CGF->EmitARMBuiltinExpr(BuiltinID, E, ReturnValue, Arch);
92 case llvm::Triple::aarch64:
93 case llvm::Triple::aarch64_32:
94 case llvm::Triple::aarch64_be:
95 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E, Arch);
96 case llvm::Triple::bpfeb:
97 case llvm::Triple::bpfel:
98 return CGF->EmitBPFBuiltinExpr(BuiltinID, E);
99 case llvm::Triple::dxil:
100 return CGF->EmitDirectXBuiltinExpr(BuiltinID, E);
101 case llvm::Triple::x86:
102 case llvm::Triple::x86_64:
103 return CGF->EmitX86BuiltinExpr(BuiltinID, E);
104 case llvm::Triple::ppc:
105 case llvm::Triple::ppcle:
106 case llvm::Triple::ppc64:
107 case llvm::Triple::ppc64le:
108 return CGF->EmitPPCBuiltinExpr(BuiltinID, E);
109 case llvm::Triple::r600:
110 case llvm::Triple::amdgcn:
111 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
112 case llvm::Triple::systemz:
113 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E);
114 case llvm::Triple::nvptx:
115 case llvm::Triple::nvptx64:
116 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E);
117 case llvm::Triple::wasm32:
118 case llvm::Triple::wasm64:
119 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E);
120 case llvm::Triple::hexagon:
121 return CGF->EmitHexagonBuiltinExpr(BuiltinID, E);
122 case llvm::Triple::riscv32:
123 case llvm::Triple::riscv64:
124 case llvm::Triple::riscv32be:
125 case llvm::Triple::riscv64be:
126 return CGF->EmitRISCVBuiltinExpr(BuiltinID, E, ReturnValue);
127 case llvm::Triple::spirv32:
128 case llvm::Triple::spirv64:
129 if (CGF->getTarget().getTriple().getOS() == llvm::Triple::OSType::AMDHSA)
130 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
131 [[fallthrough]];
132 case llvm::Triple::spirv:
133 return CGF->EmitSPIRVBuiltinExpr(BuiltinID, E);
134 default:
135 return nullptr;
136 }
137}
138
139Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
140 const CallExpr *E,
141 ReturnValueSlot ReturnValue) {
142 if (getContext().BuiltinInfo.isAuxBuiltinID(ID: BuiltinID)) {
143 assert(getContext().getAuxTargetInfo() && "Missing aux target info");
144 return EmitTargetArchBuiltinExpr(
145 CGF: this, BuiltinID: getContext().BuiltinInfo.getAuxBuiltinID(ID: BuiltinID), E,
146 ReturnValue, Arch: getContext().getAuxTargetInfo()->getTriple().getArch());
147 }
148
149 return EmitTargetArchBuiltinExpr(CGF: this, BuiltinID, E, ReturnValue,
150 Arch: getTarget().getTriple().getArch());
151}
152
153static void initializeAlloca(CodeGenFunction &CGF, AllocaInst *AI, Value *Size,
154 Align AlignmentInBytes) {
155 ConstantInt *Byte;
156 switch (CGF.getLangOpts().getTrivialAutoVarInit()) {
157 case LangOptions::TrivialAutoVarInitKind::Uninitialized:
158 // Nothing to initialize.
159 return;
160 case LangOptions::TrivialAutoVarInitKind::Zero:
161 Byte = CGF.Builder.getInt8(C: 0x00);
162 break;
163 case LangOptions::TrivialAutoVarInitKind::Pattern: {
164 llvm::Type *Int8 = llvm::IntegerType::getInt8Ty(C&: CGF.CGM.getLLVMContext());
165 Byte = llvm::dyn_cast<llvm::ConstantInt>(
166 Val: initializationPatternFor(CGF.CGM, Int8));
167 break;
168 }
169 }
170 if (CGF.CGM.stopAutoInit())
171 return;
172 auto *I = CGF.Builder.CreateMemSet(Ptr: AI, Val: Byte, Size, Align: AlignmentInBytes);
173 I->addAnnotationMetadata(Annotation: "auto-init");
174}
175
176/// getBuiltinLibFunction - Given a builtin id for a function like
177/// "__builtin_fabsf", return a Function* for "fabsf".
178llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
179 unsigned BuiltinID) {
180 assert(Context.BuiltinInfo.isLibFunction(BuiltinID));
181
182 // Get the name, skip over the __builtin_ prefix (if necessary). We may have
183 // to build this up so provide a small stack buffer to handle the vast
184 // majority of names.
185 llvm::SmallString<64> Name;
186 GlobalDecl D(FD);
187
188 // TODO: This list should be expanded or refactored after all GCC-compatible
189 // std libcall builtins are implemented.
190 static SmallDenseMap<unsigned, StringRef, 64> F128Builtins{
191 {Builtin::BI__builtin___fprintf_chk, "__fprintf_chkieee128"},
192 {Builtin::BI__builtin___printf_chk, "__printf_chkieee128"},
193 {Builtin::BI__builtin___snprintf_chk, "__snprintf_chkieee128"},
194 {Builtin::BI__builtin___sprintf_chk, "__sprintf_chkieee128"},
195 {Builtin::BI__builtin___vfprintf_chk, "__vfprintf_chkieee128"},
196 {Builtin::BI__builtin___vprintf_chk, "__vprintf_chkieee128"},
197 {Builtin::BI__builtin___vsnprintf_chk, "__vsnprintf_chkieee128"},
198 {Builtin::BI__builtin___vsprintf_chk, "__vsprintf_chkieee128"},
199 {Builtin::BI__builtin_fprintf, "__fprintfieee128"},
200 {Builtin::BI__builtin_printf, "__printfieee128"},
201 {Builtin::BI__builtin_snprintf, "__snprintfieee128"},
202 {Builtin::BI__builtin_sprintf, "__sprintfieee128"},
203 {Builtin::BI__builtin_vfprintf, "__vfprintfieee128"},
204 {Builtin::BI__builtin_vprintf, "__vprintfieee128"},
205 {Builtin::BI__builtin_vsnprintf, "__vsnprintfieee128"},
206 {Builtin::BI__builtin_vsprintf, "__vsprintfieee128"},
207 {Builtin::BI__builtin_fscanf, "__fscanfieee128"},
208 {Builtin::BI__builtin_scanf, "__scanfieee128"},
209 {Builtin::BI__builtin_sscanf, "__sscanfieee128"},
210 {Builtin::BI__builtin_vfscanf, "__vfscanfieee128"},
211 {Builtin::BI__builtin_vscanf, "__vscanfieee128"},
212 {Builtin::BI__builtin_vsscanf, "__vsscanfieee128"},
213 {Builtin::BI__builtin_nexttowardf128, "__nexttowardieee128"},
214 };
215
216 // The AIX library functions frexpl, ldexpl, and modfl are for 128-bit
217 // IBM 'long double' (i.e. __ibm128). Map to the 'double' versions
218 // if it is 64-bit 'long double' mode.
219 static SmallDenseMap<unsigned, StringRef, 4> AIXLongDouble64Builtins{
220 {Builtin::BI__builtin_frexpl, "frexp"},
221 {Builtin::BI__builtin_ldexpl, "ldexp"},
222 {Builtin::BI__builtin_modfl, "modf"},
223 };
224
225 // If the builtin has been declared explicitly with an assembler label,
226 // use the mangled name. This differs from the plain label on platforms
227 // that prefix labels.
228 if (FD->hasAttr<AsmLabelAttr>())
229 Name = getMangledName(GD: D);
230 else {
231 // TODO: This mutation should also be applied to other targets other than
232 // PPC, after backend supports IEEE 128-bit style libcalls.
233 if (getTriple().isPPC64() &&
234 &getTarget().getLongDoubleFormat() == &llvm::APFloat::IEEEquad() &&
235 F128Builtins.contains(Val: BuiltinID))
236 Name = F128Builtins[BuiltinID];
237 else if (getTriple().isOSAIX() &&
238 &getTarget().getLongDoubleFormat() ==
239 &llvm::APFloat::IEEEdouble() &&
240 AIXLongDouble64Builtins.contains(Val: BuiltinID))
241 Name = AIXLongDouble64Builtins[BuiltinID];
242 else
243 Name = Context.BuiltinInfo.getName(ID: BuiltinID).substr(pos: 10);
244 }
245
246 llvm::FunctionType *Ty =
247 cast<llvm::FunctionType>(Val: getTypes().ConvertType(T: FD->getType()));
248
249 return GetOrCreateLLVMFunction(MangledName: Name, Ty, D, /*ForVTable=*/false);
250}
251
252/// Emit the conversions required to turn the given value into an
253/// integer of the given size.
254Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V,
255 QualType T, llvm::IntegerType *IntType) {
256 V = CGF.EmitToMemory(Value: V, Ty: T);
257
258 if (V->getType()->isPointerTy())
259 return CGF.Builder.CreatePtrToInt(V, DestTy: IntType);
260
261 assert(V->getType() == IntType);
262 return V;
263}
264
265Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V,
266 QualType T, llvm::Type *ResultType) {
267 V = CGF.EmitFromMemory(Value: V, Ty: T);
268
269 if (ResultType->isPointerTy())
270 return CGF.Builder.CreateIntToPtr(V, DestTy: ResultType);
271
272 assert(V->getType() == ResultType);
273 return V;
274}
275
276Address CheckAtomicAlignment(CodeGenFunction &CGF, const CallExpr *E) {
277 ASTContext &Ctx = CGF.getContext();
278 Address Ptr = CGF.EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
279 const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
280 unsigned Bytes = Ptr.getElementType()->isPointerTy()
281 ? Ctx.getTypeSizeInChars(T: Ctx.VoidPtrTy).getQuantity()
282 : DL.getTypeStoreSize(Ty: Ptr.getElementType());
283 unsigned Align = Ptr.getAlignment().getQuantity();
284 if (Align % Bytes != 0) {
285 DiagnosticsEngine &Diags = CGF.CGM.getDiags();
286 Diags.Report(Loc: E->getBeginLoc(), DiagID: diag::warn_sync_op_misaligned);
287 // Force address to be at least naturally-aligned.
288 return Ptr.withAlignment(NewAlignment: CharUnits::fromQuantity(Quantity: Bytes));
289 }
290 return Ptr;
291}
292
293/// Utility to insert an atomic instruction based on Intrinsic::ID
294/// and the expression node.
295Value *MakeBinaryAtomicValue(
296 CodeGenFunction &CGF, llvm::AtomicRMWInst::BinOp Kind, const CallExpr *E,
297 AtomicOrdering Ordering) {
298
299 QualType T = E->getType();
300 assert(E->getArg(0)->getType()->isPointerType());
301 assert(CGF.getContext().hasSameUnqualifiedType(T,
302 E->getArg(0)->getType()->getPointeeType()));
303 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
304
305 Address DestAddr = CheckAtomicAlignment(CGF, E);
306
307 llvm::IntegerType *IntType = llvm::IntegerType::get(
308 C&: CGF.getLLVMContext(), NumBits: CGF.getContext().getTypeSize(T));
309
310 llvm::Value *Val = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
311 llvm::Type *ValueType = Val->getType();
312 Val = EmitToInt(CGF, V: Val, T, IntType);
313
314 llvm::Value *Result =
315 CGF.Builder.CreateAtomicRMW(Op: Kind, Addr: DestAddr, Val, Ordering);
316 return EmitFromInt(CGF, V: Result, T, ResultType: ValueType);
317}
318
319static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) {
320 Value *Val = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
321 Address Addr = CGF.EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
322
323 Val = CGF.EmitToMemory(Value: Val, Ty: E->getArg(Arg: 0)->getType());
324 LValue LV = CGF.MakeAddrLValue(Addr, T: E->getArg(Arg: 0)->getType());
325 LV.setNontemporal(true);
326 CGF.EmitStoreOfScalar(value: Val, lvalue: LV, isInit: false);
327 return nullptr;
328}
329
330static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) {
331 Address Addr = CGF.EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
332
333 LValue LV = CGF.MakeAddrLValue(Addr, T: E->getType());
334 LV.setNontemporal(true);
335 return CGF.EmitLoadOfScalar(lvalue: LV, Loc: E->getExprLoc());
336}
337
338static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
339 llvm::AtomicRMWInst::BinOp Kind,
340 const CallExpr *E) {
341 return RValue::get(V: MakeBinaryAtomicValue(CGF, Kind, E));
342}
343
344/// Utility to insert an atomic instruction based Intrinsic::ID and
345/// the expression node, where the return value is the result of the
346/// operation.
347static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
348 llvm::AtomicRMWInst::BinOp Kind,
349 const CallExpr *E,
350 Instruction::BinaryOps Op,
351 bool Invert = false) {
352 QualType T = E->getType();
353 assert(E->getArg(0)->getType()->isPointerType());
354 assert(CGF.getContext().hasSameUnqualifiedType(T,
355 E->getArg(0)->getType()->getPointeeType()));
356 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
357
358 Address DestAddr = CheckAtomicAlignment(CGF, E);
359
360 llvm::IntegerType *IntType = llvm::IntegerType::get(
361 C&: CGF.getLLVMContext(), NumBits: CGF.getContext().getTypeSize(T));
362
363 llvm::Value *Val = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
364 llvm::Type *ValueType = Val->getType();
365 Val = EmitToInt(CGF, V: Val, T, IntType);
366
367 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
368 Op: Kind, Addr: DestAddr, Val, Ordering: llvm::AtomicOrdering::SequentiallyConsistent);
369 Result = CGF.Builder.CreateBinOp(Opc: Op, LHS: Result, RHS: Val);
370 if (Invert)
371 Result =
372 CGF.Builder.CreateBinOp(Opc: llvm::Instruction::Xor, LHS: Result,
373 RHS: llvm::ConstantInt::getAllOnesValue(Ty: IntType));
374 Result = EmitFromInt(CGF, V: Result, T, ResultType: ValueType);
375 return RValue::get(V: Result);
376}
377
378/// Utility to insert an atomic cmpxchg instruction.
379///
380/// @param CGF The current codegen function.
381/// @param E Builtin call expression to convert to cmpxchg.
382/// arg0 - address to operate on
383/// arg1 - value to compare with
384/// arg2 - new value
385/// @param ReturnBool Specifies whether to return success flag of
386/// cmpxchg result or the old value.
387///
388/// @returns result of cmpxchg, according to ReturnBool
389///
390/// Note: In order to lower Microsoft's _InterlockedCompareExchange* intrinsics
391/// invoke the function EmitAtomicCmpXchgForMSIntrin.
392Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E,
393 bool ReturnBool) {
394 QualType T = ReturnBool ? E->getArg(Arg: 1)->getType() : E->getType();
395 Address DestAddr = CheckAtomicAlignment(CGF, E);
396
397 llvm::IntegerType *IntType = llvm::IntegerType::get(
398 C&: CGF.getLLVMContext(), NumBits: CGF.getContext().getTypeSize(T));
399
400 Value *Cmp = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
401 llvm::Type *ValueType = Cmp->getType();
402 Cmp = EmitToInt(CGF, V: Cmp, T, IntType);
403 Value *New = EmitToInt(CGF, V: CGF.EmitScalarExpr(E: E->getArg(Arg: 2)), T, IntType);
404
405 Value *Pair = CGF.Builder.CreateAtomicCmpXchg(
406 Addr: DestAddr, Cmp, New, SuccessOrdering: llvm::AtomicOrdering::SequentiallyConsistent,
407 FailureOrdering: llvm::AtomicOrdering::SequentiallyConsistent);
408 if (ReturnBool)
409 // Extract boolean success flag and zext it to int.
410 return CGF.Builder.CreateZExt(V: CGF.Builder.CreateExtractValue(Agg: Pair, Idxs: 1),
411 DestTy: CGF.ConvertType(T: E->getType()));
412 else
413 // Extract old value and emit it using the same type as compare value.
414 return EmitFromInt(CGF, V: CGF.Builder.CreateExtractValue(Agg: Pair, Idxs: 0), T,
415 ResultType: ValueType);
416}
417
418/// This function should be invoked to emit atomic cmpxchg for Microsoft's
419/// _InterlockedCompareExchange* intrinsics which have the following signature:
420/// T _InterlockedCompareExchange(T volatile *Destination,
421/// T Exchange,
422/// T Comparand);
423///
424/// Whereas the llvm 'cmpxchg' instruction has the following syntax:
425/// cmpxchg *Destination, Comparand, Exchange.
426/// So we need to swap Comparand and Exchange when invoking
427/// CreateAtomicCmpXchg. That is the reason we could not use the above utility
428/// function MakeAtomicCmpXchgValue since it expects the arguments to be
429/// already swapped.
430
431static
432Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
433 AtomicOrdering SuccessOrdering = AtomicOrdering::SequentiallyConsistent) {
434 assert(E->getArg(0)->getType()->isPointerType());
435 assert(CGF.getContext().hasSameUnqualifiedType(
436 E->getType(), E->getArg(0)->getType()->getPointeeType()));
437 assert(CGF.getContext().hasSameUnqualifiedType(E->getType(),
438 E->getArg(1)->getType()));
439 assert(CGF.getContext().hasSameUnqualifiedType(E->getType(),
440 E->getArg(2)->getType()));
441
442 Address DestAddr = CheckAtomicAlignment(CGF, E);
443
444 auto *Exchange = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
445 auto *RTy = Exchange->getType();
446
447 auto *Comparand = CGF.EmitScalarExpr(E: E->getArg(Arg: 2));
448
449 if (RTy->isPointerTy()) {
450 Exchange = CGF.Builder.CreatePtrToInt(V: Exchange, DestTy: CGF.IntPtrTy);
451 Comparand = CGF.Builder.CreatePtrToInt(V: Comparand, DestTy: CGF.IntPtrTy);
452 }
453
454 // For Release ordering, the failure ordering should be Monotonic.
455 auto FailureOrdering = SuccessOrdering == AtomicOrdering::Release ?
456 AtomicOrdering::Monotonic :
457 SuccessOrdering;
458
459 // The atomic instruction is marked volatile for consistency with MSVC. This
460 // blocks the few atomics optimizations that LLVM has. If we want to optimize
461 // _Interlocked* operations in the future, we will have to remove the volatile
462 // marker.
463 auto *CmpXchg = CGF.Builder.CreateAtomicCmpXchg(
464 Addr: DestAddr, Cmp: Comparand, New: Exchange, SuccessOrdering, FailureOrdering);
465 CmpXchg->setVolatile(true);
466
467 auto *Result = CGF.Builder.CreateExtractValue(Agg: CmpXchg, Idxs: 0);
468 if (RTy->isPointerTy()) {
469 Result = CGF.Builder.CreateIntToPtr(V: Result, DestTy: RTy);
470 }
471
472 return Result;
473}
474
475// 64-bit Microsoft platforms support 128 bit cmpxchg operations. They are
476// prototyped like this:
477//
478// unsigned char _InterlockedCompareExchange128...(
479// __int64 volatile * _Destination,
480// __int64 _ExchangeHigh,
481// __int64 _ExchangeLow,
482// __int64 * _ComparandResult);
483//
484// Note that Destination is assumed to be at least 16-byte aligned, despite
485// being typed int64.
486
487static Value *EmitAtomicCmpXchg128ForMSIntrin(CodeGenFunction &CGF,
488 const CallExpr *E,
489 AtomicOrdering SuccessOrdering) {
490 assert(E->getNumArgs() == 4);
491 llvm::Value *DestPtr = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
492 llvm::Value *ExchangeHigh = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
493 llvm::Value *ExchangeLow = CGF.EmitScalarExpr(E: E->getArg(Arg: 2));
494 Address ComparandAddr = CGF.EmitPointerWithAlignment(Addr: E->getArg(Arg: 3));
495
496 assert(DestPtr->getType()->isPointerTy());
497 assert(!ExchangeHigh->getType()->isPointerTy());
498 assert(!ExchangeLow->getType()->isPointerTy());
499
500 // For Release ordering, the failure ordering should be Monotonic.
501 auto FailureOrdering = SuccessOrdering == AtomicOrdering::Release
502 ? AtomicOrdering::Monotonic
503 : SuccessOrdering;
504
505 // Convert to i128 pointers and values. Alignment is also overridden for
506 // destination pointer.
507 llvm::Type *Int128Ty = llvm::IntegerType::get(C&: CGF.getLLVMContext(), NumBits: 128);
508 Address DestAddr(DestPtr, Int128Ty,
509 CGF.getContext().toCharUnitsFromBits(BitSize: 128));
510 ComparandAddr = ComparandAddr.withElementType(ElemTy: Int128Ty);
511
512 // (((i128)hi) << 64) | ((i128)lo)
513 ExchangeHigh = CGF.Builder.CreateZExt(V: ExchangeHigh, DestTy: Int128Ty);
514 ExchangeLow = CGF.Builder.CreateZExt(V: ExchangeLow, DestTy: Int128Ty);
515 ExchangeHigh =
516 CGF.Builder.CreateShl(LHS: ExchangeHigh, RHS: llvm::ConstantInt::get(Ty: Int128Ty, V: 64));
517 llvm::Value *Exchange = CGF.Builder.CreateOr(LHS: ExchangeHigh, RHS: ExchangeLow);
518
519 // Load the comparand for the instruction.
520 llvm::Value *Comparand = CGF.Builder.CreateLoad(Addr: ComparandAddr);
521
522 auto *CXI = CGF.Builder.CreateAtomicCmpXchg(Addr: DestAddr, Cmp: Comparand, New: Exchange,
523 SuccessOrdering, FailureOrdering);
524
525 // The atomic instruction is marked volatile for consistency with MSVC. This
526 // blocks the few atomics optimizations that LLVM has. If we want to optimize
527 // _Interlocked* operations in the future, we will have to remove the volatile
528 // marker.
529 CXI->setVolatile(true);
530
531 // Store the result as an outparameter.
532 CGF.Builder.CreateStore(Val: CGF.Builder.CreateExtractValue(Agg: CXI, Idxs: 0),
533 Addr: ComparandAddr);
534
535 // Get the success boolean and zero extend it to i8.
536 Value *Success = CGF.Builder.CreateExtractValue(Agg: CXI, Idxs: 1);
537 return CGF.Builder.CreateZExt(V: Success, DestTy: CGF.Int8Ty);
538}
539
540static Value *EmitAtomicIncrementValue(CodeGenFunction &CGF, const CallExpr *E,
541 AtomicOrdering Ordering = AtomicOrdering::SequentiallyConsistent) {
542 assert(E->getArg(0)->getType()->isPointerType());
543
544 auto *IntTy = CGF.ConvertType(T: E->getType());
545 Address DestAddr = CheckAtomicAlignment(CGF, E);
546 auto *Result = CGF.Builder.CreateAtomicRMW(
547 Op: AtomicRMWInst::Add, Addr: DestAddr, Val: ConstantInt::get(Ty: IntTy, V: 1), Ordering);
548 return CGF.Builder.CreateAdd(LHS: Result, RHS: ConstantInt::get(Ty: IntTy, V: 1));
549}
550
551static Value *EmitAtomicDecrementValue(
552 CodeGenFunction &CGF, const CallExpr *E,
553 AtomicOrdering Ordering = AtomicOrdering::SequentiallyConsistent) {
554 assert(E->getArg(0)->getType()->isPointerType());
555
556 auto *IntTy = CGF.ConvertType(T: E->getType());
557 Address DestAddr = CheckAtomicAlignment(CGF, E);
558 auto *Result = CGF.Builder.CreateAtomicRMW(
559 Op: AtomicRMWInst::Sub, Addr: DestAddr, Val: ConstantInt::get(Ty: IntTy, V: 1), Ordering);
560 return CGF.Builder.CreateSub(LHS: Result, RHS: ConstantInt::get(Ty: IntTy, V: 1));
561}
562
563// Build a plain volatile load.
564static Value *EmitISOVolatileLoad(CodeGenFunction &CGF, const CallExpr *E) {
565 Value *Ptr = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
566 QualType ElTy = E->getArg(Arg: 0)->getType()->getPointeeType();
567 CharUnits LoadSize = CGF.getContext().getTypeSizeInChars(T: ElTy);
568 llvm::Type *ITy =
569 llvm::IntegerType::get(C&: CGF.getLLVMContext(), NumBits: LoadSize.getQuantity() * 8);
570 llvm::LoadInst *Load = CGF.Builder.CreateAlignedLoad(Ty: ITy, Addr: Ptr, Align: LoadSize);
571 Load->setAtomic(Ordering: llvm::AtomicOrdering::Monotonic);
572 Load->setVolatile(true);
573 return Load;
574}
575
576// Build a plain volatile store.
577static Value *EmitISOVolatileStore(CodeGenFunction &CGF, const CallExpr *E) {
578 Value *Ptr = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
579 Value *Value = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
580 QualType ElTy = E->getArg(Arg: 0)->getType()->getPointeeType();
581 CharUnits StoreSize = CGF.getContext().getTypeSizeInChars(T: ElTy);
582 llvm::StoreInst *Store =
583 CGF.Builder.CreateAlignedStore(Val: Value, Addr: Ptr, Align: StoreSize);
584 Store->setAtomic(Ordering: llvm::AtomicOrdering::Monotonic);
585 Store->setVolatile(true);
586 return Store;
587}
588
589// Emit a simple mangled intrinsic that has 1 argument and a return type
590// matching the argument type. Depending on mode, this may be a constrained
591// floating-point intrinsic.
592Value *emitUnaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF,
593 const CallExpr *E, unsigned IntrinsicID,
594 unsigned ConstrainedIntrinsicID) {
595 llvm::Value *Src0 = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
596
597 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
598 if (CGF.Builder.getIsFPConstrained()) {
599 Function *F = CGF.CGM.getIntrinsic(IID: ConstrainedIntrinsicID, Tys: Src0->getType());
600 return CGF.Builder.CreateConstrainedFPCall(Callee: F, Args: { Src0 });
601 } else {
602 Function *F = CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: Src0->getType());
603 return CGF.Builder.CreateCall(Callee: F, Args: Src0);
604 }
605}
606
607// Emit an intrinsic that has 2 operands of the same type as its result.
608// Depending on mode, this may be a constrained floating-point intrinsic.
609static Value *emitBinaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF,
610 const CallExpr *E, unsigned IntrinsicID,
611 unsigned ConstrainedIntrinsicID) {
612 llvm::Value *Src0 = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
613 llvm::Value *Src1 = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
614
615 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
616 if (CGF.Builder.getIsFPConstrained()) {
617 Function *F = CGF.CGM.getIntrinsic(IID: ConstrainedIntrinsicID, Tys: Src0->getType());
618 return CGF.Builder.CreateConstrainedFPCall(Callee: F, Args: { Src0, Src1 });
619 } else {
620 Function *F = CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: Src0->getType());
621 return CGF.Builder.CreateCall(Callee: F, Args: { Src0, Src1 });
622 }
623}
624
625// Has second type mangled argument.
626static Value *
627emitBinaryExpMaybeConstrainedFPBuiltin(CodeGenFunction &CGF, const CallExpr *E,
628 Intrinsic::ID IntrinsicID,
629 Intrinsic::ID ConstrainedIntrinsicID) {
630 llvm::Value *Src0 = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
631 llvm::Value *Src1 = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
632
633 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
634 if (CGF.Builder.getIsFPConstrained()) {
635 Function *F = CGF.CGM.getIntrinsic(IID: ConstrainedIntrinsicID,
636 Tys: {Src0->getType(), Src1->getType()});
637 return CGF.Builder.CreateConstrainedFPCall(Callee: F, Args: {Src0, Src1});
638 }
639
640 Function *F =
641 CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: {Src0->getType(), Src1->getType()});
642 return CGF.Builder.CreateCall(Callee: F, Args: {Src0, Src1});
643}
644
645// Emit an intrinsic that has 3 operands of the same type as its result.
646// Depending on mode, this may be a constrained floating-point intrinsic.
647static Value *emitTernaryMaybeConstrainedFPBuiltin(CodeGenFunction &CGF,
648 const CallExpr *E, unsigned IntrinsicID,
649 unsigned ConstrainedIntrinsicID) {
650 llvm::Value *Src0 = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
651 llvm::Value *Src1 = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
652 llvm::Value *Src2 = CGF.EmitScalarExpr(E: E->getArg(Arg: 2));
653
654 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
655 if (CGF.Builder.getIsFPConstrained()) {
656 Function *F = CGF.CGM.getIntrinsic(IID: ConstrainedIntrinsicID, Tys: Src0->getType());
657 return CGF.Builder.CreateConstrainedFPCall(Callee: F, Args: { Src0, Src1, Src2 });
658 } else {
659 Function *F = CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: Src0->getType());
660 return CGF.Builder.CreateCall(Callee: F, Args: { Src0, Src1, Src2 });
661 }
662}
663
664// Emit an intrinsic that has overloaded integer result and fp operand.
665static Value *
666emitMaybeConstrainedFPToIntRoundBuiltin(CodeGenFunction &CGF, const CallExpr *E,
667 unsigned IntrinsicID,
668 unsigned ConstrainedIntrinsicID) {
669 llvm::Type *ResultType = CGF.ConvertType(T: E->getType());
670 llvm::Value *Src0 = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
671
672 if (CGF.Builder.getIsFPConstrained()) {
673 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
674 Function *F = CGF.CGM.getIntrinsic(IID: ConstrainedIntrinsicID,
675 Tys: {ResultType, Src0->getType()});
676 return CGF.Builder.CreateConstrainedFPCall(Callee: F, Args: {Src0});
677 } else {
678 Function *F =
679 CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: {ResultType, Src0->getType()});
680 return CGF.Builder.CreateCall(Callee: F, Args: Src0);
681 }
682}
683
684static Value *emitFrexpBuiltin(CodeGenFunction &CGF, const CallExpr *E,
685 Intrinsic::ID IntrinsicID) {
686 llvm::Value *Src0 = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
687 llvm::Value *Src1 = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
688
689 QualType IntPtrTy = E->getArg(Arg: 1)->getType()->getPointeeType();
690 llvm::Type *IntTy = CGF.ConvertType(T: IntPtrTy);
691 llvm::Function *F =
692 CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: {Src0->getType(), IntTy});
693 llvm::Value *Call = CGF.Builder.CreateCall(Callee: F, Args: Src0);
694
695 llvm::Value *Exp = CGF.Builder.CreateExtractValue(Agg: Call, Idxs: 1);
696 LValue LV = CGF.MakeNaturalAlignAddrLValue(V: Src1, T: IntPtrTy);
697 CGF.EmitStoreOfScalar(value: Exp, lvalue: LV);
698
699 return CGF.Builder.CreateExtractValue(Agg: Call, Idxs: 0);
700}
701
702static void emitSincosBuiltin(CodeGenFunction &CGF, const CallExpr *E,
703 Intrinsic::ID IntrinsicID) {
704 llvm::Value *Val = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
705 llvm::Value *Dest0 = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
706 llvm::Value *Dest1 = CGF.EmitScalarExpr(E: E->getArg(Arg: 2));
707
708 llvm::Function *F = CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: {Val->getType()});
709 llvm::Value *Call = CGF.Builder.CreateCall(Callee: F, Args: Val);
710
711 llvm::Value *SinResult = CGF.Builder.CreateExtractValue(Agg: Call, Idxs: 0);
712 llvm::Value *CosResult = CGF.Builder.CreateExtractValue(Agg: Call, Idxs: 1);
713
714 QualType DestPtrType = E->getArg(Arg: 1)->getType()->getPointeeType();
715 LValue SinLV = CGF.MakeNaturalAlignAddrLValue(V: Dest0, T: DestPtrType);
716 LValue CosLV = CGF.MakeNaturalAlignAddrLValue(V: Dest1, T: DestPtrType);
717
718 llvm::StoreInst *StoreSin =
719 CGF.Builder.CreateStore(Val: SinResult, Addr: SinLV.getAddress());
720 llvm::StoreInst *StoreCos =
721 CGF.Builder.CreateStore(Val: CosResult, Addr: CosLV.getAddress());
722
723 // Mark the two stores as non-aliasing with each other. The order of stores
724 // emitted by this builtin is arbitrary, enforcing a particular order will
725 // prevent optimizations later on.
726 llvm::MDBuilder MDHelper(CGF.getLLVMContext());
727 MDNode *Domain = MDHelper.createAnonymousAliasScopeDomain();
728 MDNode *AliasScope = MDHelper.createAnonymousAliasScope(Domain);
729 MDNode *AliasScopeList = MDNode::get(Context&: Call->getContext(), MDs: AliasScope);
730 StoreSin->setMetadata(KindID: LLVMContext::MD_alias_scope, Node: AliasScopeList);
731 StoreCos->setMetadata(KindID: LLVMContext::MD_noalias, Node: AliasScopeList);
732}
733
734static llvm::Value *emitModfBuiltin(CodeGenFunction &CGF, const CallExpr *E,
735 Intrinsic::ID IntrinsicID) {
736 llvm::Value *Val = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
737 llvm::Value *IntPartDest = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
738
739 llvm::Value *Call =
740 CGF.Builder.CreateIntrinsic(ID: IntrinsicID, Types: {Val->getType()}, Args: Val);
741
742 llvm::Value *FractionalResult = CGF.Builder.CreateExtractValue(Agg: Call, Idxs: 0);
743 llvm::Value *IntegralResult = CGF.Builder.CreateExtractValue(Agg: Call, Idxs: 1);
744
745 QualType DestPtrType = E->getArg(Arg: 1)->getType()->getPointeeType();
746 LValue IntegralLV = CGF.MakeNaturalAlignAddrLValue(V: IntPartDest, T: DestPtrType);
747 CGF.EmitStoreOfScalar(value: IntegralResult, lvalue: IntegralLV);
748
749 return FractionalResult;
750}
751
752/// EmitFAbs - Emit a call to @llvm.fabs().
753static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
754 Function *F = CGF.CGM.getIntrinsic(IID: Intrinsic::fabs, Tys: V->getType());
755 llvm::CallInst *Call = CGF.Builder.CreateCall(Callee: F, Args: V);
756 Call->setDoesNotAccessMemory();
757 return Call;
758}
759
760/// Emit the computation of the sign bit for a floating point value. Returns
761/// the i1 sign bit value.
762static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {
763 LLVMContext &C = CGF.CGM.getLLVMContext();
764
765 llvm::Type *Ty = V->getType();
766 int Width = Ty->getPrimitiveSizeInBits();
767 llvm::Type *IntTy = llvm::IntegerType::get(C, NumBits: Width);
768 V = CGF.Builder.CreateBitCast(V, DestTy: IntTy);
769 if (Ty->isPPC_FP128Ty()) {
770 // We want the sign bit of the higher-order double. The bitcast we just
771 // did works as if the double-double was stored to memory and then
772 // read as an i128. The "store" will put the higher-order double in the
773 // lower address in both little- and big-Endian modes, but the "load"
774 // will treat those bits as a different part of the i128: the low bits in
775 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian
776 // we need to shift the high bits down to the low before truncating.
777 Width >>= 1;
778 if (CGF.getTarget().isBigEndian()) {
779 Value *ShiftCst = llvm::ConstantInt::get(Ty: IntTy, V: Width);
780 V = CGF.Builder.CreateLShr(LHS: V, RHS: ShiftCst);
781 }
782 // We are truncating value in order to extract the higher-order
783 // double, which we will be using to extract the sign from.
784 IntTy = llvm::IntegerType::get(C, NumBits: Width);
785 V = CGF.Builder.CreateTrunc(V, DestTy: IntTy);
786 }
787 Value *Zero = llvm::Constant::getNullValue(Ty: IntTy);
788 return CGF.Builder.CreateICmpSLT(LHS: V, RHS: Zero);
789}
790
791/// Checks no arguments or results are passed indirectly in the ABI (i.e. via a
792/// hidden pointer). This is used to check annotating FP libcalls (that could
793/// set `errno`) with "int" TBAA metadata is safe. If any floating-point
794/// arguments are passed indirectly, setup for the call could be incorrectly
795/// optimized out.
796static bool HasNoIndirectArgumentsOrResults(CGFunctionInfo const &FnInfo) {
797 auto IsIndirect = [&](ABIArgInfo const &info) {
798 return info.isIndirect() || info.isIndirectAliased() || info.isInAlloca();
799 };
800 return !IsIndirect(FnInfo.getReturnInfo()) &&
801 llvm::none_of(Range: FnInfo.arguments(),
802 P: [&](CGFunctionInfoArgInfo const &ArgInfo) {
803 return IsIndirect(ArgInfo.info);
804 });
805}
806
807static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
808 const CallExpr *E, llvm::Constant *calleeValue) {
809 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
810 CGCallee callee = CGCallee::forDirect(functionPtr: calleeValue, abstractInfo: GlobalDecl(FD));
811 llvm::CallBase *callOrInvoke = nullptr;
812 CGFunctionInfo const *FnInfo = nullptr;
813 RValue Call =
814 CGF.EmitCall(FnType: E->getCallee()->getType(), Callee: callee, E, ReturnValue: ReturnValueSlot(),
815 /*Chain=*/nullptr, CallOrInvoke: &callOrInvoke, ResolvedFnInfo: &FnInfo);
816
817 if (unsigned BuiltinID = FD->getBuiltinID()) {
818 // Check whether a FP math builtin function, such as BI__builtin_expf
819 ASTContext &Context = CGF.getContext();
820 bool ConstWithoutErrnoAndExceptions =
821 Context.BuiltinInfo.isConstWithoutErrnoAndExceptions(ID: BuiltinID);
822 // Restrict to target with errno, for example, MacOS doesn't set errno.
823 // TODO: Support builtin function with complex type returned, eg: cacosh
824 if (ConstWithoutErrnoAndExceptions && CGF.CGM.getLangOpts().MathErrno &&
825 !CGF.Builder.getIsFPConstrained() && Call.isScalar() &&
826 HasNoIndirectArgumentsOrResults(FnInfo: *FnInfo)) {
827 // Emit "int" TBAA metadata on FP math libcalls.
828 clang::QualType IntTy = Context.IntTy;
829 TBAAAccessInfo TBAAInfo = CGF.CGM.getTBAAAccessInfo(AccessType: IntTy);
830 CGF.CGM.DecorateInstructionWithTBAA(Inst: callOrInvoke, TBAAInfo);
831 }
832 }
833 return Call;
834}
835
836/// Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.*
837/// depending on IntrinsicID.
838///
839/// \arg CGF The current codegen function.
840/// \arg IntrinsicID The ID for the Intrinsic we wish to generate.
841/// \arg X The first argument to the llvm.*.with.overflow.*.
842/// \arg Y The second argument to the llvm.*.with.overflow.*.
843/// \arg Carry The carry returned by the llvm.*.with.overflow.*.
844/// \returns The result (i.e. sum/product) returned by the intrinsic.
845llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF,
846 const Intrinsic::ID IntrinsicID,
847 llvm::Value *X, llvm::Value *Y,
848 llvm::Value *&Carry) {
849 // Make sure we have integers of the same width.
850 assert(X->getType() == Y->getType() &&
851 "Arguments must be the same type. (Did you forget to make sure both "
852 "arguments have the same integer width?)");
853
854 Function *Callee = CGF.CGM.getIntrinsic(IID: IntrinsicID, Tys: X->getType());
855 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, Args: {X, Y});
856 Carry = CGF.Builder.CreateExtractValue(Agg: Tmp, Idxs: 1);
857 return CGF.Builder.CreateExtractValue(Agg: Tmp, Idxs: 0);
858}
859
860namespace {
861 struct WidthAndSignedness {
862 unsigned Width;
863 bool Signed;
864 };
865}
866
867static WidthAndSignedness
868getIntegerWidthAndSignedness(const clang::ASTContext &context,
869 const clang::QualType Type) {
870 assert(Type->isIntegerType() && "Given type is not an integer.");
871 unsigned Width = context.getIntWidth(T: Type);
872 bool Signed = Type->isSignedIntegerType();
873 return {.Width: Width, .Signed: Signed};
874}
875
876// Given one or more integer types, this function produces an integer type that
877// encompasses them: any value in one of the given types could be expressed in
878// the encompassing type.
879static struct WidthAndSignedness
880EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) {
881 assert(Types.size() > 0 && "Empty list of types.");
882
883 // If any of the given types is signed, we must return a signed type.
884 bool Signed = false;
885 for (const auto &Type : Types) {
886 Signed |= Type.Signed;
887 }
888
889 // The encompassing type must have a width greater than or equal to the width
890 // of the specified types. Additionally, if the encompassing type is signed,
891 // its width must be strictly greater than the width of any unsigned types
892 // given.
893 unsigned Width = 0;
894 for (const auto &Type : Types) {
895 unsigned MinWidth = Type.Width + (Signed && !Type.Signed);
896 if (Width < MinWidth) {
897 Width = MinWidth;
898 }
899 }
900
901 return {.Width: Width, .Signed: Signed};
902}
903
904Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) {
905 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend;
906 return Builder.CreateCall(Callee: CGM.getIntrinsic(IID: inst, Tys: {ArgValue->getType()}),
907 Args: ArgValue);
908}
909
910/// Checks if using the result of __builtin_object_size(p, @p From) in place of
911/// __builtin_object_size(p, @p To) is correct
912static bool areBOSTypesCompatible(int From, int To) {
913 // Note: Our __builtin_object_size implementation currently treats Type=0 and
914 // Type=2 identically. Encoding this implementation detail here may make
915 // improving __builtin_object_size difficult in the future, so it's omitted.
916 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2);
917}
918
919static llvm::Value *
920getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) {
921 return ConstantInt::get(Ty: ResType, V: (Type & 2) ? 0 : -1, /*isSigned=*/IsSigned: true);
922}
923
924llvm::Value *
925CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
926 llvm::IntegerType *ResType,
927 llvm::Value *EmittedE,
928 bool IsDynamic) {
929 if (std::optional<uint64_t> ObjectSize =
930 E->tryEvaluateObjectSize(Ctx: getContext(), Type))
931 return ConstantInt::get(Ty: ResType, V: *ObjectSize, /*isSigned=*/IsSigned: true);
932 return emitBuiltinObjectSize(E, Type, ResType, EmittedE, IsDynamic);
933}
934
935namespace {
936
937/// StructFieldAccess is a simple visitor class to grab the first MemberExpr
938/// from an Expr. It records any ArraySubscriptExpr we meet along the way.
939class StructFieldAccess
940 : public ConstStmtVisitor<StructFieldAccess, const Expr *> {
941 bool AddrOfSeen = false;
942
943public:
944 const Expr *ArrayIndex = nullptr;
945 QualType ArrayElementTy;
946
947 const Expr *VisitMemberExpr(const MemberExpr *E) {
948 if (AddrOfSeen && E->getType()->isArrayType())
949 // Avoid forms like '&ptr->array'.
950 return nullptr;
951 return E;
952 }
953
954 const Expr *VisitArraySubscriptExpr(const ArraySubscriptExpr *E) {
955 if (ArrayIndex)
956 // We don't support multiple subscripts.
957 return nullptr;
958
959 AddrOfSeen = false; // '&ptr->array[idx]' is okay.
960 ArrayIndex = E->getIdx();
961 ArrayElementTy = E->getBase()->getType();
962 return Visit(S: E->getBase());
963 }
964 const Expr *VisitCastExpr(const CastExpr *E) {
965 if (E->getCastKind() == CK_LValueToRValue)
966 return E;
967 return Visit(S: E->getSubExpr());
968 }
969 const Expr *VisitParenExpr(const ParenExpr *E) {
970 return Visit(S: E->getSubExpr());
971 }
972 const Expr *VisitUnaryAddrOf(const clang::UnaryOperator *E) {
973 AddrOfSeen = true;
974 return Visit(S: E->getSubExpr());
975 }
976 const Expr *VisitUnaryDeref(const clang::UnaryOperator *E) {
977 AddrOfSeen = false;
978 return Visit(S: E->getSubExpr());
979 }
980 const Expr *VisitBinaryOperator(const clang::BinaryOperator *Op) {
981 return Op->isCommaOp() ? Visit(S: Op->getRHS()) : nullptr;
982 }
983};
984
985} // end anonymous namespace
986
987/// Find a struct's flexible array member. It may be embedded inside multiple
988/// sub-structs, but must still be the last field.
989static const FieldDecl *FindFlexibleArrayMemberField(CodeGenFunction &CGF,
990 ASTContext &Ctx,
991 const RecordDecl *RD) {
992 const LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel =
993 CGF.getLangOpts().getStrictFlexArraysLevel();
994
995 if (RD->isImplicit())
996 return nullptr;
997
998 for (const FieldDecl *FD : RD->fields()) {
999 if (Decl::isFlexibleArrayMemberLike(
1000 Context: Ctx, D: FD, Ty: FD->getType(), StrictFlexArraysLevel,
1001 /*IgnoreTemplateOrMacroSubstitution=*/true))
1002 return FD;
1003
1004 if (const auto *RD = FD->getType()->getAsRecordDecl())
1005 if (const FieldDecl *FD = FindFlexibleArrayMemberField(CGF, Ctx, RD))
1006 return FD;
1007 }
1008
1009 return nullptr;
1010}
1011
1012/// Calculate the offset of a struct field. It may be embedded inside multiple
1013/// sub-structs.
1014static bool GetFieldOffset(ASTContext &Ctx, const RecordDecl *RD,
1015 const FieldDecl *FD, int64_t &Offset) {
1016 if (RD->isImplicit())
1017 return false;
1018
1019 // Keep track of the field number ourselves, because the other methods
1020 // (CGRecordLayout::getLLVMFieldNo) aren't always equivalent to how the AST
1021 // is laid out.
1022 uint32_t FieldNo = 0;
1023 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(D: RD);
1024
1025 for (const FieldDecl *Field : RD->fields()) {
1026 if (Field == FD) {
1027 Offset += Layout.getFieldOffset(FieldNo);
1028 return true;
1029 }
1030
1031 if (const auto *RD = Field->getType()->getAsRecordDecl()) {
1032 if (GetFieldOffset(Ctx, RD, FD, Offset)) {
1033 Offset += Layout.getFieldOffset(FieldNo);
1034 return true;
1035 }
1036 }
1037
1038 if (!RD->isUnion())
1039 ++FieldNo;
1040 }
1041
1042 return false;
1043}
1044
1045static std::optional<int64_t>
1046GetFieldOffset(ASTContext &Ctx, const RecordDecl *RD, const FieldDecl *FD) {
1047 int64_t Offset = 0;
1048
1049 if (GetFieldOffset(Ctx, RD, FD, Offset))
1050 return std::optional<int64_t>(Offset);
1051
1052 return std::nullopt;
1053}
1054
1055llvm::Value *CodeGenFunction::emitCountedBySize(const Expr *E,
1056 llvm::Value *EmittedE,
1057 unsigned Type,
1058 llvm::IntegerType *ResType) {
1059 // Note: If the whole struct is specificed in the __bdos (i.e. Visitor
1060 // returns a DeclRefExpr). The calculation of the whole size of the structure
1061 // with a flexible array member can be done in two ways:
1062 //
1063 // 1) sizeof(struct S) + count * sizeof(typeof(fam))
1064 // 2) offsetof(struct S, fam) + count * sizeof(typeof(fam))
1065 //
1066 // The first will add additional padding after the end of the array
1067 // allocation while the second method is more precise, but not quite expected
1068 // from programmers. See
1069 // https://lore.kernel.org/lkml/ZvV6X5FPBBW7CO1f@archlinux/ for a discussion
1070 // of the topic.
1071 //
1072 // GCC isn't (currently) able to calculate __bdos on a pointer to the whole
1073 // structure. Therefore, because of the above issue, we choose to match what
1074 // GCC does for consistency's sake.
1075
1076 StructFieldAccess Visitor;
1077 E = Visitor.Visit(S: E);
1078 if (!E)
1079 return nullptr;
1080
1081 const Expr *Idx = Visitor.ArrayIndex;
1082 if (Idx) {
1083 if (Idx->HasSideEffects(Ctx: getContext()))
1084 // We can't have side-effects.
1085 return getDefaultBuiltinObjectSizeResult(Type, ResType);
1086
1087 if (const auto *IL = dyn_cast<IntegerLiteral>(Val: Idx)) {
1088 int64_t Val = IL->getValue().getSExtValue();
1089 if (Val < 0)
1090 return getDefaultBuiltinObjectSizeResult(Type, ResType);
1091
1092 // The index is 0, so we don't need to take it into account.
1093 if (Val == 0)
1094 Idx = nullptr;
1095 }
1096 }
1097
1098 // __counted_by on either a flexible array member or a pointer into a struct
1099 // with a flexible array member.
1100 if (const auto *ME = dyn_cast<MemberExpr>(Val: E))
1101 return emitCountedByMemberSize(E: ME, Idx, EmittedE, CastedArrayElementTy: Visitor.ArrayElementTy,
1102 Type, ResType);
1103
1104 // __counted_by on a pointer in a struct.
1105 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(Val: E);
1106 ICE && ICE->getCastKind() == CK_LValueToRValue)
1107 return emitCountedByPointerSize(E: ICE, Idx, EmittedE, CastedArrayElementTy: Visitor.ArrayElementTy,
1108 Type, ResType);
1109
1110 return nullptr;
1111}
1112
1113static llvm::Value *EmitPositiveResultOrZero(CodeGenFunction &CGF,
1114 llvm::Value *Res,
1115 llvm::Value *Index,
1116 llvm::IntegerType *ResType,
1117 bool IsSigned) {
1118 // cmp = (array_size >= 0)
1119 Value *Cmp = CGF.Builder.CreateIsNotNeg(Arg: Res);
1120 if (Index)
1121 // cmp = (cmp && index >= 0)
1122 Cmp = CGF.Builder.CreateAnd(LHS: CGF.Builder.CreateIsNotNeg(Arg: Index), RHS: Cmp);
1123
1124 // return cmp ? result : 0
1125 return CGF.Builder.CreateSelect(C: Cmp, True: Res,
1126 False: ConstantInt::get(Ty: ResType, V: 0, IsSigned));
1127}
1128
1129static std::pair<llvm::Value *, llvm::Value *>
1130GetCountFieldAndIndex(CodeGenFunction &CGF, const MemberExpr *ME,
1131 const FieldDecl *ArrayFD, const FieldDecl *CountFD,
1132 const Expr *Idx, llvm::IntegerType *ResType,
1133 bool IsSigned) {
1134 // count = ptr->count;
1135 Value *Count = CGF.EmitLoadOfCountedByField(Base: ME, FD: ArrayFD, CountDecl: CountFD);
1136 if (!Count)
1137 return std::make_pair<Value *>(x: nullptr, y: nullptr);
1138 Count = CGF.Builder.CreateIntCast(V: Count, DestTy: ResType, isSigned: IsSigned, Name: "count");
1139
1140 // index = ptr->index;
1141 Value *Index = nullptr;
1142 if (Idx) {
1143 bool IdxSigned = Idx->getType()->isSignedIntegerType();
1144 Index = CGF.EmitScalarExpr(E: Idx);
1145 Index = CGF.Builder.CreateIntCast(V: Index, DestTy: ResType, isSigned: IdxSigned, Name: "index");
1146 }
1147
1148 return std::make_pair(x&: Count, y&: Index);
1149}
1150
1151llvm::Value *CodeGenFunction::emitCountedByPointerSize(
1152 const ImplicitCastExpr *E, const Expr *Idx, llvm::Value *EmittedE,
1153 QualType CastedArrayElementTy, unsigned Type, llvm::IntegerType *ResType) {
1154 assert(E->getCastKind() == CK_LValueToRValue &&
1155 "must be an LValue to RValue cast");
1156
1157 const MemberExpr *ME =
1158 dyn_cast<MemberExpr>(Val: E->getSubExpr()->IgnoreParenNoopCasts(Ctx: getContext()));
1159 if (!ME)
1160 return nullptr;
1161
1162 const auto *ArrayBaseFD = dyn_cast<FieldDecl>(Val: ME->getMemberDecl());
1163 if (!ArrayBaseFD || !ArrayBaseFD->getType()->isPointerType() ||
1164 !ArrayBaseFD->getType()->isCountAttributedType())
1165 return nullptr;
1166
1167 // Get the 'count' FieldDecl.
1168 const FieldDecl *CountFD = ArrayBaseFD->findCountedByField();
1169 if (!CountFD)
1170 // Can't find the field referenced by the "counted_by" attribute.
1171 return nullptr;
1172
1173 // Calculate the array's object size using these formulae. (Note: if the
1174 // calculation is negative, we return 0.):
1175 //
1176 // struct p;
1177 // struct s {
1178 // /* ... */
1179 // struct p **array __attribute__((counted_by(count)));
1180 // int count;
1181 // };
1182 //
1183 // 1) 'ptr->array':
1184 //
1185 // count = ptr->count;
1186 //
1187 // array_element_size = sizeof (*ptr->array);
1188 // array_size = count * array_element_size;
1189 //
1190 // result = array_size;
1191 //
1192 // cmp = (result >= 0)
1193 // return cmp ? result : 0;
1194 //
1195 // 2) '&((cast) ptr->array)[idx]':
1196 //
1197 // count = ptr->count;
1198 // index = idx;
1199 //
1200 // array_element_size = sizeof (*ptr->array);
1201 // array_size = count * array_element_size;
1202 //
1203 // casted_array_element_size = sizeof (*((cast) ptr->array));
1204 //
1205 // index_size = index * casted_array_element_size;
1206 // result = array_size - index_size;
1207 //
1208 // cmp = (result >= 0)
1209 // if (index)
1210 // cmp = (cmp && index > 0)
1211 // return cmp ? result : 0;
1212
1213 auto GetElementBaseSize = [&](QualType ElementTy) {
1214 CharUnits ElementSize =
1215 getContext().getTypeSizeInChars(T: ElementTy->getPointeeType());
1216
1217 if (ElementSize.isZero()) {
1218 // This might be a __sized_by (or __counted_by) on a
1219 // 'void *', which counts bytes, not elements.
1220 [[maybe_unused]] auto *CAT = ElementTy->getAs<CountAttributedType>();
1221 assert(CAT && "must have an CountAttributedType");
1222
1223 ElementSize = CharUnits::One();
1224 }
1225
1226 return std::optional<CharUnits>(ElementSize);
1227 };
1228
1229 // Get the sizes of the original array element and the casted array element,
1230 // if different.
1231 std::optional<CharUnits> ArrayElementBaseSize =
1232 GetElementBaseSize(ArrayBaseFD->getType());
1233 if (!ArrayElementBaseSize)
1234 return nullptr;
1235
1236 std::optional<CharUnits> CastedArrayElementBaseSize = ArrayElementBaseSize;
1237 if (!CastedArrayElementTy.isNull() && CastedArrayElementTy->isPointerType()) {
1238 CastedArrayElementBaseSize = GetElementBaseSize(CastedArrayElementTy);
1239 if (!CastedArrayElementBaseSize)
1240 return nullptr;
1241 }
1242
1243 bool IsSigned = CountFD->getType()->isSignedIntegerType();
1244
1245 // count = ptr->count;
1246 // index = ptr->index;
1247 Value *Count, *Index;
1248 std::tie(args&: Count, args&: Index) = GetCountFieldAndIndex(
1249 CGF&: *this, ME, ArrayFD: ArrayBaseFD, CountFD, Idx, ResType, IsSigned);
1250 if (!Count)
1251 return nullptr;
1252
1253 // array_element_size = sizeof (*ptr->array)
1254 auto *ArrayElementSize = llvm::ConstantInt::get(
1255 Ty: ResType, V: ArrayElementBaseSize->getQuantity(), IsSigned);
1256
1257 // casted_array_element_size = sizeof (*((cast) ptr->array));
1258 auto *CastedArrayElementSize = llvm::ConstantInt::get(
1259 Ty: ResType, V: CastedArrayElementBaseSize->getQuantity(), IsSigned);
1260
1261 // array_size = count * array_element_size;
1262 Value *ArraySize = Builder.CreateMul(LHS: Count, RHS: ArrayElementSize, Name: "array_size",
1263 HasNUW: !IsSigned, HasNSW: IsSigned);
1264
1265 // Option (1) 'ptr->array'
1266 // result = array_size
1267 Value *Result = ArraySize;
1268
1269 if (Idx) { // Option (2) '&((cast) ptr->array)[idx]'
1270 // index_size = index * casted_array_element_size;
1271 Value *IndexSize = Builder.CreateMul(LHS: Index, RHS: CastedArrayElementSize,
1272 Name: "index_size", HasNUW: !IsSigned, HasNSW: IsSigned);
1273
1274 // result = result - index_size;
1275 Result =
1276 Builder.CreateSub(LHS: Result, RHS: IndexSize, Name: "result", HasNUW: !IsSigned, HasNSW: IsSigned);
1277 }
1278
1279 return EmitPositiveResultOrZero(CGF&: *this, Res: Result, Index, ResType, IsSigned);
1280}
1281
1282llvm::Value *CodeGenFunction::emitCountedByMemberSize(
1283 const MemberExpr *ME, const Expr *Idx, llvm::Value *EmittedE,
1284 QualType CastedArrayElementTy, unsigned Type, llvm::IntegerType *ResType) {
1285 const auto *FD = dyn_cast<FieldDecl>(Val: ME->getMemberDecl());
1286 if (!FD)
1287 return nullptr;
1288
1289 // Find the flexible array member and check that it has the __counted_by
1290 // attribute.
1291 ASTContext &Ctx = getContext();
1292 const RecordDecl *RD = FD->getDeclContext()->getOuterLexicalRecordContext();
1293 const FieldDecl *FlexibleArrayMemberFD = nullptr;
1294
1295 if (Decl::isFlexibleArrayMemberLike(
1296 Context: Ctx, D: FD, Ty: FD->getType(), StrictFlexArraysLevel: getLangOpts().getStrictFlexArraysLevel(),
1297 /*IgnoreTemplateOrMacroSubstitution=*/true))
1298 FlexibleArrayMemberFD = FD;
1299 else
1300 FlexibleArrayMemberFD = FindFlexibleArrayMemberField(CGF&: *this, Ctx, RD);
1301
1302 if (!FlexibleArrayMemberFD ||
1303 !FlexibleArrayMemberFD->getType()->isCountAttributedType())
1304 return nullptr;
1305
1306 // Get the 'count' FieldDecl.
1307 const FieldDecl *CountFD = FlexibleArrayMemberFD->findCountedByField();
1308 if (!CountFD)
1309 // Can't find the field referenced by the "counted_by" attribute.
1310 return nullptr;
1311
1312 // Calculate the flexible array member's object size using these formulae.
1313 // (Note: if the calculation is negative, we return 0.):
1314 //
1315 // struct p;
1316 // struct s {
1317 // /* ... */
1318 // int count;
1319 // struct p *array[] __attribute__((counted_by(count)));
1320 // };
1321 //
1322 // 1) 'ptr->array':
1323 //
1324 // count = ptr->count;
1325 //
1326 // flexible_array_member_element_size = sizeof (*ptr->array);
1327 // flexible_array_member_size =
1328 // count * flexible_array_member_element_size;
1329 //
1330 // result = flexible_array_member_size;
1331 //
1332 // cmp = (result >= 0)
1333 // return cmp ? result : 0;
1334 //
1335 // 2) '&((cast) ptr->array)[idx]':
1336 //
1337 // count = ptr->count;
1338 // index = idx;
1339 //
1340 // flexible_array_member_element_size = sizeof (*ptr->array);
1341 // flexible_array_member_size =
1342 // count * flexible_array_member_element_size;
1343 //
1344 // casted_flexible_array_member_element_size =
1345 // sizeof (*((cast) ptr->array));
1346 // index_size = index * casted_flexible_array_member_element_size;
1347 //
1348 // result = flexible_array_member_size - index_size;
1349 //
1350 // cmp = (result >= 0)
1351 // if (index != 0)
1352 // cmp = (cmp && index >= 0)
1353 // return cmp ? result : 0;
1354 //
1355 // 3) '&ptr->field':
1356 //
1357 // count = ptr->count;
1358 // sizeof_struct = sizeof (struct s);
1359 //
1360 // flexible_array_member_element_size = sizeof (*ptr->array);
1361 // flexible_array_member_size =
1362 // count * flexible_array_member_element_size;
1363 //
1364 // field_offset = offsetof (struct s, field);
1365 // offset_diff = sizeof_struct - field_offset;
1366 //
1367 // result = offset_diff + flexible_array_member_size;
1368 //
1369 // cmp = (result >= 0)
1370 // return cmp ? result : 0;
1371 //
1372 // 4) '&((cast) ptr->field_array)[idx]':
1373 //
1374 // count = ptr->count;
1375 // index = idx;
1376 // sizeof_struct = sizeof (struct s);
1377 //
1378 // flexible_array_member_element_size = sizeof (*ptr->array);
1379 // flexible_array_member_size =
1380 // count * flexible_array_member_element_size;
1381 //
1382 // casted_field_element_size = sizeof (*((cast) ptr->field_array));
1383 // field_offset = offsetof (struct s, field)
1384 // field_offset += index * casted_field_element_size;
1385 //
1386 // offset_diff = sizeof_struct - field_offset;
1387 //
1388 // result = offset_diff + flexible_array_member_size;
1389 //
1390 // cmp = (result >= 0)
1391 // if (index != 0)
1392 // cmp = (cmp && index >= 0)
1393 // return cmp ? result : 0;
1394
1395 bool IsSigned = CountFD->getType()->isSignedIntegerType();
1396
1397 QualType FlexibleArrayMemberTy = FlexibleArrayMemberFD->getType();
1398
1399 // Explicit cast because otherwise the CharWidth will promote an i32's into
1400 // u64's leading to overflows.
1401 int64_t CharWidth = static_cast<int64_t>(CGM.getContext().getCharWidth());
1402
1403 // field_offset = offsetof (struct s, field);
1404 Value *FieldOffset = nullptr;
1405 if (FlexibleArrayMemberFD != FD) {
1406 std::optional<int64_t> Offset = GetFieldOffset(Ctx, RD, FD);
1407 if (!Offset)
1408 return nullptr;
1409 FieldOffset =
1410 llvm::ConstantInt::get(Ty: ResType, V: *Offset / CharWidth, IsSigned);
1411 }
1412
1413 // count = ptr->count;
1414 // index = ptr->index;
1415 Value *Count, *Index;
1416 std::tie(args&: Count, args&: Index) = GetCountFieldAndIndex(
1417 CGF&: *this, ME, ArrayFD: FlexibleArrayMemberFD, CountFD, Idx, ResType, IsSigned);
1418 if (!Count)
1419 return nullptr;
1420
1421 // flexible_array_member_element_size = sizeof (*ptr->array);
1422 const ArrayType *ArrayTy = Ctx.getAsArrayType(T: FlexibleArrayMemberTy);
1423 CharUnits BaseSize = Ctx.getTypeSizeInChars(T: ArrayTy->getElementType());
1424 auto *FlexibleArrayMemberElementSize =
1425 llvm::ConstantInt::get(Ty: ResType, V: BaseSize.getQuantity(), IsSigned);
1426
1427 // flexible_array_member_size = count * flexible_array_member_element_size;
1428 Value *FlexibleArrayMemberSize =
1429 Builder.CreateMul(LHS: Count, RHS: FlexibleArrayMemberElementSize,
1430 Name: "flexible_array_member_size", HasNUW: !IsSigned, HasNSW: IsSigned);
1431
1432 Value *Result = nullptr;
1433 if (FlexibleArrayMemberFD == FD) {
1434 if (Idx) { // Option (2) '&((cast) ptr->array)[idx]'
1435 // casted_flexible_array_member_element_size =
1436 // sizeof (*((cast) ptr->array));
1437 llvm::ConstantInt *CastedFlexibleArrayMemberElementSize =
1438 FlexibleArrayMemberElementSize;
1439 if (!CastedArrayElementTy.isNull() &&
1440 CastedArrayElementTy->isPointerType()) {
1441 CharUnits BaseSize =
1442 Ctx.getTypeSizeInChars(T: CastedArrayElementTy->getPointeeType());
1443 CastedFlexibleArrayMemberElementSize =
1444 llvm::ConstantInt::get(Ty: ResType, V: BaseSize.getQuantity(), IsSigned);
1445 }
1446
1447 // index_size = index * casted_flexible_array_member_element_size;
1448 Value *IndexSize =
1449 Builder.CreateMul(LHS: Index, RHS: CastedFlexibleArrayMemberElementSize,
1450 Name: "index_size", HasNUW: !IsSigned, HasNSW: IsSigned);
1451
1452 // result = flexible_array_member_size - index_size;
1453 Result = Builder.CreateSub(LHS: FlexibleArrayMemberSize, RHS: IndexSize, Name: "result",
1454 HasNUW: !IsSigned, HasNSW: IsSigned);
1455 } else { // Option (1) 'ptr->array'
1456 // result = flexible_array_member_size;
1457 Result = FlexibleArrayMemberSize;
1458 }
1459 } else {
1460 // sizeof_struct = sizeof (struct s);
1461 llvm::StructType *StructTy = getTypes().getCGRecordLayout(RD).getLLVMType();
1462 const llvm::DataLayout &Layout = CGM.getDataLayout();
1463 TypeSize Size = Layout.getTypeSizeInBits(Ty: StructTy);
1464 Value *SizeofStruct =
1465 llvm::ConstantInt::get(Ty: ResType, V: Size.getKnownMinValue() / CharWidth);
1466
1467 if (Idx) { // Option (4) '&((cast) ptr->field_array)[idx]'
1468 // casted_field_element_size = sizeof (*((cast) ptr->field_array));
1469 CharUnits BaseSize;
1470 if (!CastedArrayElementTy.isNull() &&
1471 CastedArrayElementTy->isPointerType()) {
1472 BaseSize =
1473 Ctx.getTypeSizeInChars(T: CastedArrayElementTy->getPointeeType());
1474 } else {
1475 const ArrayType *ArrayTy = Ctx.getAsArrayType(T: FD->getType());
1476 BaseSize = Ctx.getTypeSizeInChars(T: ArrayTy->getElementType());
1477 }
1478
1479 llvm::ConstantInt *CastedFieldElementSize =
1480 llvm::ConstantInt::get(Ty: ResType, V: BaseSize.getQuantity(), IsSigned);
1481
1482 // field_offset += index * casted_field_element_size;
1483 Value *Mul = Builder.CreateMul(LHS: Index, RHS: CastedFieldElementSize,
1484 Name: "field_offset", HasNUW: !IsSigned, HasNSW: IsSigned);
1485 FieldOffset = Builder.CreateAdd(LHS: FieldOffset, RHS: Mul);
1486 }
1487 // Option (3) '&ptr->field', and Option (4) continuation.
1488 // offset_diff = flexible_array_member_offset - field_offset;
1489 Value *OffsetDiff = Builder.CreateSub(LHS: SizeofStruct, RHS: FieldOffset,
1490 Name: "offset_diff", HasNUW: !IsSigned, HasNSW: IsSigned);
1491
1492 // result = offset_diff + flexible_array_member_size;
1493 Result = Builder.CreateAdd(LHS: FlexibleArrayMemberSize, RHS: OffsetDiff, Name: "result");
1494 }
1495
1496 return EmitPositiveResultOrZero(CGF&: *this, Res: Result, Index, ResType, IsSigned);
1497}
1498
1499/// Returns a Value corresponding to the size of the given expression.
1500/// This Value may be either of the following:
1501/// - A llvm::Argument (if E is a param with the pass_object_size attribute on
1502/// it)
1503/// - A call to the @llvm.objectsize intrinsic
1504///
1505/// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null
1506/// and we wouldn't otherwise try to reference a pass_object_size parameter,
1507/// we'll call @llvm.objectsize on EmittedE, rather than emitting E.
1508llvm::Value *
1509CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
1510 llvm::IntegerType *ResType,
1511 llvm::Value *EmittedE, bool IsDynamic) {
1512 // We need to reference an argument if the pointer is a parameter with the
1513 // pass_object_size attribute.
1514 if (auto *D = dyn_cast<DeclRefExpr>(Val: E->IgnoreParenImpCasts())) {
1515 auto *Param = dyn_cast<ParmVarDecl>(Val: D->getDecl());
1516 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>();
1517 if (Param != nullptr && PS != nullptr &&
1518 areBOSTypesCompatible(From: PS->getType(), To: Type)) {
1519 auto Iter = SizeArguments.find(Val: Param);
1520 assert(Iter != SizeArguments.end());
1521
1522 const ImplicitParamDecl *D = Iter->second;
1523 auto DIter = LocalDeclMap.find(Val: D);
1524 assert(DIter != LocalDeclMap.end());
1525
1526 return EmitLoadOfScalar(Addr: DIter->second, /*Volatile=*/false,
1527 Ty: getContext().getSizeType(), Loc: E->getBeginLoc());
1528 }
1529 }
1530
1531 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't
1532 // evaluate E for side-effects. In either case, we shouldn't lower to
1533 // @llvm.objectsize.
1534 if (Type == 3 || (!EmittedE && E->HasSideEffects(Ctx: getContext())))
1535 return getDefaultBuiltinObjectSizeResult(Type, ResType);
1536
1537 Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E);
1538 assert(Ptr->getType()->isPointerTy() &&
1539 "Non-pointer passed to __builtin_object_size?");
1540
1541 if (IsDynamic)
1542 // Emit special code for a flexible array member with the "counted_by"
1543 // attribute.
1544 if (Value *V = emitCountedBySize(E, EmittedE: Ptr, Type, ResType))
1545 return V;
1546
1547 Function *F =
1548 CGM.getIntrinsic(IID: Intrinsic::objectsize, Tys: {ResType, Ptr->getType()});
1549
1550 // LLVM only supports 0 and 2, make sure that we pass along that as a boolean.
1551 Value *Min = Builder.getInt1(V: (Type & 2) != 0);
1552 // For GCC compatibility, __builtin_object_size treat NULL as unknown size.
1553 Value *NullIsUnknown = Builder.getTrue();
1554 Value *Dynamic = Builder.getInt1(V: IsDynamic);
1555 return Builder.CreateCall(Callee: F, Args: {Ptr, Min, NullIsUnknown, Dynamic});
1556}
1557
1558namespace {
1559/// A struct to generically describe a bit test intrinsic.
1560struct BitTest {
1561 enum ActionKind : uint8_t { TestOnly, Complement, Reset, Set };
1562 enum InterlockingKind : uint8_t {
1563 Unlocked,
1564 Sequential,
1565 Acquire,
1566 Release,
1567 NoFence
1568 };
1569
1570 ActionKind Action;
1571 InterlockingKind Interlocking;
1572 bool Is64Bit;
1573
1574 static BitTest decodeBitTestBuiltin(unsigned BuiltinID);
1575};
1576
1577} // namespace
1578
1579BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) {
1580 switch (BuiltinID) {
1581 // Main portable variants.
1582 case Builtin::BI_bittest:
1583 return {.Action: TestOnly, .Interlocking: Unlocked, .Is64Bit: false};
1584 case Builtin::BI_bittestandcomplement:
1585 return {.Action: Complement, .Interlocking: Unlocked, .Is64Bit: false};
1586 case Builtin::BI_bittestandreset:
1587 return {.Action: Reset, .Interlocking: Unlocked, .Is64Bit: false};
1588 case Builtin::BI_bittestandset:
1589 return {.Action: Set, .Interlocking: Unlocked, .Is64Bit: false};
1590 case Builtin::BI_interlockedbittestandreset:
1591 return {.Action: Reset, .Interlocking: Sequential, .Is64Bit: false};
1592 case Builtin::BI_interlockedbittestandset:
1593 return {.Action: Set, .Interlocking: Sequential, .Is64Bit: false};
1594
1595 // 64-bit variants.
1596 case Builtin::BI_bittest64:
1597 return {.Action: TestOnly, .Interlocking: Unlocked, .Is64Bit: true};
1598 case Builtin::BI_bittestandcomplement64:
1599 return {.Action: Complement, .Interlocking: Unlocked, .Is64Bit: true};
1600 case Builtin::BI_bittestandreset64:
1601 return {.Action: Reset, .Interlocking: Unlocked, .Is64Bit: true};
1602 case Builtin::BI_bittestandset64:
1603 return {.Action: Set, .Interlocking: Unlocked, .Is64Bit: true};
1604 case Builtin::BI_interlockedbittestandreset64:
1605 return {.Action: Reset, .Interlocking: Sequential, .Is64Bit: true};
1606 case Builtin::BI_interlockedbittestandset64:
1607 return {.Action: Set, .Interlocking: Sequential, .Is64Bit: true};
1608
1609 // ARM/AArch64-specific ordering variants.
1610 case Builtin::BI_interlockedbittestandset_acq:
1611 return {.Action: Set, .Interlocking: Acquire, .Is64Bit: false};
1612 case Builtin::BI_interlockedbittestandset_rel:
1613 return {.Action: Set, .Interlocking: Release, .Is64Bit: false};
1614 case Builtin::BI_interlockedbittestandset_nf:
1615 return {.Action: Set, .Interlocking: NoFence, .Is64Bit: false};
1616 case Builtin::BI_interlockedbittestandreset_acq:
1617 return {.Action: Reset, .Interlocking: Acquire, .Is64Bit: false};
1618 case Builtin::BI_interlockedbittestandreset_rel:
1619 return {.Action: Reset, .Interlocking: Release, .Is64Bit: false};
1620 case Builtin::BI_interlockedbittestandreset_nf:
1621 return {.Action: Reset, .Interlocking: NoFence, .Is64Bit: false};
1622 case Builtin::BI_interlockedbittestandreset64_acq:
1623 return {.Action: Reset, .Interlocking: Acquire, .Is64Bit: false};
1624 case Builtin::BI_interlockedbittestandreset64_rel:
1625 return {.Action: Reset, .Interlocking: Release, .Is64Bit: false};
1626 case Builtin::BI_interlockedbittestandreset64_nf:
1627 return {.Action: Reset, .Interlocking: NoFence, .Is64Bit: false};
1628 case Builtin::BI_interlockedbittestandset64_acq:
1629 return {.Action: Set, .Interlocking: Acquire, .Is64Bit: false};
1630 case Builtin::BI_interlockedbittestandset64_rel:
1631 return {.Action: Set, .Interlocking: Release, .Is64Bit: false};
1632 case Builtin::BI_interlockedbittestandset64_nf:
1633 return {.Action: Set, .Interlocking: NoFence, .Is64Bit: false};
1634 }
1635 llvm_unreachable("expected only bittest intrinsics");
1636}
1637
1638static char bitActionToX86BTCode(BitTest::ActionKind A) {
1639 switch (A) {
1640 case BitTest::TestOnly: return '\0';
1641 case BitTest::Complement: return 'c';
1642 case BitTest::Reset: return 'r';
1643 case BitTest::Set: return 's';
1644 }
1645 llvm_unreachable("invalid action");
1646}
1647
1648static llvm::Value *EmitX86BitTestIntrinsic(CodeGenFunction &CGF,
1649 BitTest BT,
1650 const CallExpr *E, Value *BitBase,
1651 Value *BitPos) {
1652 char Action = bitActionToX86BTCode(A: BT.Action);
1653 char SizeSuffix = BT.Is64Bit ? 'q' : 'l';
1654
1655 // Build the assembly.
1656 SmallString<64> Asm;
1657 raw_svector_ostream AsmOS(Asm);
1658 if (BT.Interlocking != BitTest::Unlocked)
1659 AsmOS << "lock ";
1660 AsmOS << "bt";
1661 if (Action)
1662 AsmOS << Action;
1663 AsmOS << SizeSuffix << " $2, ($1)";
1664
1665 // Build the constraints. FIXME: We should support immediates when possible.
1666 std::string Constraints = "={@ccc},r,r,~{cc},~{memory}";
1667 std::string_view MachineClobbers = CGF.getTarget().getClobbers();
1668 if (!MachineClobbers.empty()) {
1669 Constraints += ',';
1670 Constraints += MachineClobbers;
1671 }
1672 llvm::IntegerType *IntType = llvm::IntegerType::get(
1673 C&: CGF.getLLVMContext(),
1674 NumBits: CGF.getContext().getTypeSize(T: E->getArg(Arg: 1)->getType()));
1675 llvm::FunctionType *FTy =
1676 llvm::FunctionType::get(Result: CGF.Int8Ty, Params: {CGF.DefaultPtrTy, IntType}, isVarArg: false);
1677
1678 llvm::InlineAsm *IA =
1679 llvm::InlineAsm::get(Ty: FTy, AsmString: Asm, Constraints, /*hasSideEffects=*/true);
1680 return CGF.Builder.CreateCall(Callee: IA, Args: {BitBase, BitPos});
1681}
1682
1683static llvm::AtomicOrdering
1684getBitTestAtomicOrdering(BitTest::InterlockingKind I) {
1685 switch (I) {
1686 case BitTest::Unlocked: return llvm::AtomicOrdering::NotAtomic;
1687 case BitTest::Sequential: return llvm::AtomicOrdering::SequentiallyConsistent;
1688 case BitTest::Acquire: return llvm::AtomicOrdering::Acquire;
1689 case BitTest::Release: return llvm::AtomicOrdering::Release;
1690 case BitTest::NoFence: return llvm::AtomicOrdering::Monotonic;
1691 }
1692 llvm_unreachable("invalid interlocking");
1693}
1694
1695static llvm::Value *EmitBitCountExpr(CodeGenFunction &CGF, const Expr *E) {
1696 llvm::Value *ArgValue = CGF.EmitScalarExpr(E);
1697 llvm::Type *ArgType = ArgValue->getType();
1698
1699 // Boolean vectors can be casted directly to its bitfield representation. We
1700 // intentionally do not round up to the next power of two size and let LLVM
1701 // handle the trailing bits.
1702 if (auto *VT = dyn_cast<llvm::FixedVectorType>(Val: ArgType);
1703 VT && VT->getElementType()->isIntegerTy(Bitwidth: 1)) {
1704 llvm::Type *StorageType =
1705 llvm::Type::getIntNTy(C&: CGF.getLLVMContext(), N: VT->getNumElements());
1706 ArgValue = CGF.Builder.CreateBitCast(V: ArgValue, DestTy: StorageType);
1707 }
1708
1709 return ArgValue;
1710}
1711
1712/// Emit a _bittest* intrinsic. These intrinsics take a pointer to an array of
1713/// bits and a bit position and read and optionally modify the bit at that
1714/// position. The position index can be arbitrarily large, i.e. it can be larger
1715/// than 31 or 63, so we need an indexed load in the general case.
1716static llvm::Value *EmitBitTestIntrinsic(CodeGenFunction &CGF,
1717 unsigned BuiltinID,
1718 const CallExpr *E) {
1719 Value *BitBase = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
1720 Value *BitPos = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
1721
1722 BitTest BT = BitTest::decodeBitTestBuiltin(BuiltinID);
1723
1724 // X86 has special BT, BTC, BTR, and BTS instructions that handle the array
1725 // indexing operation internally. Use them if possible.
1726 if (CGF.getTarget().getTriple().isX86())
1727 return EmitX86BitTestIntrinsic(CGF, BT, E, BitBase, BitPos);
1728
1729 // Otherwise, use generic code to load one byte and test the bit. Use all but
1730 // the bottom three bits as the array index, and the bottom three bits to form
1731 // a mask.
1732 // Bit = BitBaseI8[BitPos >> 3] & (1 << (BitPos & 0x7)) != 0;
1733 Value *ByteIndex = CGF.Builder.CreateAShr(
1734 LHS: BitPos, RHS: llvm::ConstantInt::get(Ty: BitPos->getType(), V: 3), Name: "bittest.byteidx");
1735 Address ByteAddr(CGF.Builder.CreateInBoundsGEP(Ty: CGF.Int8Ty, Ptr: BitBase, IdxList: ByteIndex,
1736 Name: "bittest.byteaddr"),
1737 CGF.Int8Ty, CharUnits::One());
1738 Value *PosLow =
1739 CGF.Builder.CreateAnd(LHS: CGF.Builder.CreateTrunc(V: BitPos, DestTy: CGF.Int8Ty),
1740 RHS: llvm::ConstantInt::get(Ty: CGF.Int8Ty, V: 0x7));
1741
1742 // The updating instructions will need a mask.
1743 Value *Mask = nullptr;
1744 if (BT.Action != BitTest::TestOnly) {
1745 Mask = CGF.Builder.CreateShl(LHS: llvm::ConstantInt::get(Ty: CGF.Int8Ty, V: 1), RHS: PosLow,
1746 Name: "bittest.mask");
1747 }
1748
1749 // Check the action and ordering of the interlocked intrinsics.
1750 llvm::AtomicOrdering Ordering = getBitTestAtomicOrdering(I: BT.Interlocking);
1751
1752 Value *OldByte = nullptr;
1753 if (Ordering != llvm::AtomicOrdering::NotAtomic) {
1754 // Emit a combined atomicrmw load/store operation for the interlocked
1755 // intrinsics.
1756 llvm::AtomicRMWInst::BinOp RMWOp = llvm::AtomicRMWInst::Or;
1757 if (BT.Action == BitTest::Reset) {
1758 Mask = CGF.Builder.CreateNot(V: Mask);
1759 RMWOp = llvm::AtomicRMWInst::And;
1760 }
1761 OldByte = CGF.Builder.CreateAtomicRMW(Op: RMWOp, Addr: ByteAddr, Val: Mask, Ordering);
1762 } else {
1763 // Emit a plain load for the non-interlocked intrinsics.
1764 OldByte = CGF.Builder.CreateLoad(Addr: ByteAddr, Name: "bittest.byte");
1765 Value *NewByte = nullptr;
1766 switch (BT.Action) {
1767 case BitTest::TestOnly:
1768 // Don't store anything.
1769 break;
1770 case BitTest::Complement:
1771 NewByte = CGF.Builder.CreateXor(LHS: OldByte, RHS: Mask);
1772 break;
1773 case BitTest::Reset:
1774 NewByte = CGF.Builder.CreateAnd(LHS: OldByte, RHS: CGF.Builder.CreateNot(V: Mask));
1775 break;
1776 case BitTest::Set:
1777 NewByte = CGF.Builder.CreateOr(LHS: OldByte, RHS: Mask);
1778 break;
1779 }
1780 if (NewByte)
1781 CGF.Builder.CreateStore(Val: NewByte, Addr: ByteAddr);
1782 }
1783
1784 // However we loaded the old byte, either by plain load or atomicrmw, shift
1785 // the bit into the low position and mask it to 0 or 1.
1786 Value *ShiftedByte = CGF.Builder.CreateLShr(LHS: OldByte, RHS: PosLow, Name: "bittest.shr");
1787 return CGF.Builder.CreateAnd(
1788 LHS: ShiftedByte, RHS: llvm::ConstantInt::get(Ty: CGF.Int8Ty, V: 1), Name: "bittest.res");
1789}
1790
1791namespace {
1792enum class MSVCSetJmpKind {
1793 _setjmpex,
1794 _setjmp3,
1795 _setjmp
1796};
1797}
1798
1799/// MSVC handles setjmp a bit differently on different platforms. On every
1800/// architecture except 32-bit x86, the frame address is passed. On x86, extra
1801/// parameters can be passed as variadic arguments, but we always pass none.
1802static RValue EmitMSVCRTSetJmp(CodeGenFunction &CGF, MSVCSetJmpKind SJKind,
1803 const CallExpr *E) {
1804 llvm::Value *Arg1 = nullptr;
1805 llvm::Type *Arg1Ty = nullptr;
1806 StringRef Name;
1807 bool IsVarArg = false;
1808 if (SJKind == MSVCSetJmpKind::_setjmp3) {
1809 Name = "_setjmp3";
1810 Arg1Ty = CGF.Int32Ty;
1811 Arg1 = llvm::ConstantInt::get(Ty: CGF.IntTy, V: 0);
1812 IsVarArg = true;
1813 } else {
1814 Name = SJKind == MSVCSetJmpKind::_setjmp ? "_setjmp" : "_setjmpex";
1815 Arg1Ty = CGF.Int8PtrTy;
1816 if (CGF.getTarget().getTriple().getArch() == llvm::Triple::aarch64) {
1817 Arg1 = CGF.Builder.CreateCall(
1818 Callee: CGF.CGM.getIntrinsic(IID: Intrinsic::sponentry, Tys: CGF.AllocaInt8PtrTy));
1819 } else
1820 Arg1 = CGF.Builder.CreateCall(
1821 Callee: CGF.CGM.getIntrinsic(IID: Intrinsic::frameaddress, Tys: CGF.AllocaInt8PtrTy),
1822 Args: llvm::ConstantInt::get(Ty: CGF.Int32Ty, V: 0));
1823 }
1824
1825 // Mark the call site and declaration with ReturnsTwice.
1826 llvm::Type *ArgTypes[2] = {CGF.Int8PtrTy, Arg1Ty};
1827 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
1828 C&: CGF.getLLVMContext(), Index: llvm::AttributeList::FunctionIndex,
1829 Kinds: llvm::Attribute::ReturnsTwice);
1830 llvm::FunctionCallee SetJmpFn = CGF.CGM.CreateRuntimeFunction(
1831 Ty: llvm::FunctionType::get(Result: CGF.IntTy, Params: ArgTypes, isVarArg: IsVarArg), Name,
1832 ExtraAttrs: ReturnsTwiceAttr, /*Local=*/true);
1833
1834 llvm::Value *Buf = CGF.Builder.CreateBitOrPointerCast(
1835 V: CGF.EmitScalarExpr(E: E->getArg(Arg: 0)), DestTy: CGF.Int8PtrTy);
1836 llvm::Value *Args[] = {Buf, Arg1};
1837 llvm::CallBase *CB = CGF.EmitRuntimeCallOrInvoke(callee: SetJmpFn, args: Args);
1838 CB->setAttributes(ReturnsTwiceAttr);
1839 return RValue::get(V: CB);
1840}
1841
1842// Emit an MSVC intrinsic. Assumes that arguments have *not* been evaluated.
1843Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
1844 const CallExpr *E) {
1845 switch (BuiltinID) {
1846 case MSVCIntrin::_BitScanForward:
1847 case MSVCIntrin::_BitScanReverse: {
1848 Address IndexAddress(EmitPointerWithAlignment(Addr: E->getArg(Arg: 0)));
1849 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 1));
1850
1851 llvm::Type *ArgType = ArgValue->getType();
1852 llvm::Type *IndexType = IndexAddress.getElementType();
1853 llvm::Type *ResultType = ConvertType(T: E->getType());
1854
1855 Value *ArgZero = llvm::Constant::getNullValue(Ty: ArgType);
1856 Value *ResZero = llvm::Constant::getNullValue(Ty: ResultType);
1857 Value *ResOne = llvm::ConstantInt::get(Ty: ResultType, V: 1);
1858
1859 BasicBlock *Begin = Builder.GetInsertBlock();
1860 BasicBlock *End = createBasicBlock(name: "bitscan_end", parent: this->CurFn);
1861 Builder.SetInsertPoint(End);
1862 PHINode *Result = Builder.CreatePHI(Ty: ResultType, NumReservedValues: 2, Name: "bitscan_result");
1863
1864 Builder.SetInsertPoint(Begin);
1865 Value *IsZero = Builder.CreateICmpEQ(LHS: ArgValue, RHS: ArgZero);
1866 BasicBlock *NotZero = createBasicBlock(name: "bitscan_not_zero", parent: this->CurFn);
1867 Builder.CreateCondBr(Cond: IsZero, True: End, False: NotZero);
1868 Result->addIncoming(V: ResZero, BB: Begin);
1869
1870 Builder.SetInsertPoint(NotZero);
1871
1872 if (BuiltinID == MSVCIntrin::_BitScanForward) {
1873 Function *F = CGM.getIntrinsic(IID: Intrinsic::cttz, Tys: ArgType);
1874 Value *ZeroCount = Builder.CreateCall(Callee: F, Args: {ArgValue, Builder.getTrue()});
1875 ZeroCount = Builder.CreateIntCast(V: ZeroCount, DestTy: IndexType, isSigned: false);
1876 Builder.CreateStore(Val: ZeroCount, Addr: IndexAddress, IsVolatile: false);
1877 } else {
1878 unsigned ArgWidth = cast<llvm::IntegerType>(Val: ArgType)->getBitWidth();
1879 Value *ArgTypeLastIndex = llvm::ConstantInt::get(Ty: IndexType, V: ArgWidth - 1);
1880
1881 Function *F = CGM.getIntrinsic(IID: Intrinsic::ctlz, Tys: ArgType);
1882 Value *ZeroCount = Builder.CreateCall(Callee: F, Args: {ArgValue, Builder.getTrue()});
1883 ZeroCount = Builder.CreateIntCast(V: ZeroCount, DestTy: IndexType, isSigned: false);
1884 Value *Index = Builder.CreateNSWSub(LHS: ArgTypeLastIndex, RHS: ZeroCount);
1885 Builder.CreateStore(Val: Index, Addr: IndexAddress, IsVolatile: false);
1886 }
1887 Builder.CreateBr(Dest: End);
1888 Result->addIncoming(V: ResOne, BB: NotZero);
1889
1890 Builder.SetInsertPoint(End);
1891 return Result;
1892 }
1893 case MSVCIntrin::_InterlockedAnd:
1894 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::And, E);
1895 case MSVCIntrin::_InterlockedExchange:
1896 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xchg, E);
1897 case MSVCIntrin::_InterlockedExchangeAdd:
1898 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Add, E);
1899 case MSVCIntrin::_InterlockedExchangeSub:
1900 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Sub, E);
1901 case MSVCIntrin::_InterlockedOr:
1902 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Or, E);
1903 case MSVCIntrin::_InterlockedXor:
1904 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xor, E);
1905 case MSVCIntrin::_InterlockedExchangeAdd_acq:
1906 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Add, E,
1907 Ordering: AtomicOrdering::Acquire);
1908 case MSVCIntrin::_InterlockedExchangeAdd_rel:
1909 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Add, E,
1910 Ordering: AtomicOrdering::Release);
1911 case MSVCIntrin::_InterlockedExchangeAdd_nf:
1912 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Add, E,
1913 Ordering: AtomicOrdering::Monotonic);
1914 case MSVCIntrin::_InterlockedExchange_acq:
1915 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xchg, E,
1916 Ordering: AtomicOrdering::Acquire);
1917 case MSVCIntrin::_InterlockedExchange_rel:
1918 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xchg, E,
1919 Ordering: AtomicOrdering::Release);
1920 case MSVCIntrin::_InterlockedExchange_nf:
1921 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xchg, E,
1922 Ordering: AtomicOrdering::Monotonic);
1923 case MSVCIntrin::_InterlockedCompareExchange:
1924 return EmitAtomicCmpXchgForMSIntrin(CGF&: *this, E);
1925 case MSVCIntrin::_InterlockedCompareExchange_acq:
1926 return EmitAtomicCmpXchgForMSIntrin(CGF&: *this, E, SuccessOrdering: AtomicOrdering::Acquire);
1927 case MSVCIntrin::_InterlockedCompareExchange_rel:
1928 return EmitAtomicCmpXchgForMSIntrin(CGF&: *this, E, SuccessOrdering: AtomicOrdering::Release);
1929 case MSVCIntrin::_InterlockedCompareExchange_nf:
1930 return EmitAtomicCmpXchgForMSIntrin(CGF&: *this, E, SuccessOrdering: AtomicOrdering::Monotonic);
1931 case MSVCIntrin::_InterlockedCompareExchange128:
1932 return EmitAtomicCmpXchg128ForMSIntrin(
1933 CGF&: *this, E, SuccessOrdering: AtomicOrdering::SequentiallyConsistent);
1934 case MSVCIntrin::_InterlockedCompareExchange128_acq:
1935 return EmitAtomicCmpXchg128ForMSIntrin(CGF&: *this, E, SuccessOrdering: AtomicOrdering::Acquire);
1936 case MSVCIntrin::_InterlockedCompareExchange128_rel:
1937 return EmitAtomicCmpXchg128ForMSIntrin(CGF&: *this, E, SuccessOrdering: AtomicOrdering::Release);
1938 case MSVCIntrin::_InterlockedCompareExchange128_nf:
1939 return EmitAtomicCmpXchg128ForMSIntrin(CGF&: *this, E, SuccessOrdering: AtomicOrdering::Monotonic);
1940 case MSVCIntrin::_InterlockedOr_acq:
1941 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Or, E,
1942 Ordering: AtomicOrdering::Acquire);
1943 case MSVCIntrin::_InterlockedOr_rel:
1944 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Or, E,
1945 Ordering: AtomicOrdering::Release);
1946 case MSVCIntrin::_InterlockedOr_nf:
1947 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Or, E,
1948 Ordering: AtomicOrdering::Monotonic);
1949 case MSVCIntrin::_InterlockedXor_acq:
1950 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xor, E,
1951 Ordering: AtomicOrdering::Acquire);
1952 case MSVCIntrin::_InterlockedXor_rel:
1953 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xor, E,
1954 Ordering: AtomicOrdering::Release);
1955 case MSVCIntrin::_InterlockedXor_nf:
1956 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::Xor, E,
1957 Ordering: AtomicOrdering::Monotonic);
1958 case MSVCIntrin::_InterlockedAnd_acq:
1959 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::And, E,
1960 Ordering: AtomicOrdering::Acquire);
1961 case MSVCIntrin::_InterlockedAnd_rel:
1962 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::And, E,
1963 Ordering: AtomicOrdering::Release);
1964 case MSVCIntrin::_InterlockedAnd_nf:
1965 return MakeBinaryAtomicValue(CGF&: *this, Kind: AtomicRMWInst::And, E,
1966 Ordering: AtomicOrdering::Monotonic);
1967 case MSVCIntrin::_InterlockedIncrement_acq:
1968 return EmitAtomicIncrementValue(CGF&: *this, E, Ordering: AtomicOrdering::Acquire);
1969 case MSVCIntrin::_InterlockedIncrement_rel:
1970 return EmitAtomicIncrementValue(CGF&: *this, E, Ordering: AtomicOrdering::Release);
1971 case MSVCIntrin::_InterlockedIncrement_nf:
1972 return EmitAtomicIncrementValue(CGF&: *this, E, Ordering: AtomicOrdering::Monotonic);
1973 case MSVCIntrin::_InterlockedDecrement_acq:
1974 return EmitAtomicDecrementValue(CGF&: *this, E, Ordering: AtomicOrdering::Acquire);
1975 case MSVCIntrin::_InterlockedDecrement_rel:
1976 return EmitAtomicDecrementValue(CGF&: *this, E, Ordering: AtomicOrdering::Release);
1977 case MSVCIntrin::_InterlockedDecrement_nf:
1978 return EmitAtomicDecrementValue(CGF&: *this, E, Ordering: AtomicOrdering::Monotonic);
1979
1980 case MSVCIntrin::_InterlockedDecrement:
1981 return EmitAtomicDecrementValue(CGF&: *this, E);
1982 case MSVCIntrin::_InterlockedIncrement:
1983 return EmitAtomicIncrementValue(CGF&: *this, E);
1984
1985 case MSVCIntrin::__fastfail: {
1986 // Request immediate process termination from the kernel. The instruction
1987 // sequences to do this are documented on MSDN:
1988 // https://msdn.microsoft.com/en-us/library/dn774154.aspx
1989 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch();
1990 StringRef Asm, Constraints;
1991 switch (ISA) {
1992 default:
1993 ErrorUnsupported(S: E, Type: "__fastfail call for this architecture");
1994 break;
1995 case llvm::Triple::x86:
1996 case llvm::Triple::x86_64:
1997 Asm = "int $$0x29";
1998 Constraints = "{cx}";
1999 break;
2000 case llvm::Triple::thumb:
2001 Asm = "udf #251";
2002 Constraints = "{r0}";
2003 break;
2004 case llvm::Triple::aarch64:
2005 Asm = "brk #0xF003";
2006 Constraints = "{w0}";
2007 }
2008 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: VoidTy, Params: {Int32Ty}, isVarArg: false);
2009 llvm::InlineAsm *IA =
2010 llvm::InlineAsm::get(Ty: FTy, AsmString: Asm, Constraints, /*hasSideEffects=*/true);
2011 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
2012 C&: getLLVMContext(), Index: llvm::AttributeList::FunctionIndex,
2013 Kinds: llvm::Attribute::NoReturn);
2014 llvm::CallInst *CI = Builder.CreateCall(Callee: IA, Args: EmitScalarExpr(E: E->getArg(Arg: 0)));
2015 CI->setAttributes(NoReturnAttr);
2016 return CI;
2017 }
2018 }
2019 llvm_unreachable("Incorrect MSVC intrinsic!");
2020}
2021
2022namespace {
2023// ARC cleanup for __builtin_os_log_format
2024struct CallObjCArcUse final : EHScopeStack::Cleanup {
2025 CallObjCArcUse(llvm::Value *object) : object(object) {}
2026 llvm::Value *object;
2027
2028 void Emit(CodeGenFunction &CGF, Flags flags) override {
2029 CGF.EmitARCIntrinsicUse(values: object);
2030 }
2031};
2032}
2033
2034Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
2035 BuiltinCheckKind Kind) {
2036 assert((Kind == BCK_CLZPassedZero || Kind == BCK_CTZPassedZero) &&
2037 "Unsupported builtin check kind");
2038
2039 Value *ArgValue = EmitBitCountExpr(CGF&: *this, E);
2040 if (!SanOpts.has(K: SanitizerKind::Builtin))
2041 return ArgValue;
2042
2043 auto CheckOrdinal = SanitizerKind::SO_Builtin;
2044 auto CheckHandler = SanitizerHandler::InvalidBuiltin;
2045 SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
2046 Value *Cond = Builder.CreateICmpNE(
2047 LHS: ArgValue, RHS: llvm::Constant::getNullValue(Ty: ArgValue->getType()));
2048 EmitCheck(Checked: std::make_pair(x&: Cond, y&: CheckOrdinal), Check: CheckHandler,
2049 StaticArgs: {EmitCheckSourceLocation(Loc: E->getExprLoc()),
2050 llvm::ConstantInt::get(Ty: Builder.getInt8Ty(), V: Kind)},
2051 DynamicArgs: {});
2052 return ArgValue;
2053}
2054
2055Value *CodeGenFunction::EmitCheckedArgForAssume(const Expr *E) {
2056 Value *ArgValue = EvaluateExprAsBool(E);
2057 if (!SanOpts.has(K: SanitizerKind::Builtin))
2058 return ArgValue;
2059
2060 auto CheckOrdinal = SanitizerKind::SO_Builtin;
2061 auto CheckHandler = SanitizerHandler::InvalidBuiltin;
2062 SanitizerDebugLocation SanScope(this, {CheckOrdinal}, CheckHandler);
2063 EmitCheck(
2064 Checked: std::make_pair(x&: ArgValue, y&: CheckOrdinal), Check: CheckHandler,
2065 StaticArgs: {EmitCheckSourceLocation(Loc: E->getExprLoc()),
2066 llvm::ConstantInt::get(Ty: Builder.getInt8Ty(), V: BCK_AssumePassedFalse)},
2067 DynamicArgs: {});
2068 return ArgValue;
2069}
2070
2071static Value *EmitAbs(CodeGenFunction &CGF, Value *ArgValue, bool HasNSW) {
2072 return CGF.Builder.CreateBinaryIntrinsic(
2073 ID: Intrinsic::abs, LHS: ArgValue,
2074 RHS: ConstantInt::get(Ty: CGF.Builder.getInt1Ty(), V: HasNSW));
2075}
2076
2077static Value *EmitOverflowCheckedAbs(CodeGenFunction &CGF, const CallExpr *E,
2078 bool SanitizeOverflow) {
2079 Value *ArgValue = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
2080
2081 // Try to eliminate overflow check.
2082 if (const auto *VCI = dyn_cast<llvm::ConstantInt>(Val: ArgValue)) {
2083 if (!VCI->isMinSignedValue())
2084 return EmitAbs(CGF, ArgValue, HasNSW: true);
2085 }
2086
2087 SmallVector<SanitizerKind::SanitizerOrdinal, 1> Ordinals;
2088 SanitizerHandler CheckHandler;
2089 if (SanitizeOverflow) {
2090 Ordinals.push_back(Elt: SanitizerKind::SO_SignedIntegerOverflow);
2091 CheckHandler = SanitizerHandler::NegateOverflow;
2092 } else
2093 CheckHandler = SanitizerHandler::SubOverflow;
2094
2095 SanitizerDebugLocation SanScope(&CGF, Ordinals, CheckHandler);
2096
2097 Constant *Zero = Constant::getNullValue(Ty: ArgValue->getType());
2098 Value *ResultAndOverflow = CGF.Builder.CreateBinaryIntrinsic(
2099 ID: Intrinsic::ssub_with_overflow, LHS: Zero, RHS: ArgValue);
2100 Value *Result = CGF.Builder.CreateExtractValue(Agg: ResultAndOverflow, Idxs: 0);
2101 Value *NotOverflow = CGF.Builder.CreateNot(
2102 V: CGF.Builder.CreateExtractValue(Agg: ResultAndOverflow, Idxs: 1));
2103
2104 // TODO: support -ftrapv-handler.
2105 if (SanitizeOverflow) {
2106 CGF.EmitCheck(Checked: {{NotOverflow, SanitizerKind::SO_SignedIntegerOverflow}},
2107 Check: CheckHandler,
2108 StaticArgs: {CGF.EmitCheckSourceLocation(Loc: E->getArg(Arg: 0)->getExprLoc()),
2109 CGF.EmitCheckTypeDescriptor(T: E->getType())},
2110 DynamicArgs: {ArgValue});
2111 } else
2112 CGF.EmitTrapCheck(Checked: NotOverflow, CheckHandlerID: CheckHandler);
2113
2114 Value *CmpResult = CGF.Builder.CreateICmpSLT(LHS: ArgValue, RHS: Zero, Name: "abscond");
2115 return CGF.Builder.CreateSelect(C: CmpResult, True: Result, False: ArgValue, Name: "abs");
2116}
2117
2118/// Get the argument type for arguments to os_log_helper.
2119static CanQualType getOSLogArgType(ASTContext &C, int Size) {
2120 QualType UnsignedTy = C.getIntTypeForBitwidth(DestWidth: Size * 8, /*Signed=*/false);
2121 return C.getCanonicalType(T: UnsignedTy);
2122}
2123
2124llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
2125 const analyze_os_log::OSLogBufferLayout &Layout,
2126 CharUnits BufferAlignment) {
2127 ASTContext &Ctx = getContext();
2128
2129 llvm::SmallString<64> Name;
2130 {
2131 raw_svector_ostream OS(Name);
2132 OS << "__os_log_helper";
2133 OS << "_" << BufferAlignment.getQuantity();
2134 OS << "_" << int(Layout.getSummaryByte());
2135 OS << "_" << int(Layout.getNumArgsByte());
2136 for (const auto &Item : Layout.Items)
2137 OS << "_" << int(Item.getSizeByte()) << "_"
2138 << int(Item.getDescriptorByte());
2139 }
2140
2141 if (llvm::Function *F = CGM.getModule().getFunction(Name))
2142 return F;
2143
2144 llvm::SmallVector<QualType, 4> ArgTys;
2145 FunctionArgList Args;
2146 Args.push_back(Elt: ImplicitParamDecl::Create(
2147 C&: Ctx, DC: nullptr, IdLoc: SourceLocation(), Id: &Ctx.Idents.get(Name: "buffer"), T: Ctx.VoidPtrTy,
2148 ParamKind: ImplicitParamKind::Other));
2149 ArgTys.emplace_back(Args&: Ctx.VoidPtrTy);
2150
2151 for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) {
2152 char Size = Layout.Items[I].getSizeByte();
2153 if (!Size)
2154 continue;
2155
2156 QualType ArgTy = getOSLogArgType(C&: Ctx, Size);
2157 Args.push_back(Elt: ImplicitParamDecl::Create(
2158 C&: Ctx, DC: nullptr, IdLoc: SourceLocation(),
2159 Id: &Ctx.Idents.get(Name: std::string("arg") + llvm::to_string(Value: I)), T: ArgTy,
2160 ParamKind: ImplicitParamKind::Other));
2161 ArgTys.emplace_back(Args&: ArgTy);
2162 }
2163
2164 QualType ReturnTy = Ctx.VoidTy;
2165
2166 // The helper function has linkonce_odr linkage to enable the linker to merge
2167 // identical functions. To ensure the merging always happens, 'noinline' is
2168 // attached to the function when compiling with -Oz.
2169 const CGFunctionInfo &FI =
2170 CGM.getTypes().arrangeBuiltinFunctionDeclaration(resultType: ReturnTy, args: Args);
2171 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(Info: FI);
2172 llvm::Function *Fn = llvm::Function::Create(
2173 Ty: FuncTy, Linkage: llvm::GlobalValue::LinkOnceODRLinkage, N: Name, M: &CGM.getModule());
2174 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
2175 CGM.SetLLVMFunctionAttributes(GD: GlobalDecl(), Info: FI, F: Fn, /*IsThunk=*/false);
2176 CGM.SetLLVMFunctionAttributesForDefinition(D: nullptr, F: Fn);
2177 Fn->setDoesNotThrow();
2178
2179 // Attach 'noinline' at -Oz.
2180 if (CGM.getCodeGenOpts().OptimizeSize == 2)
2181 Fn->addFnAttr(Kind: llvm::Attribute::NoInline);
2182
2183 auto NL = ApplyDebugLocation::CreateEmpty(CGF&: *this);
2184 StartFunction(GD: GlobalDecl(), RetTy: ReturnTy, Fn, FnInfo: FI, Args);
2185
2186 // Create a scope with an artificial location for the body of this function.
2187 auto AL = ApplyDebugLocation::CreateArtificial(CGF&: *this);
2188
2189 CharUnits Offset;
2190 Address BufAddr = makeNaturalAddressForPointer(
2191 Ptr: Builder.CreateLoad(Addr: GetAddrOfLocalVar(VD: Args[0]), Name: "buf"), T: Ctx.VoidTy,
2192 Alignment: BufferAlignment);
2193 Builder.CreateStore(Val: Builder.getInt8(C: Layout.getSummaryByte()),
2194 Addr: Builder.CreateConstByteGEP(Addr: BufAddr, Offset: Offset++, Name: "summary"));
2195 Builder.CreateStore(Val: Builder.getInt8(C: Layout.getNumArgsByte()),
2196 Addr: Builder.CreateConstByteGEP(Addr: BufAddr, Offset: Offset++, Name: "numArgs"));
2197
2198 unsigned I = 1;
2199 for (const auto &Item : Layout.Items) {
2200 Builder.CreateStore(
2201 Val: Builder.getInt8(C: Item.getDescriptorByte()),
2202 Addr: Builder.CreateConstByteGEP(Addr: BufAddr, Offset: Offset++, Name: "argDescriptor"));
2203 Builder.CreateStore(
2204 Val: Builder.getInt8(C: Item.getSizeByte()),
2205 Addr: Builder.CreateConstByteGEP(Addr: BufAddr, Offset: Offset++, Name: "argSize"));
2206
2207 CharUnits Size = Item.size();
2208 if (!Size.getQuantity())
2209 continue;
2210
2211 Address Arg = GetAddrOfLocalVar(VD: Args[I]);
2212 Address Addr = Builder.CreateConstByteGEP(Addr: BufAddr, Offset, Name: "argData");
2213 Addr = Addr.withElementType(ElemTy: Arg.getElementType());
2214 Builder.CreateStore(Val: Builder.CreateLoad(Addr: Arg), Addr);
2215 Offset += Size;
2216 ++I;
2217 }
2218
2219 FinishFunction();
2220
2221 return Fn;
2222}
2223
2224RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
2225 assert(E.getNumArgs() >= 2 &&
2226 "__builtin_os_log_format takes at least 2 arguments");
2227 ASTContext &Ctx = getContext();
2228 analyze_os_log::OSLogBufferLayout Layout;
2229 analyze_os_log::computeOSLogBufferLayout(Ctx, E: &E, layout&: Layout);
2230 Address BufAddr = EmitPointerWithAlignment(Addr: E.getArg(Arg: 0));
2231
2232 // Ignore argument 1, the format string. It is not currently used.
2233 CallArgList Args;
2234 Args.add(rvalue: RValue::get(V: BufAddr.emitRawPointer(CGF&: *this)), type: Ctx.VoidPtrTy);
2235
2236 for (const auto &Item : Layout.Items) {
2237 int Size = Item.getSizeByte();
2238 if (!Size)
2239 continue;
2240
2241 llvm::Value *ArgVal;
2242
2243 if (Item.getKind() == analyze_os_log::OSLogBufferItem::MaskKind) {
2244 uint64_t Val = 0;
2245 for (unsigned I = 0, E = Item.getMaskType().size(); I < E; ++I)
2246 Val |= ((uint64_t)Item.getMaskType()[I]) << I * 8;
2247 ArgVal = llvm::Constant::getIntegerValue(Ty: Int64Ty, V: llvm::APInt(64, Val));
2248 } else if (const Expr *TheExpr = Item.getExpr()) {
2249 ArgVal = EmitScalarExpr(E: TheExpr, /*Ignore*/ IgnoreResultAssign: false);
2250
2251 // If a temporary object that requires destruction after the full
2252 // expression is passed, push a lifetime-extended cleanup to extend its
2253 // lifetime to the end of the enclosing block scope.
2254 auto LifetimeExtendObject = [&](const Expr *E) {
2255 E = E->IgnoreParenCasts();
2256 // Extend lifetimes of objects returned by function calls and message
2257 // sends.
2258
2259 // FIXME: We should do this in other cases in which temporaries are
2260 // created including arguments of non-ARC types (e.g., C++
2261 // temporaries).
2262 if (isa<CallExpr>(Val: E) || isa<ObjCMessageExpr>(Val: E))
2263 return true;
2264 return false;
2265 };
2266
2267 if (TheExpr->getType()->isObjCRetainableType() &&
2268 getLangOpts().ObjCAutoRefCount && LifetimeExtendObject(TheExpr)) {
2269 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar &&
2270 "Only scalar can be a ObjC retainable type");
2271 if (!isa<Constant>(Val: ArgVal)) {
2272 CleanupKind Cleanup = getARCCleanupKind();
2273 QualType Ty = TheExpr->getType();
2274 RawAddress Alloca = RawAddress::invalid();
2275 RawAddress Addr = CreateMemTemp(T: Ty, Name: "os.log.arg", Alloca: &Alloca);
2276 ArgVal = EmitARCRetain(type: Ty, value: ArgVal);
2277 Builder.CreateStore(Val: ArgVal, Addr);
2278 pushLifetimeExtendedDestroy(kind: Cleanup, addr: Alloca, type: Ty,
2279 destroyer: CodeGenFunction::destroyARCStrongPrecise,
2280 useEHCleanupForArray: Cleanup & EHCleanup);
2281
2282 // Push a clang.arc.use call to ensure ARC optimizer knows that the
2283 // argument has to be alive.
2284 if (CGM.getCodeGenOpts().OptimizationLevel != 0)
2285 pushCleanupAfterFullExpr<CallObjCArcUse>(Kind: Cleanup, A: ArgVal);
2286 }
2287 }
2288 } else {
2289 ArgVal = Builder.getInt32(C: Item.getConstValue().getQuantity());
2290 }
2291
2292 unsigned ArgValSize =
2293 CGM.getDataLayout().getTypeSizeInBits(Ty: ArgVal->getType());
2294 llvm::IntegerType *IntTy = llvm::Type::getIntNTy(C&: getLLVMContext(),
2295 N: ArgValSize);
2296 ArgVal = Builder.CreateBitOrPointerCast(V: ArgVal, DestTy: IntTy);
2297 CanQualType ArgTy = getOSLogArgType(C&: Ctx, Size);
2298 // If ArgVal has type x86_fp80, zero-extend ArgVal.
2299 ArgVal = Builder.CreateZExtOrBitCast(V: ArgVal, DestTy: ConvertType(T: ArgTy));
2300 Args.add(rvalue: RValue::get(V: ArgVal), type: ArgTy);
2301 }
2302
2303 const CGFunctionInfo &FI =
2304 CGM.getTypes().arrangeBuiltinFunctionCall(resultType: Ctx.VoidTy, args: Args);
2305 llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction(
2306 Layout, BufferAlignment: BufAddr.getAlignment());
2307 EmitCall(CallInfo: FI, Callee: CGCallee::forDirect(functionPtr: F), ReturnValue: ReturnValueSlot(), Args);
2308 return RValue::get(Addr: BufAddr, CGF&: *this);
2309}
2310
2311static bool isSpecialUnsignedMultiplySignedResult(
2312 unsigned BuiltinID, WidthAndSignedness Op1Info, WidthAndSignedness Op2Info,
2313 WidthAndSignedness ResultInfo) {
2314 return BuiltinID == Builtin::BI__builtin_mul_overflow &&
2315 Op1Info.Width == Op2Info.Width && Op2Info.Width == ResultInfo.Width &&
2316 !Op1Info.Signed && !Op2Info.Signed && ResultInfo.Signed;
2317}
2318
2319static RValue EmitCheckedUnsignedMultiplySignedResult(
2320 CodeGenFunction &CGF, const clang::Expr *Op1, WidthAndSignedness Op1Info,
2321 const clang::Expr *Op2, WidthAndSignedness Op2Info,
2322 const clang::Expr *ResultArg, QualType ResultQTy,
2323 WidthAndSignedness ResultInfo) {
2324 assert(isSpecialUnsignedMultiplySignedResult(
2325 Builtin::BI__builtin_mul_overflow, Op1Info, Op2Info, ResultInfo) &&
2326 "Cannot specialize this multiply");
2327
2328 llvm::Value *V1 = CGF.EmitScalarExpr(E: Op1);
2329 llvm::Value *V2 = CGF.EmitScalarExpr(E: Op2);
2330
2331 llvm::Value *HasOverflow;
2332 llvm::Value *Result = EmitOverflowIntrinsic(
2333 CGF, IntrinsicID: Intrinsic::umul_with_overflow, X: V1, Y: V2, Carry&: HasOverflow);
2334
2335 // The intrinsic call will detect overflow when the value is > UINT_MAX,
2336 // however, since the original builtin had a signed result, we need to report
2337 // an overflow when the result is greater than INT_MAX.
2338 auto IntMax = llvm::APInt::getSignedMaxValue(numBits: ResultInfo.Width);
2339 llvm::Value *IntMaxValue = llvm::ConstantInt::get(Ty: Result->getType(), V: IntMax);
2340
2341 llvm::Value *IntMaxOverflow = CGF.Builder.CreateICmpUGT(LHS: Result, RHS: IntMaxValue);
2342 HasOverflow = CGF.Builder.CreateOr(LHS: HasOverflow, RHS: IntMaxOverflow);
2343
2344 bool isVolatile =
2345 ResultArg->getType()->getPointeeType().isVolatileQualified();
2346 Address ResultPtr = CGF.EmitPointerWithAlignment(Addr: ResultArg);
2347 CGF.Builder.CreateStore(Val: CGF.EmitToMemory(Value: Result, Ty: ResultQTy), Addr: ResultPtr,
2348 IsVolatile: isVolatile);
2349 return RValue::get(V: HasOverflow);
2350}
2351
2352/// Determine if a binop is a checked mixed-sign multiply we can specialize.
2353static bool isSpecialMixedSignMultiply(unsigned BuiltinID,
2354 WidthAndSignedness Op1Info,
2355 WidthAndSignedness Op2Info,
2356 WidthAndSignedness ResultInfo) {
2357 return BuiltinID == Builtin::BI__builtin_mul_overflow &&
2358 std::max(a: Op1Info.Width, b: Op2Info.Width) >= ResultInfo.Width &&
2359 Op1Info.Signed != Op2Info.Signed;
2360}
2361
2362/// Emit a checked mixed-sign multiply. This is a cheaper specialization of
2363/// the generic checked-binop irgen.
2364static RValue
2365EmitCheckedMixedSignMultiply(CodeGenFunction &CGF, const clang::Expr *Op1,
2366 WidthAndSignedness Op1Info, const clang::Expr *Op2,
2367 WidthAndSignedness Op2Info,
2368 const clang::Expr *ResultArg, QualType ResultQTy,
2369 WidthAndSignedness ResultInfo) {
2370 assert(isSpecialMixedSignMultiply(Builtin::BI__builtin_mul_overflow, Op1Info,
2371 Op2Info, ResultInfo) &&
2372 "Not a mixed-sign multipliction we can specialize");
2373
2374 // Emit the signed and unsigned operands.
2375 const clang::Expr *SignedOp = Op1Info.Signed ? Op1 : Op2;
2376 const clang::Expr *UnsignedOp = Op1Info.Signed ? Op2 : Op1;
2377 llvm::Value *Signed = CGF.EmitScalarExpr(E: SignedOp);
2378 llvm::Value *Unsigned = CGF.EmitScalarExpr(E: UnsignedOp);
2379 unsigned SignedOpWidth = Op1Info.Signed ? Op1Info.Width : Op2Info.Width;
2380 unsigned UnsignedOpWidth = Op1Info.Signed ? Op2Info.Width : Op1Info.Width;
2381
2382 // One of the operands may be smaller than the other. If so, [s|z]ext it.
2383 if (SignedOpWidth < UnsignedOpWidth)
2384 Signed = CGF.Builder.CreateSExt(V: Signed, DestTy: Unsigned->getType(), Name: "op.sext");
2385 if (UnsignedOpWidth < SignedOpWidth)
2386 Unsigned = CGF.Builder.CreateZExt(V: Unsigned, DestTy: Signed->getType(), Name: "op.zext");
2387
2388 llvm::Type *OpTy = Signed->getType();
2389 llvm::Value *Zero = llvm::Constant::getNullValue(Ty: OpTy);
2390 Address ResultPtr = CGF.EmitPointerWithAlignment(Addr: ResultArg);
2391 llvm::Type *ResTy = CGF.getTypes().ConvertType(T: ResultQTy);
2392 unsigned OpWidth = std::max(a: Op1Info.Width, b: Op2Info.Width);
2393
2394 // Take the absolute value of the signed operand.
2395 llvm::Value *IsNegative = CGF.Builder.CreateICmpSLT(LHS: Signed, RHS: Zero);
2396 llvm::Value *AbsOfNegative = CGF.Builder.CreateSub(LHS: Zero, RHS: Signed);
2397 llvm::Value *AbsSigned =
2398 CGF.Builder.CreateSelect(C: IsNegative, True: AbsOfNegative, False: Signed);
2399
2400 // Perform a checked unsigned multiplication.
2401 llvm::Value *UnsignedOverflow;
2402 llvm::Value *UnsignedResult =
2403 EmitOverflowIntrinsic(CGF, IntrinsicID: Intrinsic::umul_with_overflow, X: AbsSigned,
2404 Y: Unsigned, Carry&: UnsignedOverflow);
2405
2406 llvm::Value *Overflow, *Result;
2407 if (ResultInfo.Signed) {
2408 // Signed overflow occurs if the result is greater than INT_MAX or lesser
2409 // than INT_MIN, i.e when |Result| > (INT_MAX + IsNegative).
2410 auto IntMax =
2411 llvm::APInt::getSignedMaxValue(numBits: ResultInfo.Width).zext(width: OpWidth);
2412 llvm::Value *MaxResult =
2413 CGF.Builder.CreateAdd(LHS: llvm::ConstantInt::get(Ty: OpTy, V: IntMax),
2414 RHS: CGF.Builder.CreateZExt(V: IsNegative, DestTy: OpTy));
2415 llvm::Value *SignedOverflow =
2416 CGF.Builder.CreateICmpUGT(LHS: UnsignedResult, RHS: MaxResult);
2417 Overflow = CGF.Builder.CreateOr(LHS: UnsignedOverflow, RHS: SignedOverflow);
2418
2419 // Prepare the signed result (possibly by negating it).
2420 llvm::Value *NegativeResult = CGF.Builder.CreateNeg(V: UnsignedResult);
2421 llvm::Value *SignedResult =
2422 CGF.Builder.CreateSelect(C: IsNegative, True: NegativeResult, False: UnsignedResult);
2423 Result = CGF.Builder.CreateTrunc(V: SignedResult, DestTy: ResTy);
2424 } else {
2425 // Unsigned overflow occurs if the result is < 0 or greater than UINT_MAX.
2426 llvm::Value *Underflow = CGF.Builder.CreateAnd(
2427 LHS: IsNegative, RHS: CGF.Builder.CreateIsNotNull(Arg: UnsignedResult));
2428 Overflow = CGF.Builder.CreateOr(LHS: UnsignedOverflow, RHS: Underflow);
2429 if (ResultInfo.Width < OpWidth) {
2430 auto IntMax =
2431 llvm::APInt::getMaxValue(numBits: ResultInfo.Width).zext(width: OpWidth);
2432 llvm::Value *TruncOverflow = CGF.Builder.CreateICmpUGT(
2433 LHS: UnsignedResult, RHS: llvm::ConstantInt::get(Ty: OpTy, V: IntMax));
2434 Overflow = CGF.Builder.CreateOr(LHS: Overflow, RHS: TruncOverflow);
2435 }
2436
2437 // Negate the product if it would be negative in infinite precision.
2438 Result = CGF.Builder.CreateSelect(
2439 C: IsNegative, True: CGF.Builder.CreateNeg(V: UnsignedResult), False: UnsignedResult);
2440
2441 Result = CGF.Builder.CreateTrunc(V: Result, DestTy: ResTy);
2442 }
2443 assert(Overflow && Result && "Missing overflow or result");
2444
2445 bool isVolatile =
2446 ResultArg->getType()->getPointeeType().isVolatileQualified();
2447 CGF.Builder.CreateStore(Val: CGF.EmitToMemory(Value: Result, Ty: ResultQTy), Addr: ResultPtr,
2448 IsVolatile: isVolatile);
2449 return RValue::get(V: Overflow);
2450}
2451
2452static bool
2453TypeRequiresBuiltinLaunderImp(const ASTContext &Ctx, QualType Ty,
2454 llvm::SmallPtrSetImpl<const Decl *> &Seen) {
2455 if (const auto *Arr = Ctx.getAsArrayType(T: Ty))
2456 Ty = Ctx.getBaseElementType(VAT: Arr);
2457
2458 const auto *Record = Ty->getAsCXXRecordDecl();
2459 if (!Record)
2460 return false;
2461
2462 // We've already checked this type, or are in the process of checking it.
2463 if (!Seen.insert(Ptr: Record).second)
2464 return false;
2465
2466 assert(Record->hasDefinition() &&
2467 "Incomplete types should already be diagnosed");
2468
2469 if (Record->isDynamicClass())
2470 return true;
2471
2472 for (FieldDecl *F : Record->fields()) {
2473 if (TypeRequiresBuiltinLaunderImp(Ctx, Ty: F->getType(), Seen))
2474 return true;
2475 }
2476 return false;
2477}
2478
2479/// Determine if the specified type requires laundering by checking if it is a
2480/// dynamic class type or contains a subobject which is a dynamic class type.
2481static bool TypeRequiresBuiltinLaunder(CodeGenModule &CGM, QualType Ty) {
2482 if (!CGM.getCodeGenOpts().StrictVTablePointers)
2483 return false;
2484 llvm::SmallPtrSet<const Decl *, 16> Seen;
2485 return TypeRequiresBuiltinLaunderImp(Ctx: CGM.getContext(), Ty, Seen);
2486}
2487
2488RValue CodeGenFunction::emitRotate(const CallExpr *E, bool IsRotateRight) {
2489 llvm::Value *Src = EmitScalarExpr(E: E->getArg(Arg: 0));
2490 llvm::Value *ShiftAmt = EmitScalarExpr(E: E->getArg(Arg: 1));
2491
2492 // The builtin's shift arg may have a different type than the source arg and
2493 // result, but the LLVM intrinsic uses the same type for all values.
2494 llvm::Type *Ty = Src->getType();
2495 llvm::Type *ShiftTy = ShiftAmt->getType();
2496
2497 unsigned BitWidth = Ty->getIntegerBitWidth();
2498
2499 // Normalize shift amount to [0, BitWidth) range to match runtime behavior.
2500 // This matches the algorithm in ExprConstant.cpp for constant evaluation.
2501 if (BitWidth == 1) {
2502 // Rotating a 1-bit value is always a no-op
2503 ShiftAmt = ConstantInt::get(Ty: ShiftTy, V: 0);
2504 } else if (BitWidth == 2) {
2505 // For 2-bit values: rotation amount is 0 or 1 based on
2506 // whether the amount is even or odd. We can't use srem here because
2507 // the divisor (2) would be misinterpreted as -2 in 2-bit signed arithmetic.
2508 llvm::Value *One = ConstantInt::get(Ty: ShiftTy, V: 1);
2509 ShiftAmt = Builder.CreateAnd(LHS: ShiftAmt, RHS: One);
2510 } else {
2511 unsigned ShiftAmtBitWidth = ShiftTy->getIntegerBitWidth();
2512 bool ShiftAmtIsSigned = E->getArg(Arg: 1)->getType()->isSignedIntegerType();
2513
2514 // Choose the wider type for the divisor to avoid truncation
2515 llvm::Type *DivisorTy = ShiftAmtBitWidth > BitWidth ? ShiftTy : Ty;
2516 llvm::Value *Divisor = ConstantInt::get(Ty: DivisorTy, V: BitWidth);
2517
2518 // Extend ShiftAmt to match Divisor width if needed
2519 if (ShiftAmtBitWidth < DivisorTy->getIntegerBitWidth()) {
2520 ShiftAmt = Builder.CreateIntCast(V: ShiftAmt, DestTy: DivisorTy, isSigned: ShiftAmtIsSigned);
2521 }
2522
2523 // Normalize to [0, BitWidth)
2524 llvm::Value *RemResult;
2525 if (ShiftAmtIsSigned) {
2526 RemResult = Builder.CreateSRem(LHS: ShiftAmt, RHS: Divisor);
2527 // Signed remainder can be negative, convert to positive equivalent
2528 llvm::Value *Zero = ConstantInt::get(Ty: DivisorTy, V: 0);
2529 llvm::Value *IsNegative = Builder.CreateICmpSLT(LHS: RemResult, RHS: Zero);
2530 llvm::Value *PositiveShift = Builder.CreateAdd(LHS: RemResult, RHS: Divisor);
2531 ShiftAmt = Builder.CreateSelect(C: IsNegative, True: PositiveShift, False: RemResult);
2532 } else {
2533 ShiftAmt = Builder.CreateURem(LHS: ShiftAmt, RHS: Divisor);
2534 }
2535 }
2536
2537 // Convert to the source type if needed
2538 if (ShiftAmt->getType() != Ty) {
2539 ShiftAmt = Builder.CreateIntCast(V: ShiftAmt, DestTy: Ty, isSigned: false);
2540 }
2541
2542 // Rotate is a special case of LLVM funnel shift - 1st 2 args are the same.
2543 unsigned IID = IsRotateRight ? Intrinsic::fshr : Intrinsic::fshl;
2544 Function *F = CGM.getIntrinsic(IID, Tys: Ty);
2545 return RValue::get(V: Builder.CreateCall(Callee: F, Args: {Src, Src, ShiftAmt}));
2546}
2547
2548// Map math builtins for long-double to f128 version.
2549static unsigned mutateLongDoubleBuiltin(unsigned BuiltinID) {
2550 switch (BuiltinID) {
2551#define MUTATE_LDBL(func) \
2552 case Builtin::BI__builtin_##func##l: \
2553 return Builtin::BI__builtin_##func##f128;
2554 MUTATE_LDBL(sqrt)
2555 MUTATE_LDBL(cbrt)
2556 MUTATE_LDBL(fabs)
2557 MUTATE_LDBL(log)
2558 MUTATE_LDBL(log2)
2559 MUTATE_LDBL(log10)
2560 MUTATE_LDBL(log1p)
2561 MUTATE_LDBL(logb)
2562 MUTATE_LDBL(exp)
2563 MUTATE_LDBL(exp2)
2564 MUTATE_LDBL(expm1)
2565 MUTATE_LDBL(fdim)
2566 MUTATE_LDBL(hypot)
2567 MUTATE_LDBL(ilogb)
2568 MUTATE_LDBL(pow)
2569 MUTATE_LDBL(fmin)
2570 MUTATE_LDBL(fmax)
2571 MUTATE_LDBL(ceil)
2572 MUTATE_LDBL(trunc)
2573 MUTATE_LDBL(rint)
2574 MUTATE_LDBL(nearbyint)
2575 MUTATE_LDBL(round)
2576 MUTATE_LDBL(floor)
2577 MUTATE_LDBL(lround)
2578 MUTATE_LDBL(llround)
2579 MUTATE_LDBL(lrint)
2580 MUTATE_LDBL(llrint)
2581 MUTATE_LDBL(fmod)
2582 MUTATE_LDBL(modf)
2583 MUTATE_LDBL(nan)
2584 MUTATE_LDBL(nans)
2585 MUTATE_LDBL(inf)
2586 MUTATE_LDBL(fma)
2587 MUTATE_LDBL(sin)
2588 MUTATE_LDBL(cos)
2589 MUTATE_LDBL(tan)
2590 MUTATE_LDBL(sinh)
2591 MUTATE_LDBL(cosh)
2592 MUTATE_LDBL(tanh)
2593 MUTATE_LDBL(asin)
2594 MUTATE_LDBL(acos)
2595 MUTATE_LDBL(atan)
2596 MUTATE_LDBL(asinh)
2597 MUTATE_LDBL(acosh)
2598 MUTATE_LDBL(atanh)
2599 MUTATE_LDBL(atan2)
2600 MUTATE_LDBL(erf)
2601 MUTATE_LDBL(erfc)
2602 MUTATE_LDBL(ldexp)
2603 MUTATE_LDBL(frexp)
2604 MUTATE_LDBL(huge_val)
2605 MUTATE_LDBL(copysign)
2606 MUTATE_LDBL(nextafter)
2607 MUTATE_LDBL(nexttoward)
2608 MUTATE_LDBL(remainder)
2609 MUTATE_LDBL(remquo)
2610 MUTATE_LDBL(scalbln)
2611 MUTATE_LDBL(scalbn)
2612 MUTATE_LDBL(tgamma)
2613 MUTATE_LDBL(lgamma)
2614#undef MUTATE_LDBL
2615 default:
2616 return BuiltinID;
2617 }
2618}
2619
2620static Value *tryUseTestFPKind(CodeGenFunction &CGF, unsigned BuiltinID,
2621 Value *V) {
2622 if (CGF.Builder.getIsFPConstrained() &&
2623 CGF.Builder.getDefaultConstrainedExcept() != fp::ebIgnore) {
2624 if (Value *Result =
2625 CGF.getTargetHooks().testFPKind(V, BuiltinID, Builder&: CGF.Builder, CGM&: CGF.CGM))
2626 return Result;
2627 }
2628 return nullptr;
2629}
2630
2631static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
2632 const FunctionDecl *FD) {
2633 auto Name = FD->getNameAsString() + "__hipstdpar_unsupported";
2634 auto FnTy = CGF->CGM.getTypes().GetFunctionType(GD: FD);
2635 auto UBF = CGF->CGM.getModule().getOrInsertFunction(Name, T: FnTy);
2636
2637 SmallVector<Value *, 16> Args;
2638 for (auto &&FormalTy : FnTy->params())
2639 Args.push_back(Elt: llvm::PoisonValue::get(T: FormalTy));
2640
2641 return RValue::get(V: CGF->Builder.CreateCall(Callee: UBF, Args));
2642}
2643
2644RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
2645 const CallExpr *E,
2646 ReturnValueSlot ReturnValue) {
2647 assert(!getContext().BuiltinInfo.isImmediate(BuiltinID) &&
2648 "Should not codegen for consteval builtins");
2649
2650 const FunctionDecl *FD = GD.getDecl()->getAsFunction();
2651 // See if we can constant fold this builtin. If so, don't emit it at all.
2652 // TODO: Extend this handling to all builtin calls that we can constant-fold.
2653 Expr::EvalResult Result;
2654 if (E->isPRValue() && E->EvaluateAsRValue(Result, Ctx: CGM.getContext()) &&
2655 !Result.hasSideEffects()) {
2656 if (Result.Val.isInt())
2657 return RValue::get(V: llvm::ConstantInt::get(Context&: getLLVMContext(),
2658 V: Result.Val.getInt()));
2659 if (Result.Val.isFloat())
2660 return RValue::get(V: llvm::ConstantFP::get(Context&: getLLVMContext(),
2661 V: Result.Val.getFloat()));
2662 }
2663
2664 // If current long-double semantics is IEEE 128-bit, replace math builtins
2665 // of long-double with f128 equivalent.
2666 // TODO: This mutation should also be applied to other targets other than PPC,
2667 // after backend supports IEEE 128-bit style libcalls.
2668 if (getTarget().getTriple().isPPC64() &&
2669 &getTarget().getLongDoubleFormat() == &llvm::APFloat::IEEEquad())
2670 BuiltinID = mutateLongDoubleBuiltin(BuiltinID);
2671
2672 // If the builtin has been declared explicitly with an assembler label,
2673 // disable the specialized emitting below. Ideally we should communicate the
2674 // rename in IR, or at least avoid generating the intrinsic calls that are
2675 // likely to get lowered to the renamed library functions.
2676 const unsigned BuiltinIDIfNoAsmLabel =
2677 FD->hasAttr<AsmLabelAttr>() ? 0 : BuiltinID;
2678
2679 std::optional<bool> ErrnoOverriden;
2680 // ErrnoOverriden is true if math-errno is overriden via the
2681 // '#pragma float_control(precise, on)'. This pragma disables fast-math,
2682 // which implies math-errno.
2683 if (E->hasStoredFPFeatures()) {
2684 FPOptionsOverride OP = E->getFPFeatures();
2685 if (OP.hasMathErrnoOverride())
2686 ErrnoOverriden = OP.getMathErrnoOverride();
2687 }
2688 // True if 'attribute__((optnone))' is used. This attribute overrides
2689 // fast-math which implies math-errno.
2690 bool OptNone = CurFuncDecl && CurFuncDecl->hasAttr<OptimizeNoneAttr>();
2691
2692 bool IsOptimizationEnabled = CGM.getCodeGenOpts().OptimizationLevel != 0;
2693
2694 bool GenerateFPMathIntrinsics =
2695 getContext().BuiltinInfo.shouldGenerateFPMathIntrinsic(
2696 BuiltinID, Trip: CGM.getTriple(), ErrnoOverwritten: ErrnoOverriden, MathErrnoEnabled: getLangOpts().MathErrno,
2697 HasOptNoneAttr: OptNone, IsOptimizationEnabled);
2698
2699 if (GenerateFPMathIntrinsics) {
2700 switch (BuiltinIDIfNoAsmLabel) {
2701 case Builtin::BIacos:
2702 case Builtin::BIacosf:
2703 case Builtin::BIacosl:
2704 case Builtin::BI__builtin_acos:
2705 case Builtin::BI__builtin_acosf:
2706 case Builtin::BI__builtin_acosf16:
2707 case Builtin::BI__builtin_acosl:
2708 case Builtin::BI__builtin_acosf128:
2709 case Builtin::BI__builtin_elementwise_acos:
2710 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(
2711 CGF&: *this, E, IntrinsicID: Intrinsic::acos, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_acos));
2712
2713 case Builtin::BIasin:
2714 case Builtin::BIasinf:
2715 case Builtin::BIasinl:
2716 case Builtin::BI__builtin_asin:
2717 case Builtin::BI__builtin_asinf:
2718 case Builtin::BI__builtin_asinf16:
2719 case Builtin::BI__builtin_asinl:
2720 case Builtin::BI__builtin_asinf128:
2721 case Builtin::BI__builtin_elementwise_asin:
2722 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(
2723 CGF&: *this, E, IntrinsicID: Intrinsic::asin, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_asin));
2724
2725 case Builtin::BIatan:
2726 case Builtin::BIatanf:
2727 case Builtin::BIatanl:
2728 case Builtin::BI__builtin_atan:
2729 case Builtin::BI__builtin_atanf:
2730 case Builtin::BI__builtin_atanf16:
2731 case Builtin::BI__builtin_atanl:
2732 case Builtin::BI__builtin_atanf128:
2733 case Builtin::BI__builtin_elementwise_atan:
2734 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(
2735 CGF&: *this, E, IntrinsicID: Intrinsic::atan, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_atan));
2736
2737 case Builtin::BIatan2:
2738 case Builtin::BIatan2f:
2739 case Builtin::BIatan2l:
2740 case Builtin::BI__builtin_atan2:
2741 case Builtin::BI__builtin_atan2f:
2742 case Builtin::BI__builtin_atan2f16:
2743 case Builtin::BI__builtin_atan2l:
2744 case Builtin::BI__builtin_atan2f128:
2745 case Builtin::BI__builtin_elementwise_atan2:
2746 return RValue::get(V: emitBinaryMaybeConstrainedFPBuiltin(
2747 CGF&: *this, E, IntrinsicID: Intrinsic::atan2,
2748 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_atan2));
2749
2750 case Builtin::BIceil:
2751 case Builtin::BIceilf:
2752 case Builtin::BIceill:
2753 case Builtin::BI__builtin_ceil:
2754 case Builtin::BI__builtin_ceilf:
2755 case Builtin::BI__builtin_ceilf16:
2756 case Builtin::BI__builtin_ceill:
2757 case Builtin::BI__builtin_ceilf128:
2758 case Builtin::BI__builtin_elementwise_ceil:
2759 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2760 IntrinsicID: Intrinsic::ceil,
2761 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_ceil));
2762
2763 case Builtin::BIcopysign:
2764 case Builtin::BIcopysignf:
2765 case Builtin::BIcopysignl:
2766 case Builtin::BI__builtin_copysign:
2767 case Builtin::BI__builtin_copysignf:
2768 case Builtin::BI__builtin_copysignf16:
2769 case Builtin::BI__builtin_copysignl:
2770 case Builtin::BI__builtin_copysignf128:
2771 return RValue::get(
2772 V: emitBuiltinWithOneOverloadedType<2>(CGF&: *this, E, IntrinsicID: Intrinsic::copysign));
2773
2774 case Builtin::BIcos:
2775 case Builtin::BIcosf:
2776 case Builtin::BIcosl:
2777 case Builtin::BI__builtin_cos:
2778 case Builtin::BI__builtin_cosf:
2779 case Builtin::BI__builtin_cosf16:
2780 case Builtin::BI__builtin_cosl:
2781 case Builtin::BI__builtin_cosf128:
2782 case Builtin::BI__builtin_elementwise_cos:
2783 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2784 IntrinsicID: Intrinsic::cos,
2785 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_cos));
2786
2787 case Builtin::BIcosh:
2788 case Builtin::BIcoshf:
2789 case Builtin::BIcoshl:
2790 case Builtin::BI__builtin_cosh:
2791 case Builtin::BI__builtin_coshf:
2792 case Builtin::BI__builtin_coshf16:
2793 case Builtin::BI__builtin_coshl:
2794 case Builtin::BI__builtin_coshf128:
2795 case Builtin::BI__builtin_elementwise_cosh:
2796 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(
2797 CGF&: *this, E, IntrinsicID: Intrinsic::cosh, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_cosh));
2798
2799 case Builtin::BIexp:
2800 case Builtin::BIexpf:
2801 case Builtin::BIexpl:
2802 case Builtin::BI__builtin_exp:
2803 case Builtin::BI__builtin_expf:
2804 case Builtin::BI__builtin_expf16:
2805 case Builtin::BI__builtin_expl:
2806 case Builtin::BI__builtin_expf128:
2807 case Builtin::BI__builtin_elementwise_exp:
2808 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2809 IntrinsicID: Intrinsic::exp,
2810 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_exp));
2811
2812 case Builtin::BIexp2:
2813 case Builtin::BIexp2f:
2814 case Builtin::BIexp2l:
2815 case Builtin::BI__builtin_exp2:
2816 case Builtin::BI__builtin_exp2f:
2817 case Builtin::BI__builtin_exp2f16:
2818 case Builtin::BI__builtin_exp2l:
2819 case Builtin::BI__builtin_exp2f128:
2820 case Builtin::BI__builtin_elementwise_exp2:
2821 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2822 IntrinsicID: Intrinsic::exp2,
2823 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_exp2));
2824 case Builtin::BI__builtin_exp10:
2825 case Builtin::BI__builtin_exp10f:
2826 case Builtin::BI__builtin_exp10f16:
2827 case Builtin::BI__builtin_exp10l:
2828 case Builtin::BI__builtin_exp10f128:
2829 case Builtin::BI__builtin_elementwise_exp10: {
2830 // TODO: strictfp support
2831 if (Builder.getIsFPConstrained())
2832 break;
2833 return RValue::get(
2834 V: emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::exp10));
2835 }
2836 case Builtin::BIfabs:
2837 case Builtin::BIfabsf:
2838 case Builtin::BIfabsl:
2839 case Builtin::BI__builtin_fabs:
2840 case Builtin::BI__builtin_fabsf:
2841 case Builtin::BI__builtin_fabsf16:
2842 case Builtin::BI__builtin_fabsl:
2843 case Builtin::BI__builtin_fabsf128:
2844 return RValue::get(
2845 V: emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::fabs));
2846
2847 case Builtin::BIfloor:
2848 case Builtin::BIfloorf:
2849 case Builtin::BIfloorl:
2850 case Builtin::BI__builtin_floor:
2851 case Builtin::BI__builtin_floorf:
2852 case Builtin::BI__builtin_floorf16:
2853 case Builtin::BI__builtin_floorl:
2854 case Builtin::BI__builtin_floorf128:
2855 case Builtin::BI__builtin_elementwise_floor:
2856 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2857 IntrinsicID: Intrinsic::floor,
2858 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_floor));
2859
2860 case Builtin::BIfma:
2861 case Builtin::BIfmaf:
2862 case Builtin::BIfmal:
2863 case Builtin::BI__builtin_fma:
2864 case Builtin::BI__builtin_fmaf:
2865 case Builtin::BI__builtin_fmaf16:
2866 case Builtin::BI__builtin_fmal:
2867 case Builtin::BI__builtin_fmaf128:
2868 case Builtin::BI__builtin_elementwise_fma:
2869 return RValue::get(V: emitTernaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2870 IntrinsicID: Intrinsic::fma,
2871 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_fma));
2872
2873 case Builtin::BIfmax:
2874 case Builtin::BIfmaxf:
2875 case Builtin::BIfmaxl:
2876 case Builtin::BI__builtin_fmax:
2877 case Builtin::BI__builtin_fmaxf:
2878 case Builtin::BI__builtin_fmaxf16:
2879 case Builtin::BI__builtin_fmaxl:
2880 case Builtin::BI__builtin_fmaxf128: {
2881 IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2882 Builder.getFastMathFlags().setNoSignedZeros();
2883 return RValue::get(V: emitBinaryMaybeConstrainedFPBuiltin(
2884 CGF&: *this, E, IntrinsicID: Intrinsic::maxnum,
2885 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_maxnum));
2886 }
2887
2888 case Builtin::BIfmin:
2889 case Builtin::BIfminf:
2890 case Builtin::BIfminl:
2891 case Builtin::BI__builtin_fmin:
2892 case Builtin::BI__builtin_fminf:
2893 case Builtin::BI__builtin_fminf16:
2894 case Builtin::BI__builtin_fminl:
2895 case Builtin::BI__builtin_fminf128: {
2896 IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2897 Builder.getFastMathFlags().setNoSignedZeros();
2898 return RValue::get(V: emitBinaryMaybeConstrainedFPBuiltin(
2899 CGF&: *this, E, IntrinsicID: Intrinsic::minnum,
2900 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_minnum));
2901 }
2902
2903 case Builtin::BIfmaximum_num:
2904 case Builtin::BIfmaximum_numf:
2905 case Builtin::BIfmaximum_numl:
2906 case Builtin::BI__builtin_fmaximum_num:
2907 case Builtin::BI__builtin_fmaximum_numf:
2908 case Builtin::BI__builtin_fmaximum_numf16:
2909 case Builtin::BI__builtin_fmaximum_numl:
2910 case Builtin::BI__builtin_fmaximum_numf128:
2911 return RValue::get(
2912 V: emitBuiltinWithOneOverloadedType<2>(CGF&: *this, E, IntrinsicID: Intrinsic::maximumnum));
2913
2914 case Builtin::BIfminimum_num:
2915 case Builtin::BIfminimum_numf:
2916 case Builtin::BIfminimum_numl:
2917 case Builtin::BI__builtin_fminimum_num:
2918 case Builtin::BI__builtin_fminimum_numf:
2919 case Builtin::BI__builtin_fminimum_numf16:
2920 case Builtin::BI__builtin_fminimum_numl:
2921 case Builtin::BI__builtin_fminimum_numf128:
2922 return RValue::get(
2923 V: emitBuiltinWithOneOverloadedType<2>(CGF&: *this, E, IntrinsicID: Intrinsic::minimumnum));
2924
2925 // fmod() is a special-case. It maps to the frem instruction rather than an
2926 // LLVM intrinsic.
2927 case Builtin::BIfmod:
2928 case Builtin::BIfmodf:
2929 case Builtin::BIfmodl:
2930 case Builtin::BI__builtin_fmod:
2931 case Builtin::BI__builtin_fmodf:
2932 case Builtin::BI__builtin_fmodf16:
2933 case Builtin::BI__builtin_fmodl:
2934 case Builtin::BI__builtin_fmodf128:
2935 case Builtin::BI__builtin_elementwise_fmod: {
2936 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
2937 Value *Arg1 = EmitScalarExpr(E: E->getArg(Arg: 0));
2938 Value *Arg2 = EmitScalarExpr(E: E->getArg(Arg: 1));
2939 if (Builder.getIsFPConstrained()) {
2940 Function *F = CGM.getIntrinsic(IID: Intrinsic::experimental_constrained_frem,
2941 Tys: Arg1->getType());
2942 return RValue::get(V: Builder.CreateConstrainedFPCall(Callee: F, Args: {Arg1, Arg2}));
2943 } else {
2944 return RValue::get(V: Builder.CreateFRem(L: Arg1, R: Arg2, Name: "fmod"));
2945 }
2946 }
2947
2948 case Builtin::BIlog:
2949 case Builtin::BIlogf:
2950 case Builtin::BIlogl:
2951 case Builtin::BI__builtin_log:
2952 case Builtin::BI__builtin_logf:
2953 case Builtin::BI__builtin_logf16:
2954 case Builtin::BI__builtin_logl:
2955 case Builtin::BI__builtin_logf128:
2956 case Builtin::BI__builtin_elementwise_log:
2957 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2958 IntrinsicID: Intrinsic::log,
2959 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_log));
2960
2961 case Builtin::BIlog10:
2962 case Builtin::BIlog10f:
2963 case Builtin::BIlog10l:
2964 case Builtin::BI__builtin_log10:
2965 case Builtin::BI__builtin_log10f:
2966 case Builtin::BI__builtin_log10f16:
2967 case Builtin::BI__builtin_log10l:
2968 case Builtin::BI__builtin_log10f128:
2969 case Builtin::BI__builtin_elementwise_log10:
2970 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2971 IntrinsicID: Intrinsic::log10,
2972 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_log10));
2973
2974 case Builtin::BIlog2:
2975 case Builtin::BIlog2f:
2976 case Builtin::BIlog2l:
2977 case Builtin::BI__builtin_log2:
2978 case Builtin::BI__builtin_log2f:
2979 case Builtin::BI__builtin_log2f16:
2980 case Builtin::BI__builtin_log2l:
2981 case Builtin::BI__builtin_log2f128:
2982 case Builtin::BI__builtin_elementwise_log2:
2983 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2984 IntrinsicID: Intrinsic::log2,
2985 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_log2));
2986
2987 case Builtin::BInearbyint:
2988 case Builtin::BInearbyintf:
2989 case Builtin::BInearbyintl:
2990 case Builtin::BI__builtin_nearbyint:
2991 case Builtin::BI__builtin_nearbyintf:
2992 case Builtin::BI__builtin_nearbyintl:
2993 case Builtin::BI__builtin_nearbyintf128:
2994 case Builtin::BI__builtin_elementwise_nearbyint:
2995 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
2996 IntrinsicID: Intrinsic::nearbyint,
2997 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_nearbyint));
2998
2999 case Builtin::BIpow:
3000 case Builtin::BIpowf:
3001 case Builtin::BIpowl:
3002 case Builtin::BI__builtin_pow:
3003 case Builtin::BI__builtin_powf:
3004 case Builtin::BI__builtin_powf16:
3005 case Builtin::BI__builtin_powl:
3006 case Builtin::BI__builtin_powf128:
3007 case Builtin::BI__builtin_elementwise_pow:
3008 return RValue::get(V: emitBinaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
3009 IntrinsicID: Intrinsic::pow,
3010 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_pow));
3011
3012 case Builtin::BIrint:
3013 case Builtin::BIrintf:
3014 case Builtin::BIrintl:
3015 case Builtin::BI__builtin_rint:
3016 case Builtin::BI__builtin_rintf:
3017 case Builtin::BI__builtin_rintf16:
3018 case Builtin::BI__builtin_rintl:
3019 case Builtin::BI__builtin_rintf128:
3020 case Builtin::BI__builtin_elementwise_rint:
3021 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
3022 IntrinsicID: Intrinsic::rint,
3023 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_rint));
3024
3025 case Builtin::BIround:
3026 case Builtin::BIroundf:
3027 case Builtin::BIroundl:
3028 case Builtin::BI__builtin_round:
3029 case Builtin::BI__builtin_roundf:
3030 case Builtin::BI__builtin_roundf16:
3031 case Builtin::BI__builtin_roundl:
3032 case Builtin::BI__builtin_roundf128:
3033 case Builtin::BI__builtin_elementwise_round:
3034 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
3035 IntrinsicID: Intrinsic::round,
3036 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_round));
3037
3038 case Builtin::BIroundeven:
3039 case Builtin::BIroundevenf:
3040 case Builtin::BIroundevenl:
3041 case Builtin::BI__builtin_roundeven:
3042 case Builtin::BI__builtin_roundevenf:
3043 case Builtin::BI__builtin_roundevenf16:
3044 case Builtin::BI__builtin_roundevenl:
3045 case Builtin::BI__builtin_roundevenf128:
3046 case Builtin::BI__builtin_elementwise_roundeven:
3047 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
3048 IntrinsicID: Intrinsic::roundeven,
3049 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_roundeven));
3050
3051 case Builtin::BIsin:
3052 case Builtin::BIsinf:
3053 case Builtin::BIsinl:
3054 case Builtin::BI__builtin_sin:
3055 case Builtin::BI__builtin_sinf:
3056 case Builtin::BI__builtin_sinf16:
3057 case Builtin::BI__builtin_sinl:
3058 case Builtin::BI__builtin_sinf128:
3059 case Builtin::BI__builtin_elementwise_sin:
3060 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
3061 IntrinsicID: Intrinsic::sin,
3062 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_sin));
3063
3064 case Builtin::BIsinh:
3065 case Builtin::BIsinhf:
3066 case Builtin::BIsinhl:
3067 case Builtin::BI__builtin_sinh:
3068 case Builtin::BI__builtin_sinhf:
3069 case Builtin::BI__builtin_sinhf16:
3070 case Builtin::BI__builtin_sinhl:
3071 case Builtin::BI__builtin_sinhf128:
3072 case Builtin::BI__builtin_elementwise_sinh:
3073 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(
3074 CGF&: *this, E, IntrinsicID: Intrinsic::sinh, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_sinh));
3075
3076 case Builtin::BI__builtin_sincospi:
3077 case Builtin::BI__builtin_sincospif:
3078 case Builtin::BI__builtin_sincospil:
3079 if (Builder.getIsFPConstrained())
3080 break; // TODO: Emit constrained sincospi intrinsic once one exists.
3081 emitSincosBuiltin(CGF&: *this, E, IntrinsicID: Intrinsic::sincospi);
3082 return RValue::get(V: nullptr);
3083
3084 case Builtin::BIsincos:
3085 case Builtin::BIsincosf:
3086 case Builtin::BIsincosl:
3087 case Builtin::BI__builtin_sincos:
3088 case Builtin::BI__builtin_sincosf:
3089 case Builtin::BI__builtin_sincosf16:
3090 case Builtin::BI__builtin_sincosl:
3091 case Builtin::BI__builtin_sincosf128:
3092 if (Builder.getIsFPConstrained())
3093 break; // TODO: Emit constrained sincos intrinsic once one exists.
3094 emitSincosBuiltin(CGF&: *this, E, IntrinsicID: Intrinsic::sincos);
3095 return RValue::get(V: nullptr);
3096
3097 case Builtin::BIsqrt:
3098 case Builtin::BIsqrtf:
3099 case Builtin::BIsqrtl:
3100 case Builtin::BI__builtin_sqrt:
3101 case Builtin::BI__builtin_sqrtf:
3102 case Builtin::BI__builtin_sqrtf16:
3103 case Builtin::BI__builtin_sqrtl:
3104 case Builtin::BI__builtin_sqrtf128:
3105 case Builtin::BI__builtin_elementwise_sqrt: {
3106 llvm::Value *Call = emitUnaryMaybeConstrainedFPBuiltin(
3107 CGF&: *this, E, IntrinsicID: Intrinsic::sqrt, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_sqrt);
3108 SetSqrtFPAccuracy(Call);
3109 return RValue::get(V: Call);
3110 }
3111
3112 case Builtin::BItan:
3113 case Builtin::BItanf:
3114 case Builtin::BItanl:
3115 case Builtin::BI__builtin_tan:
3116 case Builtin::BI__builtin_tanf:
3117 case Builtin::BI__builtin_tanf16:
3118 case Builtin::BI__builtin_tanl:
3119 case Builtin::BI__builtin_tanf128:
3120 case Builtin::BI__builtin_elementwise_tan:
3121 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(
3122 CGF&: *this, E, IntrinsicID: Intrinsic::tan, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_tan));
3123
3124 case Builtin::BItanh:
3125 case Builtin::BItanhf:
3126 case Builtin::BItanhl:
3127 case Builtin::BI__builtin_tanh:
3128 case Builtin::BI__builtin_tanhf:
3129 case Builtin::BI__builtin_tanhf16:
3130 case Builtin::BI__builtin_tanhl:
3131 case Builtin::BI__builtin_tanhf128:
3132 case Builtin::BI__builtin_elementwise_tanh:
3133 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(
3134 CGF&: *this, E, IntrinsicID: Intrinsic::tanh, ConstrainedIntrinsicID: Intrinsic::experimental_constrained_tanh));
3135
3136 case Builtin::BItrunc:
3137 case Builtin::BItruncf:
3138 case Builtin::BItruncl:
3139 case Builtin::BI__builtin_trunc:
3140 case Builtin::BI__builtin_truncf:
3141 case Builtin::BI__builtin_truncf16:
3142 case Builtin::BI__builtin_truncl:
3143 case Builtin::BI__builtin_truncf128:
3144 case Builtin::BI__builtin_elementwise_trunc:
3145 return RValue::get(V: emitUnaryMaybeConstrainedFPBuiltin(CGF&: *this, E,
3146 IntrinsicID: Intrinsic::trunc,
3147 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_trunc));
3148
3149 case Builtin::BIlround:
3150 case Builtin::BIlroundf:
3151 case Builtin::BIlroundl:
3152 case Builtin::BI__builtin_lround:
3153 case Builtin::BI__builtin_lroundf:
3154 case Builtin::BI__builtin_lroundl:
3155 case Builtin::BI__builtin_lroundf128:
3156 return RValue::get(V: emitMaybeConstrainedFPToIntRoundBuiltin(
3157 CGF&: *this, E, IntrinsicID: Intrinsic::lround,
3158 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_lround));
3159
3160 case Builtin::BIllround:
3161 case Builtin::BIllroundf:
3162 case Builtin::BIllroundl:
3163 case Builtin::BI__builtin_llround:
3164 case Builtin::BI__builtin_llroundf:
3165 case Builtin::BI__builtin_llroundl:
3166 case Builtin::BI__builtin_llroundf128:
3167 return RValue::get(V: emitMaybeConstrainedFPToIntRoundBuiltin(
3168 CGF&: *this, E, IntrinsicID: Intrinsic::llround,
3169 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_llround));
3170
3171 case Builtin::BIlrint:
3172 case Builtin::BIlrintf:
3173 case Builtin::BIlrintl:
3174 case Builtin::BI__builtin_lrint:
3175 case Builtin::BI__builtin_lrintf:
3176 case Builtin::BI__builtin_lrintl:
3177 case Builtin::BI__builtin_lrintf128:
3178 return RValue::get(V: emitMaybeConstrainedFPToIntRoundBuiltin(
3179 CGF&: *this, E, IntrinsicID: Intrinsic::lrint,
3180 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_lrint));
3181
3182 case Builtin::BIllrint:
3183 case Builtin::BIllrintf:
3184 case Builtin::BIllrintl:
3185 case Builtin::BI__builtin_llrint:
3186 case Builtin::BI__builtin_llrintf:
3187 case Builtin::BI__builtin_llrintl:
3188 case Builtin::BI__builtin_llrintf128:
3189 return RValue::get(V: emitMaybeConstrainedFPToIntRoundBuiltin(
3190 CGF&: *this, E, IntrinsicID: Intrinsic::llrint,
3191 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_llrint));
3192 case Builtin::BI__builtin_ldexp:
3193 case Builtin::BI__builtin_ldexpf:
3194 case Builtin::BI__builtin_ldexpl:
3195 case Builtin::BI__builtin_ldexpf16:
3196 case Builtin::BI__builtin_ldexpf128:
3197 case Builtin::BI__builtin_elementwise_ldexp:
3198 return RValue::get(V: emitBinaryExpMaybeConstrainedFPBuiltin(
3199 CGF&: *this, E, IntrinsicID: Intrinsic::ldexp,
3200 ConstrainedIntrinsicID: Intrinsic::experimental_constrained_ldexp));
3201 default:
3202 break;
3203 }
3204 }
3205
3206 // Check NonnullAttribute/NullabilityArg and Alignment.
3207 auto EmitArgCheck = [&](TypeCheckKind Kind, Address A, const Expr *Arg,
3208 unsigned ParmNum) {
3209 Value *Val = A.emitRawPointer(CGF&: *this);
3210 EmitNonNullArgCheck(RV: RValue::get(V: Val), ArgType: Arg->getType(), ArgLoc: Arg->getExprLoc(), AC: FD,
3211 ParmNum);
3212
3213 if (SanOpts.has(K: SanitizerKind::Alignment)) {
3214 SanitizerSet SkippedChecks;
3215 SkippedChecks.set(SanitizerKind::All);
3216 SkippedChecks.clear(K: SanitizerKind::Alignment);
3217 SourceLocation Loc = Arg->getExprLoc();
3218 // Strip an implicit cast.
3219 if (auto *CE = dyn_cast<ImplicitCastExpr>(Val: Arg))
3220 if (CE->getCastKind() == CK_BitCast)
3221 Arg = CE->getSubExpr();
3222 EmitTypeCheck(TCK: Kind, Loc, V: Val, Type: Arg->getType(), Alignment: A.getAlignment(),
3223 SkippedChecks);
3224 }
3225 };
3226
3227 switch (BuiltinIDIfNoAsmLabel) {
3228 default: break;
3229 case Builtin::BI__builtin___CFStringMakeConstantString:
3230 case Builtin::BI__builtin___NSStringMakeConstantString:
3231 return RValue::get(V: ConstantEmitter(*this).emitAbstract(E, T: E->getType()));
3232 case Builtin::BI__builtin_stdarg_start:
3233 case Builtin::BI__builtin_va_start:
3234 case Builtin::BI__va_start:
3235 case Builtin::BI__builtin_c23_va_start:
3236 case Builtin::BI__builtin_va_end:
3237 EmitVAStartEnd(ArgValue: BuiltinID == Builtin::BI__va_start
3238 ? EmitScalarExpr(E: E->getArg(Arg: 0))
3239 : EmitVAListRef(E: E->getArg(Arg: 0)).emitRawPointer(CGF&: *this),
3240 IsStart: BuiltinID != Builtin::BI__builtin_va_end);
3241 return RValue::get(V: nullptr);
3242 case Builtin::BI__builtin_va_copy: {
3243 Value *DstPtr = EmitVAListRef(E: E->getArg(Arg: 0)).emitRawPointer(CGF&: *this);
3244 Value *SrcPtr = EmitVAListRef(E: E->getArg(Arg: 1)).emitRawPointer(CGF&: *this);
3245 Builder.CreateCall(Callee: CGM.getIntrinsic(IID: Intrinsic::vacopy, Tys: {DstPtr->getType()}),
3246 Args: {DstPtr, SrcPtr});
3247 return RValue::get(V: nullptr);
3248 }
3249 case Builtin::BIabs:
3250 case Builtin::BIlabs:
3251 case Builtin::BIllabs:
3252 case Builtin::BI__builtin_abs:
3253 case Builtin::BI__builtin_labs:
3254 case Builtin::BI__builtin_llabs: {
3255 bool SanitizeOverflow = SanOpts.has(K: SanitizerKind::SignedIntegerOverflow);
3256
3257 Value *Result;
3258 switch (getLangOpts().getSignedOverflowBehavior()) {
3259 case LangOptions::SOB_Defined:
3260 Result = EmitAbs(CGF&: *this, ArgValue: EmitScalarExpr(E: E->getArg(Arg: 0)), HasNSW: false);
3261 break;
3262 case LangOptions::SOB_Undefined:
3263 if (!SanitizeOverflow) {
3264 Result = EmitAbs(CGF&: *this, ArgValue: EmitScalarExpr(E: E->getArg(Arg: 0)), HasNSW: true);
3265 break;
3266 }
3267 [[fallthrough]];
3268 case LangOptions::SOB_Trapping:
3269 // TODO: Somehow handle the corner case when the address of abs is taken.
3270 Result = EmitOverflowCheckedAbs(CGF&: *this, E, SanitizeOverflow);
3271 break;
3272 }
3273 return RValue::get(V: Result);
3274 }
3275 case Builtin::BI__builtin_complex: {
3276 Value *Real = EmitScalarExpr(E: E->getArg(Arg: 0));
3277 Value *Imag = EmitScalarExpr(E: E->getArg(Arg: 1));
3278 return RValue::getComplex(C: {Real, Imag});
3279 }
3280 case Builtin::BI__builtin_conj:
3281 case Builtin::BI__builtin_conjf:
3282 case Builtin::BI__builtin_conjl:
3283 case Builtin::BIconj:
3284 case Builtin::BIconjf:
3285 case Builtin::BIconjl: {
3286 ComplexPairTy ComplexVal = EmitComplexExpr(E: E->getArg(Arg: 0));
3287 Value *Real = ComplexVal.first;
3288 Value *Imag = ComplexVal.second;
3289 Imag = Builder.CreateFNeg(V: Imag, Name: "neg");
3290 return RValue::getComplex(C: std::make_pair(x&: Real, y&: Imag));
3291 }
3292 case Builtin::BI__builtin_creal:
3293 case Builtin::BI__builtin_crealf:
3294 case Builtin::BI__builtin_creall:
3295 case Builtin::BIcreal:
3296 case Builtin::BIcrealf:
3297 case Builtin::BIcreall: {
3298 ComplexPairTy ComplexVal = EmitComplexExpr(E: E->getArg(Arg: 0));
3299 return RValue::get(V: ComplexVal.first);
3300 }
3301
3302 case Builtin::BI__builtin_preserve_access_index: {
3303 // Only enabled preserved access index region when debuginfo
3304 // is available as debuginfo is needed to preserve user-level
3305 // access pattern.
3306 if (!getDebugInfo()) {
3307 CGM.Error(loc: E->getExprLoc(), error: "using builtin_preserve_access_index() without -g");
3308 return RValue::get(V: EmitScalarExpr(E: E->getArg(Arg: 0)));
3309 }
3310
3311 // Nested builtin_preserve_access_index() not supported
3312 if (IsInPreservedAIRegion) {
3313 CGM.Error(loc: E->getExprLoc(), error: "nested builtin_preserve_access_index() not supported");
3314 return RValue::get(V: EmitScalarExpr(E: E->getArg(Arg: 0)));
3315 }
3316
3317 IsInPreservedAIRegion = true;
3318 Value *Res = EmitScalarExpr(E: E->getArg(Arg: 0));
3319 IsInPreservedAIRegion = false;
3320 return RValue::get(V: Res);
3321 }
3322
3323 case Builtin::BI__builtin_cimag:
3324 case Builtin::BI__builtin_cimagf:
3325 case Builtin::BI__builtin_cimagl:
3326 case Builtin::BIcimag:
3327 case Builtin::BIcimagf:
3328 case Builtin::BIcimagl: {
3329 ComplexPairTy ComplexVal = EmitComplexExpr(E: E->getArg(Arg: 0));
3330 return RValue::get(V: ComplexVal.second);
3331 }
3332
3333 case Builtin::BI__builtin_clrsb:
3334 case Builtin::BI__builtin_clrsbl:
3335 case Builtin::BI__builtin_clrsbll: {
3336 // clrsb(x) -> clz(x < 0 ? ~x : x) - 1 or
3337 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3338
3339 llvm::Type *ArgType = ArgValue->getType();
3340 Function *F = CGM.getIntrinsic(IID: Intrinsic::ctlz, Tys: ArgType);
3341
3342 llvm::Type *ResultType = ConvertType(T: E->getType());
3343 Value *Zero = llvm::Constant::getNullValue(Ty: ArgType);
3344 Value *IsNeg = Builder.CreateICmpSLT(LHS: ArgValue, RHS: Zero, Name: "isneg");
3345 Value *Inverse = Builder.CreateNot(V: ArgValue, Name: "not");
3346 Value *Tmp = Builder.CreateSelect(C: IsNeg, True: Inverse, False: ArgValue);
3347 Value *Ctlz = Builder.CreateCall(Callee: F, Args: {Tmp, Builder.getFalse()});
3348 Value *Result =
3349 Builder.CreateNUWSub(LHS: Ctlz, RHS: llvm::ConstantInt::get(Ty: ArgType, V: 1));
3350 Result = Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/true,
3351 Name: "cast");
3352 return RValue::get(V: Result);
3353 }
3354 case Builtin::BI__builtin_ctzs:
3355 case Builtin::BI__builtin_ctz:
3356 case Builtin::BI__builtin_ctzl:
3357 case Builtin::BI__builtin_ctzll:
3358 case Builtin::BI__builtin_ctzg:
3359 case Builtin::BI__builtin_elementwise_ctzg: {
3360 bool HasFallback =
3361 (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_ctzg ||
3362 BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_elementwise_ctzg) &&
3363 E->getNumArgs() > 1;
3364
3365 Value *ArgValue =
3366 HasFallback ? EmitBitCountExpr(CGF&: *this, E: E->getArg(Arg: 0))
3367 : EmitCheckedArgForBuiltin(E: E->getArg(Arg: 0), Kind: BCK_CTZPassedZero);
3368
3369 llvm::Type *ArgType = ArgValue->getType();
3370 Function *F = CGM.getIntrinsic(IID: Intrinsic::cttz, Tys: ArgType);
3371
3372 llvm::Type *ResultType = ConvertType(T: E->getType());
3373 // The elementwise builtins always exhibit zero-is-undef behaviour
3374 Value *ZeroUndef = Builder.getInt1(
3375 V: HasFallback || getTarget().isCLZForZeroUndef() ||
3376 BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_elementwise_ctzg);
3377 Value *Result = Builder.CreateCall(Callee: F, Args: {ArgValue, ZeroUndef});
3378 if (Result->getType() != ResultType)
3379 Result =
3380 Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/ false, Name: "cast");
3381 if (!HasFallback)
3382 return RValue::get(V: Result);
3383
3384 Value *Zero = Constant::getNullValue(Ty: ArgType);
3385 Value *IsZero = Builder.CreateICmpEQ(LHS: ArgValue, RHS: Zero, Name: "iszero");
3386 Value *FallbackValue = EmitScalarExpr(E: E->getArg(Arg: 1));
3387 Value *ResultOrFallback =
3388 Builder.CreateSelect(C: IsZero, True: FallbackValue, False: Result, Name: "ctzg");
3389 return RValue::get(V: ResultOrFallback);
3390 }
3391 case Builtin::BI__builtin_clzs:
3392 case Builtin::BI__builtin_clz:
3393 case Builtin::BI__builtin_clzl:
3394 case Builtin::BI__builtin_clzll:
3395 case Builtin::BI__builtin_clzg:
3396 case Builtin::BI__builtin_elementwise_clzg: {
3397 bool HasFallback =
3398 (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_clzg ||
3399 BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_elementwise_clzg) &&
3400 E->getNumArgs() > 1;
3401
3402 Value *ArgValue =
3403 HasFallback ? EmitBitCountExpr(CGF&: *this, E: E->getArg(Arg: 0))
3404 : EmitCheckedArgForBuiltin(E: E->getArg(Arg: 0), Kind: BCK_CLZPassedZero);
3405
3406 llvm::Type *ArgType = ArgValue->getType();
3407 Function *F = CGM.getIntrinsic(IID: Intrinsic::ctlz, Tys: ArgType);
3408
3409 llvm::Type *ResultType = ConvertType(T: E->getType());
3410 // The elementwise builtins always exhibit zero-is-undef behaviour
3411 Value *ZeroUndef = Builder.getInt1(
3412 V: HasFallback || getTarget().isCLZForZeroUndef() ||
3413 BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_elementwise_clzg);
3414 Value *Result = Builder.CreateCall(Callee: F, Args: {ArgValue, ZeroUndef});
3415 if (Result->getType() != ResultType)
3416 Result =
3417 Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/ false, Name: "cast");
3418 if (!HasFallback)
3419 return RValue::get(V: Result);
3420
3421 Value *Zero = Constant::getNullValue(Ty: ArgType);
3422 Value *IsZero = Builder.CreateICmpEQ(LHS: ArgValue, RHS: Zero, Name: "iszero");
3423 Value *FallbackValue = EmitScalarExpr(E: E->getArg(Arg: 1));
3424 Value *ResultOrFallback =
3425 Builder.CreateSelect(C: IsZero, True: FallbackValue, False: Result, Name: "clzg");
3426 return RValue::get(V: ResultOrFallback);
3427 }
3428 case Builtin::BI__builtin_ffs:
3429 case Builtin::BI__builtin_ffsl:
3430 case Builtin::BI__builtin_ffsll: {
3431 // ffs(x) -> x ? cttz(x) + 1 : 0
3432 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3433
3434 llvm::Type *ArgType = ArgValue->getType();
3435 Function *F = CGM.getIntrinsic(IID: Intrinsic::cttz, Tys: ArgType);
3436
3437 llvm::Type *ResultType = ConvertType(T: E->getType());
3438 Value *Tmp =
3439 Builder.CreateAdd(LHS: Builder.CreateCall(Callee: F, Args: {ArgValue, Builder.getTrue()}),
3440 RHS: llvm::ConstantInt::get(Ty: ArgType, V: 1));
3441 Value *Zero = llvm::Constant::getNullValue(Ty: ArgType);
3442 Value *IsZero = Builder.CreateICmpEQ(LHS: ArgValue, RHS: Zero, Name: "iszero");
3443 Value *Result = Builder.CreateSelect(C: IsZero, True: Zero, False: Tmp, Name: "ffs");
3444 if (Result->getType() != ResultType)
3445 Result = Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/true,
3446 Name: "cast");
3447 return RValue::get(V: Result);
3448 }
3449 case Builtin::BI__builtin_parity:
3450 case Builtin::BI__builtin_parityl:
3451 case Builtin::BI__builtin_parityll: {
3452 // parity(x) -> ctpop(x) & 1
3453 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3454
3455 llvm::Type *ArgType = ArgValue->getType();
3456 Function *F = CGM.getIntrinsic(IID: Intrinsic::ctpop, Tys: ArgType);
3457
3458 llvm::Type *ResultType = ConvertType(T: E->getType());
3459 Value *Tmp = Builder.CreateCall(Callee: F, Args: ArgValue);
3460 Value *Result = Builder.CreateAnd(LHS: Tmp, RHS: llvm::ConstantInt::get(Ty: ArgType, V: 1));
3461 if (Result->getType() != ResultType)
3462 Result = Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/true,
3463 Name: "cast");
3464 return RValue::get(V: Result);
3465 }
3466 case Builtin::BI__lzcnt16:
3467 case Builtin::BI__lzcnt:
3468 case Builtin::BI__lzcnt64: {
3469 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3470
3471 llvm::Type *ArgType = ArgValue->getType();
3472 Function *F = CGM.getIntrinsic(IID: Intrinsic::ctlz, Tys: ArgType);
3473
3474 llvm::Type *ResultType = ConvertType(T: E->getType());
3475 Value *Result = Builder.CreateCall(Callee: F, Args: {ArgValue, Builder.getFalse()});
3476 if (Result->getType() != ResultType)
3477 Result = Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/true,
3478 Name: "cast");
3479 return RValue::get(V: Result);
3480 }
3481 case Builtin::BI__popcnt16:
3482 case Builtin::BI__popcnt:
3483 case Builtin::BI__popcnt64:
3484 case Builtin::BI__builtin_popcount:
3485 case Builtin::BI__builtin_popcountl:
3486 case Builtin::BI__builtin_popcountll:
3487 case Builtin::BI__builtin_popcountg: {
3488 Value *ArgValue = EmitBitCountExpr(CGF&: *this, E: E->getArg(Arg: 0));
3489
3490 llvm::Type *ArgType = ArgValue->getType();
3491 Function *F = CGM.getIntrinsic(IID: Intrinsic::ctpop, Tys: ArgType);
3492
3493 llvm::Type *ResultType = ConvertType(T: E->getType());
3494 Value *Result = Builder.CreateCall(Callee: F, Args: ArgValue);
3495 if (Result->getType() != ResultType)
3496 Result =
3497 Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/ false, Name: "cast");
3498 return RValue::get(V: Result);
3499 }
3500 case Builtin::BI__builtin_unpredictable: {
3501 // Always return the argument of __builtin_unpredictable. LLVM does not
3502 // handle this builtin. Metadata for this builtin should be added directly
3503 // to instructions such as branches or switches that use it.
3504 return RValue::get(V: EmitScalarExpr(E: E->getArg(Arg: 0)));
3505 }
3506 case Builtin::BI__builtin_expect: {
3507 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3508 llvm::Type *ArgType = ArgValue->getType();
3509
3510 Value *ExpectedValue = EmitScalarExpr(E: E->getArg(Arg: 1));
3511 // Don't generate llvm.expect on -O0 as the backend won't use it for
3512 // anything.
3513 // Note, we still IRGen ExpectedValue because it could have side-effects.
3514 if (CGM.getCodeGenOpts().OptimizationLevel == 0)
3515 return RValue::get(V: ArgValue);
3516
3517 Function *FnExpect = CGM.getIntrinsic(IID: Intrinsic::expect, Tys: ArgType);
3518 Value *Result =
3519 Builder.CreateCall(Callee: FnExpect, Args: {ArgValue, ExpectedValue}, Name: "expval");
3520 return RValue::get(V: Result);
3521 }
3522 case Builtin::BI__builtin_expect_with_probability: {
3523 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3524 llvm::Type *ArgType = ArgValue->getType();
3525
3526 Value *ExpectedValue = EmitScalarExpr(E: E->getArg(Arg: 1));
3527 llvm::APFloat Probability(0.0);
3528 const Expr *ProbArg = E->getArg(Arg: 2);
3529 bool EvalSucceed = ProbArg->EvaluateAsFloat(Result&: Probability, Ctx: CGM.getContext());
3530 assert(EvalSucceed && "probability should be able to evaluate as float");
3531 (void)EvalSucceed;
3532 bool LoseInfo = false;
3533 Probability.convert(ToSemantics: llvm::APFloat::IEEEdouble(),
3534 RM: llvm::RoundingMode::Dynamic, losesInfo: &LoseInfo);
3535 llvm::Type *Ty = ConvertType(T: ProbArg->getType());
3536 Constant *Confidence = ConstantFP::get(Ty, V: Probability);
3537 // Don't generate llvm.expect.with.probability on -O0 as the backend
3538 // won't use it for anything.
3539 // Note, we still IRGen ExpectedValue because it could have side-effects.
3540 if (CGM.getCodeGenOpts().OptimizationLevel == 0)
3541 return RValue::get(V: ArgValue);
3542
3543 Function *FnExpect =
3544 CGM.getIntrinsic(IID: Intrinsic::expect_with_probability, Tys: ArgType);
3545 Value *Result = Builder.CreateCall(
3546 Callee: FnExpect, Args: {ArgValue, ExpectedValue, Confidence}, Name: "expval");
3547 return RValue::get(V: Result);
3548 }
3549 case Builtin::BI__builtin_assume_aligned: {
3550 const Expr *Ptr = E->getArg(Arg: 0);
3551 Value *PtrValue = EmitScalarExpr(E: Ptr);
3552 Value *OffsetValue =
3553 (E->getNumArgs() > 2) ? EmitScalarExpr(E: E->getArg(Arg: 2)) : nullptr;
3554
3555 Value *AlignmentValue = EmitScalarExpr(E: E->getArg(Arg: 1));
3556 ConstantInt *AlignmentCI = cast<ConstantInt>(Val: AlignmentValue);
3557 if (AlignmentCI->getValue().ugt(RHS: llvm::Value::MaximumAlignment))
3558 AlignmentCI = ConstantInt::get(Ty: AlignmentCI->getIntegerType(),
3559 V: llvm::Value::MaximumAlignment);
3560
3561 emitAlignmentAssumption(PtrValue, E: Ptr,
3562 /*The expr loc is sufficient.*/ AssumptionLoc: SourceLocation(),
3563 Alignment: AlignmentCI, OffsetValue);
3564 return RValue::get(V: PtrValue);
3565 }
3566 case Builtin::BI__builtin_assume_dereferenceable: {
3567 const Expr *Ptr = E->getArg(Arg: 0);
3568 const Expr *Size = E->getArg(Arg: 1);
3569 Value *PtrValue = EmitScalarExpr(E: Ptr);
3570 Value *SizeValue = EmitScalarExpr(E: Size);
3571 if (SizeValue->getType() != IntPtrTy)
3572 SizeValue =
3573 Builder.CreateIntCast(V: SizeValue, DestTy: IntPtrTy, isSigned: false, Name: "casted.size");
3574 Builder.CreateDereferenceableAssumption(PtrValue, SizeValue);
3575 return RValue::get(V: nullptr);
3576 }
3577 case Builtin::BI__assume:
3578 case Builtin::BI__builtin_assume: {
3579 if (E->getArg(Arg: 0)->HasSideEffects(Ctx: getContext()))
3580 return RValue::get(V: nullptr);
3581
3582 Value *ArgValue = EmitCheckedArgForAssume(E: E->getArg(Arg: 0));
3583 Function *FnAssume = CGM.getIntrinsic(IID: Intrinsic::assume);
3584 Builder.CreateCall(Callee: FnAssume, Args: ArgValue);
3585 return RValue::get(V: nullptr);
3586 }
3587 case Builtin::BI__builtin_assume_separate_storage: {
3588 const Expr *Arg0 = E->getArg(Arg: 0);
3589 const Expr *Arg1 = E->getArg(Arg: 1);
3590
3591 Value *Value0 = EmitScalarExpr(E: Arg0);
3592 Value *Value1 = EmitScalarExpr(E: Arg1);
3593
3594 Value *Values[] = {Value0, Value1};
3595 OperandBundleDefT<Value *> OBD("separate_storage", Values);
3596 Builder.CreateAssumption(Cond: ConstantInt::getTrue(Context&: getLLVMContext()), OpBundles: {OBD});
3597 return RValue::get(V: nullptr);
3598 }
3599 case Builtin::BI__builtin_allow_runtime_check: {
3600 StringRef Kind =
3601 cast<StringLiteral>(Val: E->getArg(Arg: 0)->IgnoreParenCasts())->getString();
3602 LLVMContext &Ctx = CGM.getLLVMContext();
3603 llvm::Value *Allow = Builder.CreateCall(
3604 Callee: CGM.getIntrinsic(IID: Intrinsic::allow_runtime_check),
3605 Args: llvm::MetadataAsValue::get(Context&: Ctx, MD: llvm::MDString::get(Context&: Ctx, Str: Kind)));
3606 return RValue::get(V: Allow);
3607 }
3608 case Builtin::BI__builtin_allow_sanitize_check: {
3609 Intrinsic::ID IntrID = Intrinsic::not_intrinsic;
3610 StringRef Name =
3611 cast<StringLiteral>(Val: E->getArg(Arg: 0)->IgnoreParenCasts())->getString();
3612
3613 // We deliberately allow the use of kernel- and non-kernel names
3614 // interchangably, even when one or the other is enabled. This is consistent
3615 // with the no_sanitize-attribute, which allows either kernel- or non-kernel
3616 // name to disable instrumentation (see CodeGenFunction::StartFunction).
3617 if (getLangOpts().Sanitize.hasOneOf(K: SanitizerKind::Address |
3618 SanitizerKind::KernelAddress) &&
3619 (Name == "address" || Name == "kernel-address")) {
3620 IntrID = Intrinsic::allow_sanitize_address;
3621 } else if (getLangOpts().Sanitize.has(K: SanitizerKind::Thread) &&
3622 Name == "thread") {
3623 IntrID = Intrinsic::allow_sanitize_thread;
3624 } else if (getLangOpts().Sanitize.hasOneOf(K: SanitizerKind::Memory |
3625 SanitizerKind::KernelMemory) &&
3626 (Name == "memory" || Name == "kernel-memory")) {
3627 IntrID = Intrinsic::allow_sanitize_memory;
3628 } else if (getLangOpts().Sanitize.hasOneOf(
3629 K: SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress) &&
3630 (Name == "hwaddress" || Name == "kernel-hwaddress")) {
3631 IntrID = Intrinsic::allow_sanitize_hwaddress;
3632 }
3633
3634 if (IntrID != Intrinsic::not_intrinsic) {
3635 llvm::Value *Allow = Builder.CreateCall(Callee: CGM.getIntrinsic(IID: IntrID));
3636 return RValue::get(V: Allow);
3637 }
3638 // If the checked sanitizer is not enabled, we can safely lower to false
3639 // right away. This is also more efficient, since the LowerAllowCheckPass
3640 // must not always be enabled if none of the above sanitizers are enabled.
3641 return RValue::get(V: Builder.getFalse());
3642 }
3643 case Builtin::BI__arithmetic_fence: {
3644 // Create the builtin call if FastMath is selected, and the target
3645 // supports the builtin, otherwise just return the argument.
3646 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3647 llvm::FastMathFlags FMF = Builder.getFastMathFlags();
3648 bool isArithmeticFenceEnabled =
3649 FMF.allowReassoc() &&
3650 getContext().getTargetInfo().checkArithmeticFenceSupported();
3651 QualType ArgType = E->getArg(Arg: 0)->getType();
3652 if (ArgType->isComplexType()) {
3653 if (isArithmeticFenceEnabled) {
3654 QualType ElementType = ArgType->castAs<ComplexType>()->getElementType();
3655 ComplexPairTy ComplexVal = EmitComplexExpr(E: E->getArg(Arg: 0));
3656 Value *Real = Builder.CreateArithmeticFence(Val: ComplexVal.first,
3657 DstType: ConvertType(T: ElementType));
3658 Value *Imag = Builder.CreateArithmeticFence(Val: ComplexVal.second,
3659 DstType: ConvertType(T: ElementType));
3660 return RValue::getComplex(C: std::make_pair(x&: Real, y&: Imag));
3661 }
3662 ComplexPairTy ComplexVal = EmitComplexExpr(E: E->getArg(Arg: 0));
3663 Value *Real = ComplexVal.first;
3664 Value *Imag = ComplexVal.second;
3665 return RValue::getComplex(C: std::make_pair(x&: Real, y&: Imag));
3666 }
3667 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3668 if (isArithmeticFenceEnabled)
3669 return RValue::get(
3670 V: Builder.CreateArithmeticFence(Val: ArgValue, DstType: ConvertType(T: ArgType)));
3671 return RValue::get(V: ArgValue);
3672 }
3673 case Builtin::BI__builtin_bswapg: {
3674 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3675 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Val: ArgValue->getType());
3676 assert(IntTy && "LLVM's __builtin_bswapg only supports integer variants");
3677 if (IntTy->getBitWidth() == 1 || IntTy->getBitWidth() == 8)
3678 return RValue::get(V: ArgValue);
3679 assert(((IntTy->getBitWidth() % 16 == 0 && IntTy->getBitWidth() != 0)) &&
3680 "LLVM's __builtin_bswapg only supports integer variants that has a "
3681 "multiple of 16 bits as well as a single byte");
3682 return RValue::get(
3683 V: emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::bswap));
3684 }
3685 case Builtin::BI__builtin_bswap16:
3686 case Builtin::BI__builtin_bswap32:
3687 case Builtin::BI__builtin_bswap64:
3688 case Builtin::BI_byteswap_ushort:
3689 case Builtin::BI_byteswap_ulong:
3690 case Builtin::BI_byteswap_uint64: {
3691 return RValue::get(
3692 V: emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::bswap));
3693 }
3694 case Builtin::BI__builtin_bitreverseg: {
3695 Value *ArgValue = EmitScalarExpr(E: E->getArg(Arg: 0));
3696 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Val: ArgValue->getType());
3697 assert(IntTy &&
3698 "LLVM's __builtin_bitreverseg only support integer variants");
3699 if (IntTy->getBitWidth() == 1)
3700 return RValue::get(V: ArgValue);
3701 return RValue::get(
3702 V: emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::bitreverse));
3703 }
3704 case Builtin::BI__builtin_bitreverse8:
3705 case Builtin::BI__builtin_bitreverse16:
3706 case Builtin::BI__builtin_bitreverse32:
3707 case Builtin::BI__builtin_bitreverse64: {
3708 return RValue::get(
3709 V: emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::bitreverse));
3710 }
3711 case Builtin::BI__builtin_rotateleft8:
3712 case Builtin::BI__builtin_rotateleft16:
3713 case Builtin::BI__builtin_rotateleft32:
3714 case Builtin::BI__builtin_rotateleft64:
3715 case Builtin::BI__builtin_stdc_rotate_left:
3716 case Builtin::BI_rotl8: // Microsoft variants of rotate left
3717 case Builtin::BI_rotl16:
3718 case Builtin::BI_rotl:
3719 case Builtin::BI_lrotl:
3720 case Builtin::BI_rotl64:
3721 return emitRotate(E, IsRotateRight: false);
3722
3723 case Builtin::BI__builtin_rotateright8:
3724 case Builtin::BI__builtin_rotateright16:
3725 case Builtin::BI__builtin_rotateright32:
3726 case Builtin::BI__builtin_rotateright64:
3727 case Builtin::BI__builtin_stdc_rotate_right:
3728 case Builtin::BI_rotr8: // Microsoft variants of rotate right
3729 case Builtin::BI_rotr16:
3730 case Builtin::BI_rotr:
3731 case Builtin::BI_lrotr:
3732 case Builtin::BI_rotr64:
3733 return emitRotate(E, IsRotateRight: true);
3734
3735 case Builtin::BI__builtin_constant_p: {
3736 llvm::Type *ResultType = ConvertType(T: E->getType());
3737
3738 const Expr *Arg = E->getArg(Arg: 0);
3739 QualType ArgType = Arg->getType();
3740 // FIXME: The allowance for Obj-C pointers and block pointers is historical
3741 // and likely a mistake.
3742 if (!ArgType->isIntegralOrEnumerationType() && !ArgType->isFloatingType() &&
3743 !ArgType->isObjCObjectPointerType() && !ArgType->isBlockPointerType())
3744 // Per the GCC documentation, only numeric constants are recognized after
3745 // inlining.
3746 return RValue::get(V: ConstantInt::get(Ty: ResultType, V: 0));
3747
3748 if (Arg->HasSideEffects(Ctx: getContext()))
3749 // The argument is unevaluated, so be conservative if it might have
3750 // side-effects.
3751 return RValue::get(V: ConstantInt::get(Ty: ResultType, V: 0));
3752
3753 Value *ArgValue = EmitScalarExpr(E: Arg);
3754 if (ArgType->isObjCObjectPointerType()) {
3755 // Convert Objective-C objects to id because we cannot distinguish between
3756 // LLVM types for Obj-C classes as they are opaque.
3757 ArgType = CGM.getContext().getObjCIdType();
3758 ArgValue = Builder.CreateBitCast(V: ArgValue, DestTy: ConvertType(T: ArgType));
3759 }
3760 Function *F =
3761 CGM.getIntrinsic(IID: Intrinsic::is_constant, Tys: ConvertType(T: ArgType));
3762 Value *Result = Builder.CreateCall(Callee: F, Args: ArgValue);
3763 if (Result->getType() != ResultType)
3764 Result = Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/false);
3765 return RValue::get(V: Result);
3766 }
3767 case Builtin::BI__builtin_dynamic_object_size:
3768 case Builtin::BI__builtin_object_size: {
3769 unsigned Type =
3770 E->getArg(Arg: 1)->EvaluateKnownConstInt(Ctx: getContext()).getZExtValue();
3771 auto *ResType = cast<llvm::IntegerType>(Val: ConvertType(T: E->getType()));
3772
3773 // We pass this builtin onto the optimizer so that it can figure out the
3774 // object size in more complex cases.
3775 bool IsDynamic = BuiltinID == Builtin::BI__builtin_dynamic_object_size;
3776 return RValue::get(V: emitBuiltinObjectSize(E: E->getArg(Arg: 0), Type, ResType,
3777 /*EmittedE=*/nullptr, IsDynamic));
3778 }
3779 case Builtin::BI__builtin_counted_by_ref: {
3780 // Default to returning '(void *) 0'.
3781 llvm::Value *Result = llvm::ConstantPointerNull::get(
3782 T: llvm::PointerType::getUnqual(C&: getLLVMContext()));
3783
3784 const Expr *Arg = E->getArg(Arg: 0)->IgnoreParenImpCasts();
3785
3786 if (auto *UO = dyn_cast<UnaryOperator>(Val: Arg);
3787 UO && UO->getOpcode() == UO_AddrOf) {
3788 Arg = UO->getSubExpr()->IgnoreParenImpCasts();
3789
3790 if (auto *ASE = dyn_cast<ArraySubscriptExpr>(Val: Arg))
3791 Arg = ASE->getBase()->IgnoreParenImpCasts();
3792 }
3793
3794 if (const MemberExpr *ME = dyn_cast_if_present<MemberExpr>(Val: Arg)) {
3795 if (auto *CATy =
3796 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
3797 CATy && CATy->getKind() == CountAttributedType::CountedBy) {
3798 const auto *MemberDecl = cast<FieldDecl>(Val: ME->getMemberDecl());
3799 if (const FieldDecl *CountFD = MemberDecl->findCountedByField())
3800 Result = GetCountedByFieldExprGEP(Base: Arg, FD: MemberDecl, CountDecl: CountFD);
3801 else
3802 llvm::report_fatal_error(reason: "Cannot find the counted_by 'count' field");
3803 }
3804 }
3805
3806 return RValue::get(V: Result);
3807 }
3808 case Builtin::BI__builtin_prefetch: {
3809 Value *Locality, *RW, *Address = EmitScalarExpr(E: E->getArg(Arg: 0));
3810 // FIXME: Technically these constants should of type 'int', yes?
3811 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E: E->getArg(Arg: 1)) :
3812 llvm::ConstantInt::get(Ty: Int32Ty, V: 0);
3813 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E: E->getArg(Arg: 2)) :
3814 llvm::ConstantInt::get(Ty: Int32Ty, V: 3);
3815 Value *Data = llvm::ConstantInt::get(Ty: Int32Ty, V: 1);
3816 Function *F = CGM.getIntrinsic(IID: Intrinsic::prefetch, Tys: Address->getType());
3817 Builder.CreateCall(Callee: F, Args: {Address, RW, Locality, Data});
3818 return RValue::get(V: nullptr);
3819 }
3820 case Builtin::BI__builtin_readcyclecounter: {
3821 Function *F = CGM.getIntrinsic(IID: Intrinsic::readcyclecounter);
3822 return RValue::get(V: Builder.CreateCall(Callee: F));
3823 }
3824 case Builtin::BI__builtin_readsteadycounter: {
3825 Function *F = CGM.getIntrinsic(IID: Intrinsic::readsteadycounter);
3826 return RValue::get(V: Builder.CreateCall(Callee: F));
3827 }
3828 case Builtin::BI__builtin___clear_cache: {
3829 Value *Begin = EmitScalarExpr(E: E->getArg(Arg: 0));
3830 Value *End = EmitScalarExpr(E: E->getArg(Arg: 1));
3831 Function *F = CGM.getIntrinsic(IID: Intrinsic::clear_cache);
3832 return RValue::get(V: Builder.CreateCall(Callee: F, Args: {Begin, End}));
3833 }
3834 case Builtin::BI__builtin_trap:
3835 EmitTrapCall(IntrID: Intrinsic::trap);
3836 return RValue::get(V: nullptr);
3837 case Builtin::BI__builtin_verbose_trap: {
3838 llvm::DILocation *TrapLocation = Builder.getCurrentDebugLocation();
3839 if (getDebugInfo()) {
3840 TrapLocation = getDebugInfo()->CreateTrapFailureMessageFor(
3841 TrapLocation, Category: *E->getArg(Arg: 0)->tryEvaluateString(Ctx&: getContext()),
3842 FailureMsg: *E->getArg(Arg: 1)->tryEvaluateString(Ctx&: getContext()));
3843 }
3844 ApplyDebugLocation ApplyTrapDI(*this, TrapLocation);
3845 // Currently no attempt is made to prevent traps from being merged.
3846 EmitTrapCall(IntrID: Intrinsic::trap);
3847 return RValue::get(V: nullptr);
3848 }
3849 case Builtin::BI__debugbreak:
3850 EmitTrapCall(IntrID: Intrinsic::debugtrap);
3851 return RValue::get(V: nullptr);
3852 case Builtin::BI__builtin_unreachable: {
3853 EmitUnreachable(Loc: E->getExprLoc());
3854
3855 // We do need to preserve an insertion point.
3856 EmitBlock(BB: createBasicBlock(name: "unreachable.cont"));
3857
3858 return RValue::get(V: nullptr);
3859 }
3860
3861 case Builtin::BI__builtin_powi:
3862 case Builtin::BI__builtin_powif:
3863 case Builtin::BI__builtin_powil: {
3864 llvm::Value *Src0 = EmitScalarExpr(E: E->getArg(Arg: 0));
3865 llvm::Value *Src1 = EmitScalarExpr(E: E->getArg(Arg: 1));
3866
3867 if (Builder.getIsFPConstrained()) {
3868 // FIXME: llvm.powi has 2 mangling types,
3869 // llvm.experimental.constrained.powi has one.
3870 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3871 Function *F = CGM.getIntrinsic(IID: Intrinsic::experimental_constrained_powi,
3872 Tys: Src0->getType());
3873 return RValue::get(V: Builder.CreateConstrainedFPCall(Callee: F, Args: { Src0, Src1 }));
3874 }
3875
3876 Function *F = CGM.getIntrinsic(IID: Intrinsic::powi,
3877 Tys: { Src0->getType(), Src1->getType() });
3878 return RValue::get(V: Builder.CreateCall(Callee: F, Args: { Src0, Src1 }));
3879 }
3880 case Builtin::BI__builtin_frexpl: {
3881 // Linux PPC will not be adding additional PPCDoubleDouble support.
3882 // WIP to switch default to IEEE long double. Will emit libcall for
3883 // frexpl instead of legalizing this type in the BE.
3884 if (&getTarget().getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble())
3885 break;
3886 [[fallthrough]];
3887 }
3888 case Builtin::BI__builtin_frexp:
3889 case Builtin::BI__builtin_frexpf:
3890 case Builtin::BI__builtin_frexpf128:
3891 case Builtin::BI__builtin_frexpf16:
3892 return RValue::get(V: emitFrexpBuiltin(CGF&: *this, E, IntrinsicID: Intrinsic::frexp));
3893 case Builtin::BImodf:
3894 case Builtin::BImodff:
3895 case Builtin::BImodfl:
3896 case Builtin::BI__builtin_modf:
3897 case Builtin::BI__builtin_modff:
3898 case Builtin::BI__builtin_modfl:
3899 if (Builder.getIsFPConstrained())
3900 break; // TODO: Emit constrained modf intrinsic once one exists.
3901 return RValue::get(V: emitModfBuiltin(CGF&: *this, E, IntrinsicID: Intrinsic::modf));
3902 case Builtin::BI__builtin_isgreater:
3903 case Builtin::BI__builtin_isgreaterequal:
3904 case Builtin::BI__builtin_isless:
3905 case Builtin::BI__builtin_islessequal:
3906 case Builtin::BI__builtin_islessgreater:
3907 case Builtin::BI__builtin_isunordered: {
3908 // Ordered comparisons: we know the arguments to these are matching scalar
3909 // floating point values.
3910 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3911 Value *LHS = EmitScalarExpr(E: E->getArg(Arg: 0));
3912 Value *RHS = EmitScalarExpr(E: E->getArg(Arg: 1));
3913
3914 switch (BuiltinID) {
3915 default: llvm_unreachable("Unknown ordered comparison");
3916 case Builtin::BI__builtin_isgreater:
3917 LHS = Builder.CreateFCmpOGT(LHS, RHS, Name: "cmp");
3918 break;
3919 case Builtin::BI__builtin_isgreaterequal:
3920 LHS = Builder.CreateFCmpOGE(LHS, RHS, Name: "cmp");
3921 break;
3922 case Builtin::BI__builtin_isless:
3923 LHS = Builder.CreateFCmpOLT(LHS, RHS, Name: "cmp");
3924 break;
3925 case Builtin::BI__builtin_islessequal:
3926 LHS = Builder.CreateFCmpOLE(LHS, RHS, Name: "cmp");
3927 break;
3928 case Builtin::BI__builtin_islessgreater:
3929 LHS = Builder.CreateFCmpONE(LHS, RHS, Name: "cmp");
3930 break;
3931 case Builtin::BI__builtin_isunordered:
3932 LHS = Builder.CreateFCmpUNO(LHS, RHS, Name: "cmp");
3933 break;
3934 }
3935 // ZExt bool to int type.
3936 return RValue::get(V: Builder.CreateZExt(V: LHS, DestTy: ConvertType(T: E->getType())));
3937 }
3938
3939 case Builtin::BI__builtin_isnan: {
3940 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3941 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
3942 if (Value *Result = tryUseTestFPKind(CGF&: *this, BuiltinID, V))
3943 return RValue::get(V: Result);
3944 return RValue::get(
3945 V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test: FPClassTest::fcNan),
3946 DestTy: ConvertType(T: E->getType())));
3947 }
3948
3949 case Builtin::BI__builtin_issignaling: {
3950 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3951 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
3952 return RValue::get(
3953 V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test: FPClassTest::fcSNan),
3954 DestTy: ConvertType(T: E->getType())));
3955 }
3956
3957 case Builtin::BI__builtin_isinf: {
3958 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3959 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
3960 if (Value *Result = tryUseTestFPKind(CGF&: *this, BuiltinID, V))
3961 return RValue::get(V: Result);
3962 return RValue::get(
3963 V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test: FPClassTest::fcInf),
3964 DestTy: ConvertType(T: E->getType())));
3965 }
3966
3967 case Builtin::BIfinite:
3968 case Builtin::BI__finite:
3969 case Builtin::BIfinitef:
3970 case Builtin::BI__finitef:
3971 case Builtin::BIfinitel:
3972 case Builtin::BI__finitel:
3973 case Builtin::BI__builtin_isfinite: {
3974 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3975 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
3976 if (Value *Result = tryUseTestFPKind(CGF&: *this, BuiltinID, V))
3977 return RValue::get(V: Result);
3978 return RValue::get(
3979 V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test: FPClassTest::fcFinite),
3980 DestTy: ConvertType(T: E->getType())));
3981 }
3982
3983 case Builtin::BI__builtin_isnormal: {
3984 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3985 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
3986 return RValue::get(
3987 V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test: FPClassTest::fcNormal),
3988 DestTy: ConvertType(T: E->getType())));
3989 }
3990
3991 case Builtin::BI__builtin_issubnormal: {
3992 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
3993 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
3994 return RValue::get(
3995 V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test: FPClassTest::fcSubnormal),
3996 DestTy: ConvertType(T: E->getType())));
3997 }
3998
3999 case Builtin::BI__builtin_iszero: {
4000 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
4001 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
4002 return RValue::get(
4003 V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test: FPClassTest::fcZero),
4004 DestTy: ConvertType(T: E->getType())));
4005 }
4006
4007 case Builtin::BI__builtin_isfpclass: {
4008 Expr::EvalResult Result;
4009 if (!E->getArg(Arg: 1)->EvaluateAsInt(Result, Ctx: CGM.getContext()))
4010 break;
4011 uint64_t Test = Result.Val.getInt().getLimitedValue();
4012 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
4013 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
4014 return RValue::get(V: Builder.CreateZExt(V: Builder.createIsFPClass(FPNum: V, Test),
4015 DestTy: ConvertType(T: E->getType())));
4016 }
4017
4018 case Builtin::BI__builtin_nondeterministic_value: {
4019 llvm::Type *Ty = ConvertType(T: E->getArg(Arg: 0)->getType());
4020
4021 Value *Result = PoisonValue::get(T: Ty);
4022 Result = Builder.CreateFreeze(V: Result);
4023
4024 return RValue::get(V: Result);
4025 }
4026
4027 case Builtin::BI__builtin_elementwise_abs: {
4028 Value *Result;
4029 QualType QT = E->getArg(Arg: 0)->getType();
4030
4031 if (auto *VecTy = QT->getAs<VectorType>())
4032 QT = VecTy->getElementType();
4033 if (QT->isIntegerType())
4034 Result = Builder.CreateBinaryIntrinsic(
4035 ID: Intrinsic::abs, LHS: EmitScalarExpr(E: E->getArg(Arg: 0)), RHS: Builder.getFalse(),
4036 FMFSource: nullptr, Name: "elt.abs");
4037 else
4038 Result = emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::fabs,
4039 Name: "elt.abs");
4040
4041 return RValue::get(V: Result);
4042 }
4043 case Builtin::BI__builtin_elementwise_bitreverse:
4044 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4045 CGF&: *this, E, IntrinsicID: Intrinsic::bitreverse, Name: "elt.bitreverse"));
4046 case Builtin::BI__builtin_elementwise_popcount:
4047 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4048 CGF&: *this, E, IntrinsicID: Intrinsic::ctpop, Name: "elt.ctpop"));
4049 case Builtin::BI__builtin_elementwise_canonicalize:
4050 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4051 CGF&: *this, E, IntrinsicID: Intrinsic::canonicalize, Name: "elt.canonicalize"));
4052 case Builtin::BI__builtin_elementwise_copysign:
4053 return RValue::get(
4054 V: emitBuiltinWithOneOverloadedType<2>(CGF&: *this, E, IntrinsicID: Intrinsic::copysign));
4055 case Builtin::BI__builtin_elementwise_fshl:
4056 return RValue::get(
4057 V: emitBuiltinWithOneOverloadedType<3>(CGF&: *this, E, IntrinsicID: Intrinsic::fshl));
4058 case Builtin::BI__builtin_elementwise_fshr:
4059 return RValue::get(
4060 V: emitBuiltinWithOneOverloadedType<3>(CGF&: *this, E, IntrinsicID: Intrinsic::fshr));
4061
4062 case Builtin::BI__builtin_elementwise_add_sat:
4063 case Builtin::BI__builtin_elementwise_sub_sat: {
4064 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4065 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4066 Value *Result;
4067 assert(Op0->getType()->isIntOrIntVectorTy() && "integer type expected");
4068 QualType Ty = E->getArg(Arg: 0)->getType();
4069 if (auto *VecTy = Ty->getAs<VectorType>())
4070 Ty = VecTy->getElementType();
4071 bool IsSigned = Ty->isSignedIntegerType();
4072 unsigned Opc;
4073 if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_elementwise_add_sat)
4074 Opc = IsSigned ? Intrinsic::sadd_sat : Intrinsic::uadd_sat;
4075 else
4076 Opc = IsSigned ? Intrinsic::ssub_sat : Intrinsic::usub_sat;
4077 Result = Builder.CreateBinaryIntrinsic(ID: Opc, LHS: Op0, RHS: Op1, FMFSource: nullptr, Name: "elt.sat");
4078 return RValue::get(V: Result);
4079 }
4080
4081 case Builtin::BI__builtin_elementwise_max: {
4082 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4083 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4084 Value *Result;
4085 if (Op0->getType()->isIntOrIntVectorTy()) {
4086 QualType Ty = E->getArg(Arg: 0)->getType();
4087 if (auto *VecTy = Ty->getAs<VectorType>())
4088 Ty = VecTy->getElementType();
4089 Result = Builder.CreateBinaryIntrinsic(
4090 ID: Ty->isSignedIntegerType() ? Intrinsic::smax : Intrinsic::umax, LHS: Op0,
4091 RHS: Op1, FMFSource: nullptr, Name: "elt.max");
4092 } else
4093 Result = Builder.CreateMaxNum(LHS: Op0, RHS: Op1, /*FMFSource=*/nullptr, Name: "elt.max");
4094 return RValue::get(V: Result);
4095 }
4096 case Builtin::BI__builtin_elementwise_min: {
4097 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4098 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4099 Value *Result;
4100 if (Op0->getType()->isIntOrIntVectorTy()) {
4101 QualType Ty = E->getArg(Arg: 0)->getType();
4102 if (auto *VecTy = Ty->getAs<VectorType>())
4103 Ty = VecTy->getElementType();
4104 Result = Builder.CreateBinaryIntrinsic(
4105 ID: Ty->isSignedIntegerType() ? Intrinsic::smin : Intrinsic::umin, LHS: Op0,
4106 RHS: Op1, FMFSource: nullptr, Name: "elt.min");
4107 } else
4108 Result = Builder.CreateMinNum(LHS: Op0, RHS: Op1, /*FMFSource=*/nullptr, Name: "elt.min");
4109 return RValue::get(V: Result);
4110 }
4111
4112 case Builtin::BI__builtin_elementwise_maxnum: {
4113 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4114 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4115 Value *Result = Builder.CreateBinaryIntrinsic(ID: llvm::Intrinsic::maxnum, LHS: Op0,
4116 RHS: Op1, FMFSource: nullptr, Name: "elt.maxnum");
4117 return RValue::get(V: Result);
4118 }
4119
4120 case Builtin::BI__builtin_elementwise_minnum: {
4121 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4122 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4123 Value *Result = Builder.CreateBinaryIntrinsic(ID: llvm::Intrinsic::minnum, LHS: Op0,
4124 RHS: Op1, FMFSource: nullptr, Name: "elt.minnum");
4125 return RValue::get(V: Result);
4126 }
4127
4128 case Builtin::BI__builtin_elementwise_maximum: {
4129 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4130 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4131 Value *Result = Builder.CreateBinaryIntrinsic(ID: Intrinsic::maximum, LHS: Op0, RHS: Op1,
4132 FMFSource: nullptr, Name: "elt.maximum");
4133 return RValue::get(V: Result);
4134 }
4135
4136 case Builtin::BI__builtin_elementwise_minimum: {
4137 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4138 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4139 Value *Result = Builder.CreateBinaryIntrinsic(ID: Intrinsic::minimum, LHS: Op0, RHS: Op1,
4140 FMFSource: nullptr, Name: "elt.minimum");
4141 return RValue::get(V: Result);
4142 }
4143
4144 case Builtin::BI__builtin_elementwise_maximumnum: {
4145 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4146 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4147 Value *Result = Builder.CreateBinaryIntrinsic(
4148 ID: Intrinsic::maximumnum, LHS: Op0, RHS: Op1, FMFSource: nullptr, Name: "elt.maximumnum");
4149 return RValue::get(V: Result);
4150 }
4151
4152 case Builtin::BI__builtin_elementwise_minimumnum: {
4153 Value *Op0 = EmitScalarExpr(E: E->getArg(Arg: 0));
4154 Value *Op1 = EmitScalarExpr(E: E->getArg(Arg: 1));
4155 Value *Result = Builder.CreateBinaryIntrinsic(
4156 ID: Intrinsic::minimumnum, LHS: Op0, RHS: Op1, FMFSource: nullptr, Name: "elt.minimumnum");
4157 return RValue::get(V: Result);
4158 }
4159
4160 case Builtin::BI__builtin_reduce_max: {
4161 auto GetIntrinsicID = [this](QualType QT) {
4162 if (auto *VecTy = QT->getAs<VectorType>())
4163 QT = VecTy->getElementType();
4164 else if (QT->isSizelessVectorType())
4165 QT = QT->getSizelessVectorEltType(Ctx: CGM.getContext());
4166
4167 if (QT->isSignedIntegerType())
4168 return Intrinsic::vector_reduce_smax;
4169 if (QT->isUnsignedIntegerType())
4170 return Intrinsic::vector_reduce_umax;
4171 assert(QT->isFloatingType() && "must have a float here");
4172 return Intrinsic::vector_reduce_fmax;
4173 };
4174 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4175 CGF&: *this, E, IntrinsicID: GetIntrinsicID(E->getArg(Arg: 0)->getType()), Name: "rdx.min"));
4176 }
4177
4178 case Builtin::BI__builtin_reduce_min: {
4179 auto GetIntrinsicID = [this](QualType QT) {
4180 if (auto *VecTy = QT->getAs<VectorType>())
4181 QT = VecTy->getElementType();
4182 else if (QT->isSizelessVectorType())
4183 QT = QT->getSizelessVectorEltType(Ctx: CGM.getContext());
4184
4185 if (QT->isSignedIntegerType())
4186 return Intrinsic::vector_reduce_smin;
4187 if (QT->isUnsignedIntegerType())
4188 return Intrinsic::vector_reduce_umin;
4189 assert(QT->isFloatingType() && "must have a float here");
4190 return Intrinsic::vector_reduce_fmin;
4191 };
4192
4193 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4194 CGF&: *this, E, IntrinsicID: GetIntrinsicID(E->getArg(Arg: 0)->getType()), Name: "rdx.min"));
4195 }
4196
4197 case Builtin::BI__builtin_reduce_add:
4198 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4199 CGF&: *this, E, IntrinsicID: Intrinsic::vector_reduce_add, Name: "rdx.add"));
4200 case Builtin::BI__builtin_reduce_mul:
4201 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4202 CGF&: *this, E, IntrinsicID: Intrinsic::vector_reduce_mul, Name: "rdx.mul"));
4203 case Builtin::BI__builtin_reduce_xor:
4204 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4205 CGF&: *this, E, IntrinsicID: Intrinsic::vector_reduce_xor, Name: "rdx.xor"));
4206 case Builtin::BI__builtin_reduce_or:
4207 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4208 CGF&: *this, E, IntrinsicID: Intrinsic::vector_reduce_or, Name: "rdx.or"));
4209 case Builtin::BI__builtin_reduce_and:
4210 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4211 CGF&: *this, E, IntrinsicID: Intrinsic::vector_reduce_and, Name: "rdx.and"));
4212 case Builtin::BI__builtin_reduce_maximum:
4213 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4214 CGF&: *this, E, IntrinsicID: Intrinsic::vector_reduce_fmaximum, Name: "rdx.maximum"));
4215 case Builtin::BI__builtin_reduce_minimum:
4216 return RValue::get(V: emitBuiltinWithOneOverloadedType<1>(
4217 CGF&: *this, E, IntrinsicID: Intrinsic::vector_reduce_fminimum, Name: "rdx.minimum"));
4218
4219 case Builtin::BI__builtin_matrix_transpose: {
4220 auto *MatrixTy = E->getArg(Arg: 0)->getType()->castAs<ConstantMatrixType>();
4221 Value *MatValue = EmitScalarExpr(E: E->getArg(Arg: 0));
4222 MatrixBuilder MB(Builder);
4223 Value *Result = MB.CreateMatrixTranspose(Matrix: MatValue, Rows: MatrixTy->getNumRows(),
4224 Columns: MatrixTy->getNumColumns());
4225 return RValue::get(V: Result);
4226 }
4227
4228 case Builtin::BI__builtin_matrix_column_major_load: {
4229 MatrixBuilder MB(Builder);
4230 // Emit everything that isn't dependent on the first parameter type
4231 Value *Stride = EmitScalarExpr(E: E->getArg(Arg: 3));
4232 const auto *ResultTy = E->getType()->getAs<ConstantMatrixType>();
4233 auto *PtrTy = E->getArg(Arg: 0)->getType()->getAs<PointerType>();
4234 assert(PtrTy && "arg0 must be of pointer type");
4235 bool IsVolatile = PtrTy->getPointeeType().isVolatileQualified();
4236
4237 Address Src = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4238 EmitNonNullArgCheck(RV: RValue::get(V: Src.emitRawPointer(CGF&: *this)),
4239 ArgType: E->getArg(Arg: 0)->getType(), ArgLoc: E->getArg(Arg: 0)->getExprLoc(), AC: FD,
4240 ParmNum: 0);
4241 Value *Result = MB.CreateColumnMajorLoad(
4242 EltTy: Src.getElementType(), DataPtr: Src.emitRawPointer(CGF&: *this),
4243 Alignment: Align(Src.getAlignment().getQuantity()), Stride, IsVolatile,
4244 Rows: ResultTy->getNumRows(), Columns: ResultTy->getNumColumns(), Name: "matrix");
4245 return RValue::get(V: Result);
4246 }
4247
4248 case Builtin::BI__builtin_matrix_column_major_store: {
4249 MatrixBuilder MB(Builder);
4250 Value *Matrix = EmitScalarExpr(E: E->getArg(Arg: 0));
4251 Address Dst = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4252 Value *Stride = EmitScalarExpr(E: E->getArg(Arg: 2));
4253
4254 const auto *MatrixTy = E->getArg(Arg: 0)->getType()->getAs<ConstantMatrixType>();
4255 auto *PtrTy = E->getArg(Arg: 1)->getType()->getAs<PointerType>();
4256 assert(PtrTy && "arg1 must be of pointer type");
4257 bool IsVolatile = PtrTy->getPointeeType().isVolatileQualified();
4258
4259 EmitNonNullArgCheck(RV: RValue::get(V: Dst.emitRawPointer(CGF&: *this)),
4260 ArgType: E->getArg(Arg: 1)->getType(), ArgLoc: E->getArg(Arg: 1)->getExprLoc(), AC: FD,
4261 ParmNum: 0);
4262 Value *Result = MB.CreateColumnMajorStore(
4263 Matrix, Ptr: Dst.emitRawPointer(CGF&: *this),
4264 Alignment: Align(Dst.getAlignment().getQuantity()), Stride, IsVolatile,
4265 Rows: MatrixTy->getNumRows(), Columns: MatrixTy->getNumColumns());
4266 addInstToNewSourceAtom(KeyInstruction: cast<Instruction>(Val: Result), Backup: Matrix);
4267 return RValue::get(V: Result);
4268 }
4269
4270 case Builtin::BI__builtin_masked_load:
4271 case Builtin::BI__builtin_masked_expand_load: {
4272 llvm::Value *Mask = EmitScalarExpr(E: E->getArg(Arg: 0));
4273 llvm::Value *Ptr = EmitScalarExpr(E: E->getArg(Arg: 1));
4274
4275 llvm::Type *RetTy = CGM.getTypes().ConvertType(T: E->getType());
4276 llvm::Value *PassThru = llvm::PoisonValue::get(T: RetTy);
4277 if (E->getNumArgs() > 2)
4278 PassThru = EmitScalarExpr(E: E->getArg(Arg: 2));
4279
4280 CharUnits Align = CGM.getNaturalTypeAlignment(
4281 T: E->getType()->getAs<VectorType>()->getElementType(), BaseInfo: nullptr);
4282
4283 llvm::Value *Result;
4284 if (BuiltinID == Builtin::BI__builtin_masked_load) {
4285 Result = Builder.CreateMaskedLoad(Ty: RetTy, Ptr, Alignment: Align.getAsAlign(), Mask,
4286 PassThru, Name: "masked_load");
4287 } else {
4288 Function *F = CGM.getIntrinsic(IID: Intrinsic::masked_expandload, Tys: {RetTy});
4289 Result =
4290 Builder.CreateCall(Callee: F, Args: {Ptr, Mask, PassThru}, Name: "masked_expand_load");
4291 }
4292 return RValue::get(V: Result);
4293 };
4294 case Builtin::BI__builtin_masked_gather: {
4295 llvm::Value *Mask = EmitScalarExpr(E: E->getArg(Arg: 0));
4296 llvm::Value *Idx = EmitScalarExpr(E: E->getArg(Arg: 1));
4297 llvm::Value *Ptr = EmitScalarExpr(E: E->getArg(Arg: 2));
4298
4299 llvm::Type *RetTy = CGM.getTypes().ConvertType(T: E->getType());
4300 CharUnits Align = CGM.getNaturalTypeAlignment(
4301 T: E->getType()->getAs<VectorType>()->getElementType(), BaseInfo: nullptr);
4302
4303 llvm::Value *PassThru = llvm::PoisonValue::get(T: RetTy);
4304 if (E->getNumArgs() > 3)
4305 PassThru = EmitScalarExpr(E: E->getArg(Arg: 3));
4306
4307 llvm::Type *ElemTy = CGM.getTypes().ConvertType(
4308 T: E->getType()->getAs<VectorType>()->getElementType());
4309 llvm::Value *PtrVec = Builder.CreateGEP(Ty: ElemTy, Ptr, IdxList: Idx);
4310
4311 llvm::Value *Result = Builder.CreateMaskedGather(
4312 Ty: RetTy, Ptrs: PtrVec, Alignment: Align.getAsAlign(), Mask, PassThru, Name: "masked_gather");
4313 return RValue::get(V: Result);
4314 }
4315 case Builtin::BI__builtin_masked_store:
4316 case Builtin::BI__builtin_masked_compress_store: {
4317 llvm::Value *Mask = EmitScalarExpr(E: E->getArg(Arg: 0));
4318 llvm::Value *Val = EmitScalarExpr(E: E->getArg(Arg: 1));
4319 llvm::Value *Ptr = EmitScalarExpr(E: E->getArg(Arg: 2));
4320
4321 QualType ValTy = E->getArg(Arg: 1)->getType();
4322 llvm::Type *ValLLTy = CGM.getTypes().ConvertType(T: ValTy);
4323
4324 CharUnits Align = CGM.getNaturalTypeAlignment(
4325 T: E->getArg(Arg: 1)->getType()->getAs<VectorType>()->getElementType(),
4326 BaseInfo: nullptr);
4327
4328 if (BuiltinID == Builtin::BI__builtin_masked_store) {
4329 Builder.CreateMaskedStore(Val, Ptr, Alignment: Align.getAsAlign(), Mask);
4330 } else {
4331 llvm::Function *F =
4332 CGM.getIntrinsic(IID: llvm::Intrinsic::masked_compressstore, Tys: {ValLLTy});
4333 Builder.CreateCall(Callee: F, Args: {Val, Ptr, Mask});
4334 }
4335 return RValue::get(V: nullptr);
4336 }
4337 case Builtin::BI__builtin_masked_scatter: {
4338 llvm::Value *Mask = EmitScalarExpr(E: E->getArg(Arg: 0));
4339 llvm::Value *Idx = EmitScalarExpr(E: E->getArg(Arg: 1));
4340 llvm::Value *Val = EmitScalarExpr(E: E->getArg(Arg: 2));
4341 llvm::Value *Ptr = EmitScalarExpr(E: E->getArg(Arg: 3));
4342
4343 CharUnits Align = CGM.getNaturalTypeAlignment(
4344 T: E->getArg(Arg: 2)->getType()->getAs<VectorType>()->getElementType(),
4345 BaseInfo: nullptr);
4346
4347 llvm::Type *ElemTy = CGM.getTypes().ConvertType(
4348 T: E->getArg(Arg: 1)->getType()->getAs<VectorType>()->getElementType());
4349 llvm::Value *PtrVec = Builder.CreateGEP(Ty: ElemTy, Ptr, IdxList: Idx);
4350
4351 Builder.CreateMaskedScatter(Val, Ptrs: PtrVec, Alignment: Align.getAsAlign(), Mask);
4352 return RValue();
4353 }
4354 case Builtin::BI__builtin_isinf_sign: {
4355 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0
4356 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
4357 // FIXME: for strictfp/IEEE-754 we need to not trap on SNaN here.
4358 Value *Arg = EmitScalarExpr(E: E->getArg(Arg: 0));
4359 Value *AbsArg = EmitFAbs(CGF&: *this, V: Arg);
4360 Value *IsInf = Builder.CreateFCmpOEQ(
4361 LHS: AbsArg, RHS: ConstantFP::getInfinity(Ty: Arg->getType()), Name: "isinf");
4362 Value *IsNeg = EmitSignBit(CGF&: *this, V: Arg);
4363
4364 llvm::Type *IntTy = ConvertType(T: E->getType());
4365 Value *Zero = Constant::getNullValue(Ty: IntTy);
4366 Value *One = ConstantInt::get(Ty: IntTy, V: 1);
4367 Value *NegativeOne = ConstantInt::getAllOnesValue(Ty: IntTy);
4368 Value *SignResult = Builder.CreateSelect(C: IsNeg, True: NegativeOne, False: One);
4369 Value *Result = Builder.CreateSelect(C: IsInf, True: SignResult, False: Zero);
4370 return RValue::get(V: Result);
4371 }
4372
4373 case Builtin::BI__builtin_flt_rounds: {
4374 Function *F = CGM.getIntrinsic(IID: Intrinsic::get_rounding);
4375
4376 llvm::Type *ResultType = ConvertType(T: E->getType());
4377 Value *Result = Builder.CreateCall(Callee: F);
4378 if (Result->getType() != ResultType)
4379 Result = Builder.CreateIntCast(V: Result, DestTy: ResultType, /*isSigned*/true,
4380 Name: "cast");
4381 return RValue::get(V: Result);
4382 }
4383
4384 case Builtin::BI__builtin_set_flt_rounds: {
4385 Function *F = CGM.getIntrinsic(IID: Intrinsic::set_rounding);
4386
4387 Value *V = EmitScalarExpr(E: E->getArg(Arg: 0));
4388 Builder.CreateCall(Callee: F, Args: V);
4389 return RValue::get(V: nullptr);
4390 }
4391
4392 case Builtin::BI__builtin_fpclassify: {
4393 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
4394 // FIXME: for strictfp/IEEE-754 we need to not trap on SNaN here.
4395 Value *V = EmitScalarExpr(E: E->getArg(Arg: 5));
4396 llvm::Type *Ty = ConvertType(T: E->getArg(Arg: 5)->getType());
4397
4398 // Create Result
4399 BasicBlock *Begin = Builder.GetInsertBlock();
4400 BasicBlock *End = createBasicBlock(name: "fpclassify_end", parent: this->CurFn);
4401 Builder.SetInsertPoint(End);
4402 PHINode *Result =
4403 Builder.CreatePHI(Ty: ConvertType(T: E->getArg(Arg: 0)->getType()), NumReservedValues: 4,
4404 Name: "fpclassify_result");
4405
4406 // if (V==0) return FP_ZERO
4407 Builder.SetInsertPoint(Begin);
4408 Value *IsZero = Builder.CreateFCmpOEQ(LHS: V, RHS: Constant::getNullValue(Ty),
4409 Name: "iszero");
4410 Value *ZeroLiteral = EmitScalarExpr(E: E->getArg(Arg: 4));
4411 BasicBlock *NotZero = createBasicBlock(name: "fpclassify_not_zero", parent: this->CurFn);
4412 Builder.CreateCondBr(Cond: IsZero, True: End, False: NotZero);
4413 Result->addIncoming(V: ZeroLiteral, BB: Begin);
4414
4415 // if (V != V) return FP_NAN
4416 Builder.SetInsertPoint(NotZero);
4417 Value *IsNan = Builder.CreateFCmpUNO(LHS: V, RHS: V, Name: "cmp");
4418 Value *NanLiteral = EmitScalarExpr(E: E->getArg(Arg: 0));
4419 BasicBlock *NotNan = createBasicBlock(name: "fpclassify_not_nan", parent: this->CurFn);
4420 Builder.CreateCondBr(Cond: IsNan, True: End, False: NotNan);
4421 Result->addIncoming(V: NanLiteral, BB: NotZero);
4422
4423 // if (fabs(V) == infinity) return FP_INFINITY
4424 Builder.SetInsertPoint(NotNan);
4425 Value *VAbs = EmitFAbs(CGF&: *this, V);
4426 Value *IsInf =
4427 Builder.CreateFCmpOEQ(LHS: VAbs, RHS: ConstantFP::getInfinity(Ty: V->getType()),
4428 Name: "isinf");
4429 Value *InfLiteral = EmitScalarExpr(E: E->getArg(Arg: 1));
4430 BasicBlock *NotInf = createBasicBlock(name: "fpclassify_not_inf", parent: this->CurFn);
4431 Builder.CreateCondBr(Cond: IsInf, True: End, False: NotInf);
4432 Result->addIncoming(V: InfLiteral, BB: NotNan);
4433
4434 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL
4435 Builder.SetInsertPoint(NotInf);
4436 APFloat Smallest = APFloat::getSmallestNormalized(
4437 Sem: getContext().getFloatTypeSemantics(T: E->getArg(Arg: 5)->getType()));
4438 Value *IsNormal =
4439 Builder.CreateFCmpUGE(LHS: VAbs, RHS: ConstantFP::get(Context&: V->getContext(), V: Smallest),
4440 Name: "isnormal");
4441 Value *NormalResult =
4442 Builder.CreateSelect(C: IsNormal, True: EmitScalarExpr(E: E->getArg(Arg: 2)),
4443 False: EmitScalarExpr(E: E->getArg(Arg: 3)));
4444 Builder.CreateBr(Dest: End);
4445 Result->addIncoming(V: NormalResult, BB: NotInf);
4446
4447 // return Result
4448 Builder.SetInsertPoint(End);
4449 return RValue::get(V: Result);
4450 }
4451
4452 // An alloca will always return a pointer to the alloca (stack) address
4453 // space. This address space need not be the same as the AST / Language
4454 // default (e.g. in C / C++ auto vars are in the generic address space). At
4455 // the AST level this is handled within CreateTempAlloca et al., but for the
4456 // builtin / dynamic alloca we have to handle it here. We use an explicit cast
4457 // instead of passing an AS to CreateAlloca so as to not inhibit optimisation.
4458 case Builtin::BIalloca:
4459 case Builtin::BI_alloca:
4460 case Builtin::BI__builtin_alloca_uninitialized:
4461 case Builtin::BI__builtin_alloca: {
4462 Value *Size = EmitScalarExpr(E: E->getArg(Arg: 0));
4463 const TargetInfo &TI = getContext().getTargetInfo();
4464 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
4465 const Align SuitableAlignmentInBytes =
4466 CGM.getContext()
4467 .toCharUnitsFromBits(BitSize: TI.getSuitableAlign())
4468 .getAsAlign();
4469 AllocaInst *AI = Builder.CreateAlloca(Ty: Builder.getInt8Ty(), ArraySize: Size);
4470 AI->setAlignment(SuitableAlignmentInBytes);
4471 if (BuiltinID != Builtin::BI__builtin_alloca_uninitialized)
4472 initializeAlloca(CGF&: *this, AI, Size, AlignmentInBytes: SuitableAlignmentInBytes);
4473 if (AI->getAddressSpace() !=
4474 CGM.getContext().getTargetAddressSpace(
4475 AS: E->getType()->getPointeeType().getAddressSpace())) {
4476 llvm::Type *Ty = CGM.getTypes().ConvertType(T: E->getType());
4477 return RValue::get(V: performAddrSpaceCast(Src: AI, DestTy: Ty));
4478 }
4479 return RValue::get(V: AI);
4480 }
4481
4482 case Builtin::BI__builtin_alloca_with_align_uninitialized:
4483 case Builtin::BI__builtin_alloca_with_align: {
4484 Value *Size = EmitScalarExpr(E: E->getArg(Arg: 0));
4485 Value *AlignmentInBitsValue = EmitScalarExpr(E: E->getArg(Arg: 1));
4486 auto *AlignmentInBitsCI = cast<ConstantInt>(Val: AlignmentInBitsValue);
4487 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue();
4488 const Align AlignmentInBytes =
4489 CGM.getContext().toCharUnitsFromBits(BitSize: AlignmentInBits).getAsAlign();
4490 AllocaInst *AI = Builder.CreateAlloca(Ty: Builder.getInt8Ty(), ArraySize: Size);
4491 AI->setAlignment(AlignmentInBytes);
4492 if (BuiltinID != Builtin::BI__builtin_alloca_with_align_uninitialized)
4493 initializeAlloca(CGF&: *this, AI, Size, AlignmentInBytes);
4494 if (AI->getAddressSpace() !=
4495 CGM.getContext().getTargetAddressSpace(
4496 AS: E->getType()->getPointeeType().getAddressSpace())) {
4497 llvm::Type *Ty = CGM.getTypes().ConvertType(T: E->getType());
4498 return RValue::get(V: performAddrSpaceCast(Src: AI, DestTy: Ty));
4499 }
4500 return RValue::get(V: AI);
4501 }
4502
4503 case Builtin::BI__builtin_infer_alloc_token: {
4504 llvm::MDNode *MDN = buildAllocToken(E);
4505 llvm::Value *MDV = MetadataAsValue::get(Context&: getLLVMContext(), MD: MDN);
4506 llvm::Function *F =
4507 CGM.getIntrinsic(IID: llvm::Intrinsic::alloc_token_id, Tys: {IntPtrTy});
4508 llvm::CallBase *TokenID = Builder.CreateCall(Callee: F, Args: MDV);
4509 return RValue::get(V: TokenID);
4510 }
4511
4512 case Builtin::BIbzero:
4513 case Builtin::BI__builtin_bzero: {
4514 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4515 Value *SizeVal = EmitScalarExpr(E: E->getArg(Arg: 1));
4516 EmitNonNullArgCheck(Addr: Dest, ArgType: E->getArg(Arg: 0)->getType(),
4517 ArgLoc: E->getArg(Arg: 0)->getExprLoc(), AC: FD, ParmNum: 0);
4518 auto *I = Builder.CreateMemSet(Dest, Value: Builder.getInt8(C: 0), Size: SizeVal, IsVolatile: false);
4519 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4520 return RValue::get(V: nullptr);
4521 }
4522
4523 case Builtin::BIbcopy:
4524 case Builtin::BI__builtin_bcopy: {
4525 Address Src = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4526 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4527 Value *SizeVal = EmitScalarExpr(E: E->getArg(Arg: 2));
4528 EmitNonNullArgCheck(RV: RValue::get(V: Src.emitRawPointer(CGF&: *this)),
4529 ArgType: E->getArg(Arg: 0)->getType(), ArgLoc: E->getArg(Arg: 0)->getExprLoc(), AC: FD,
4530 ParmNum: 0);
4531 EmitNonNullArgCheck(RV: RValue::get(V: Dest.emitRawPointer(CGF&: *this)),
4532 ArgType: E->getArg(Arg: 1)->getType(), ArgLoc: E->getArg(Arg: 1)->getExprLoc(), AC: FD,
4533 ParmNum: 0);
4534 auto *I = Builder.CreateMemMove(Dest, Src, Size: SizeVal, IsVolatile: false);
4535 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4536 return RValue::get(V: nullptr);
4537 }
4538
4539 case Builtin::BImemcpy:
4540 case Builtin::BI__builtin_memcpy:
4541 case Builtin::BImempcpy:
4542 case Builtin::BI__builtin_mempcpy: {
4543 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4544 Address Src = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4545 Value *SizeVal = EmitScalarExpr(E: E->getArg(Arg: 2));
4546 EmitArgCheck(TCK_Store, Dest, E->getArg(Arg: 0), 0);
4547 EmitArgCheck(TCK_Load, Src, E->getArg(Arg: 1), 1);
4548 auto *I = Builder.CreateMemCpy(Dest, Src, Size: SizeVal, IsVolatile: false);
4549 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4550 if (BuiltinID == Builtin::BImempcpy ||
4551 BuiltinID == Builtin::BI__builtin_mempcpy)
4552 return RValue::get(V: Builder.CreateInBoundsGEP(
4553 Ty: Dest.getElementType(), Ptr: Dest.emitRawPointer(CGF&: *this), IdxList: SizeVal));
4554 else
4555 return RValue::get(Addr: Dest, CGF&: *this);
4556 }
4557
4558 case Builtin::BI__builtin_memcpy_inline: {
4559 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4560 Address Src = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4561 uint64_t Size =
4562 E->getArg(Arg: 2)->EvaluateKnownConstInt(Ctx: getContext()).getZExtValue();
4563 EmitArgCheck(TCK_Store, Dest, E->getArg(Arg: 0), 0);
4564 EmitArgCheck(TCK_Load, Src, E->getArg(Arg: 1), 1);
4565 auto *I = Builder.CreateMemCpyInline(Dest, Src, Size);
4566 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4567 return RValue::get(V: nullptr);
4568 }
4569
4570 case Builtin::BI__builtin_char_memchr:
4571 BuiltinID = Builtin::BI__builtin_memchr;
4572 break;
4573
4574 case Builtin::BI__builtin___memcpy_chk: {
4575 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
4576 Expr::EvalResult SizeResult, DstSizeResult;
4577 if (!E->getArg(Arg: 2)->EvaluateAsInt(Result&: SizeResult, Ctx: CGM.getContext()) ||
4578 !E->getArg(Arg: 3)->EvaluateAsInt(Result&: DstSizeResult, Ctx: CGM.getContext()))
4579 break;
4580 llvm::APSInt Size = SizeResult.Val.getInt();
4581 llvm::APSInt DstSize = DstSizeResult.Val.getInt();
4582 if (Size.ugt(RHS: DstSize))
4583 break;
4584 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4585 Address Src = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4586 Value *SizeVal = llvm::ConstantInt::get(Context&: Builder.getContext(), V: Size);
4587 auto *I = Builder.CreateMemCpy(Dest, Src, Size: SizeVal, IsVolatile: false);
4588 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4589 return RValue::get(Addr: Dest, CGF&: *this);
4590 }
4591
4592 case Builtin::BI__builtin_objc_memmove_collectable: {
4593 Address DestAddr = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4594 Address SrcAddr = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4595 Value *SizeVal = EmitScalarExpr(E: E->getArg(Arg: 2));
4596 CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF&: *this,
4597 DestPtr: DestAddr, SrcPtr: SrcAddr, Size: SizeVal);
4598 return RValue::get(Addr: DestAddr, CGF&: *this);
4599 }
4600
4601 case Builtin::BI__builtin___memmove_chk: {
4602 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2.
4603 Expr::EvalResult SizeResult, DstSizeResult;
4604 if (!E->getArg(Arg: 2)->EvaluateAsInt(Result&: SizeResult, Ctx: CGM.getContext()) ||
4605 !E->getArg(Arg: 3)->EvaluateAsInt(Result&: DstSizeResult, Ctx: CGM.getContext()))
4606 break;
4607 llvm::APSInt Size = SizeResult.Val.getInt();
4608 llvm::APSInt DstSize = DstSizeResult.Val.getInt();
4609 if (Size.ugt(RHS: DstSize))
4610 break;
4611 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4612 Address Src = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4613 Value *SizeVal = llvm::ConstantInt::get(Context&: Builder.getContext(), V: Size);
4614 auto *I = Builder.CreateMemMove(Dest, Src, Size: SizeVal, IsVolatile: false);
4615 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4616 return RValue::get(Addr: Dest, CGF&: *this);
4617 }
4618
4619 case Builtin::BI__builtin_trivially_relocate:
4620 case Builtin::BImemmove:
4621 case Builtin::BI__builtin_memmove: {
4622 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4623 Address Src = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
4624 Value *SizeVal = EmitScalarExpr(E: E->getArg(Arg: 2));
4625 if (BuiltinIDIfNoAsmLabel == Builtin::BI__builtin_trivially_relocate)
4626 SizeVal = Builder.CreateMul(
4627 LHS: SizeVal,
4628 RHS: ConstantInt::get(
4629 Ty: SizeVal->getType(),
4630 V: getContext()
4631 .getTypeSizeInChars(T: E->getArg(Arg: 0)->getType()->getPointeeType())
4632 .getQuantity()));
4633 EmitArgCheck(TCK_Store, Dest, E->getArg(Arg: 0), 0);
4634 EmitArgCheck(TCK_Load, Src, E->getArg(Arg: 1), 1);
4635 auto *I = Builder.CreateMemMove(Dest, Src, Size: SizeVal, IsVolatile: false);
4636 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4637 return RValue::get(Addr: Dest, CGF&: *this);
4638 }
4639 case Builtin::BImemset:
4640 case Builtin::BI__builtin_memset: {
4641 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4642 Value *ByteVal = Builder.CreateTrunc(V: EmitScalarExpr(E: E->getArg(Arg: 1)),
4643 DestTy: Builder.getInt8Ty());
4644 Value *SizeVal = EmitScalarExpr(E: E->getArg(Arg: 2));
4645 EmitNonNullArgCheck(Addr: Dest, ArgType: E->getArg(Arg: 0)->getType(),
4646 ArgLoc: E->getArg(Arg: 0)->getExprLoc(), AC: FD, ParmNum: 0);
4647 auto *I = Builder.CreateMemSet(Dest, Value: ByteVal, Size: SizeVal, IsVolatile: false);
4648 addInstToNewSourceAtom(KeyInstruction: I, Backup: ByteVal);
4649 return RValue::get(Addr: Dest, CGF&: *this);
4650 }
4651 case Builtin::BI__builtin_memset_inline: {
4652 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4653 Value *ByteVal =
4654 Builder.CreateTrunc(V: EmitScalarExpr(E: E->getArg(Arg: 1)), DestTy: Builder.getInt8Ty());
4655 uint64_t Size =
4656 E->getArg(Arg: 2)->EvaluateKnownConstInt(Ctx: getContext()).getZExtValue();
4657 EmitNonNullArgCheck(RV: RValue::get(V: Dest.emitRawPointer(CGF&: *this)),
4658 ArgType: E->getArg(Arg: 0)->getType(), ArgLoc: E->getArg(Arg: 0)->getExprLoc(), AC: FD,
4659 ParmNum: 0);
4660 auto *I = Builder.CreateMemSetInline(Dest, Value: ByteVal, Size);
4661 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4662 return RValue::get(V: nullptr);
4663 }
4664 case Builtin::BI__builtin___memset_chk: {
4665 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
4666 Expr::EvalResult SizeResult, DstSizeResult;
4667 if (!E->getArg(Arg: 2)->EvaluateAsInt(Result&: SizeResult, Ctx: CGM.getContext()) ||
4668 !E->getArg(Arg: 3)->EvaluateAsInt(Result&: DstSizeResult, Ctx: CGM.getContext()))
4669 break;
4670 llvm::APSInt Size = SizeResult.Val.getInt();
4671 llvm::APSInt DstSize = DstSizeResult.Val.getInt();
4672 if (Size.ugt(RHS: DstSize))
4673 break;
4674 Address Dest = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4675 Value *ByteVal = Builder.CreateTrunc(V: EmitScalarExpr(E: E->getArg(Arg: 1)),
4676 DestTy: Builder.getInt8Ty());
4677 Value *SizeVal = llvm::ConstantInt::get(Context&: Builder.getContext(), V: Size);
4678 auto *I = Builder.CreateMemSet(Dest, Value: ByteVal, Size: SizeVal, IsVolatile: false);
4679 addInstToNewSourceAtom(KeyInstruction: I, Backup: nullptr);
4680 return RValue::get(Addr: Dest, CGF&: *this);
4681 }
4682 case Builtin::BI__builtin_wmemchr: {
4683 // The MSVC runtime library does not provide a definition of wmemchr, so we
4684 // need an inline implementation.
4685 if (!getTarget().getTriple().isOSMSVCRT())
4686 break;
4687
4688 llvm::Type *WCharTy = ConvertType(T: getContext().WCharTy);
4689 Value *Str = EmitScalarExpr(E: E->getArg(Arg: 0));
4690 Value *Chr = EmitScalarExpr(E: E->getArg(Arg: 1));
4691 Value *Size = EmitScalarExpr(E: E->getArg(Arg: 2));
4692
4693 BasicBlock *Entry = Builder.GetInsertBlock();
4694 BasicBlock *CmpEq = createBasicBlock(name: "wmemchr.eq");
4695 BasicBlock *Next = createBasicBlock(name: "wmemchr.next");
4696 BasicBlock *Exit = createBasicBlock(name: "wmemchr.exit");
4697 Value *SizeEq0 = Builder.CreateICmpEQ(LHS: Size, RHS: ConstantInt::get(Ty: SizeTy, V: 0));
4698 Builder.CreateCondBr(Cond: SizeEq0, True: Exit, False: CmpEq);
4699
4700 EmitBlock(BB: CmpEq);
4701 PHINode *StrPhi = Builder.CreatePHI(Ty: Str->getType(), NumReservedValues: 2);
4702 StrPhi->addIncoming(V: Str, BB: Entry);
4703 PHINode *SizePhi = Builder.CreatePHI(Ty: SizeTy, NumReservedValues: 2);
4704 SizePhi->addIncoming(V: Size, BB: Entry);
4705 CharUnits WCharAlign =
4706 getContext().getTypeAlignInChars(T: getContext().WCharTy);
4707 Value *StrCh = Builder.CreateAlignedLoad(Ty: WCharTy, Addr: StrPhi, Align: WCharAlign);
4708 Value *FoundChr = Builder.CreateConstInBoundsGEP1_32(Ty: WCharTy, Ptr: StrPhi, Idx0: 0);
4709 Value *StrEqChr = Builder.CreateICmpEQ(LHS: StrCh, RHS: Chr);
4710 Builder.CreateCondBr(Cond: StrEqChr, True: Exit, False: Next);
4711
4712 EmitBlock(BB: Next);
4713 Value *NextStr = Builder.CreateConstInBoundsGEP1_32(Ty: WCharTy, Ptr: StrPhi, Idx0: 1);
4714 Value *NextSize = Builder.CreateSub(LHS: SizePhi, RHS: ConstantInt::get(Ty: SizeTy, V: 1));
4715 Value *NextSizeEq0 =
4716 Builder.CreateICmpEQ(LHS: NextSize, RHS: ConstantInt::get(Ty: SizeTy, V: 0));
4717 Builder.CreateCondBr(Cond: NextSizeEq0, True: Exit, False: CmpEq);
4718 StrPhi->addIncoming(V: NextStr, BB: Next);
4719 SizePhi->addIncoming(V: NextSize, BB: Next);
4720
4721 EmitBlock(BB: Exit);
4722 PHINode *Ret = Builder.CreatePHI(Ty: Str->getType(), NumReservedValues: 3);
4723 Ret->addIncoming(V: llvm::Constant::getNullValue(Ty: Str->getType()), BB: Entry);
4724 Ret->addIncoming(V: llvm::Constant::getNullValue(Ty: Str->getType()), BB: Next);
4725 Ret->addIncoming(V: FoundChr, BB: CmpEq);
4726 return RValue::get(V: Ret);
4727 }
4728 case Builtin::BI__builtin_wmemcmp: {
4729 // The MSVC runtime library does not provide a definition of wmemcmp, so we
4730 // need an inline implementation.
4731 if (!getTarget().getTriple().isOSMSVCRT())
4732 break;
4733
4734 llvm::Type *WCharTy = ConvertType(T: getContext().WCharTy);
4735
4736 Value *Dst = EmitScalarExpr(E: E->getArg(Arg: 0));
4737 Value *Src = EmitScalarExpr(E: E->getArg(Arg: 1));
4738 Value *Size = EmitScalarExpr(E: E->getArg(Arg: 2));
4739
4740 BasicBlock *Entry = Builder.GetInsertBlock();
4741 BasicBlock *CmpGT = createBasicBlock(name: "wmemcmp.gt");
4742 BasicBlock *CmpLT = createBasicBlock(name: "wmemcmp.lt");
4743 BasicBlock *Next = createBasicBlock(name: "wmemcmp.next");
4744 BasicBlock *Exit = createBasicBlock(name: "wmemcmp.exit");
4745 Value *SizeEq0 = Builder.CreateICmpEQ(LHS: Size, RHS: ConstantInt::get(Ty: SizeTy, V: 0));
4746 Builder.CreateCondBr(Cond: SizeEq0, True: Exit, False: CmpGT);
4747
4748 EmitBlock(BB: CmpGT);
4749 PHINode *DstPhi = Builder.CreatePHI(Ty: Dst->getType(), NumReservedValues: 2);
4750 DstPhi->addIncoming(V: Dst, BB: Entry);
4751 PHINode *SrcPhi = Builder.CreatePHI(Ty: Src->getType(), NumReservedValues: 2);
4752 SrcPhi->addIncoming(V: Src, BB: Entry);
4753 PHINode *SizePhi = Builder.CreatePHI(Ty: SizeTy, NumReservedValues: 2);
4754 SizePhi->addIncoming(V: Size, BB: Entry);
4755 CharUnits WCharAlign =
4756 getContext().getTypeAlignInChars(T: getContext().WCharTy);
4757 Value *DstCh = Builder.CreateAlignedLoad(Ty: WCharTy, Addr: DstPhi, Align: WCharAlign);
4758 Value *SrcCh = Builder.CreateAlignedLoad(Ty: WCharTy, Addr: SrcPhi, Align: WCharAlign);
4759 Value *DstGtSrc = Builder.CreateICmpUGT(LHS: DstCh, RHS: SrcCh);
4760 Builder.CreateCondBr(Cond: DstGtSrc, True: Exit, False: CmpLT);
4761
4762 EmitBlock(BB: CmpLT);
4763 Value *DstLtSrc = Builder.CreateICmpULT(LHS: DstCh, RHS: SrcCh);
4764 Builder.CreateCondBr(Cond: DstLtSrc, True: Exit, False: Next);
4765
4766 EmitBlock(BB: Next);
4767 Value *NextDst = Builder.CreateConstInBoundsGEP1_32(Ty: WCharTy, Ptr: DstPhi, Idx0: 1);
4768 Value *NextSrc = Builder.CreateConstInBoundsGEP1_32(Ty: WCharTy, Ptr: SrcPhi, Idx0: 1);
4769 Value *NextSize = Builder.CreateSub(LHS: SizePhi, RHS: ConstantInt::get(Ty: SizeTy, V: 1));
4770 Value *NextSizeEq0 =
4771 Builder.CreateICmpEQ(LHS: NextSize, RHS: ConstantInt::get(Ty: SizeTy, V: 0));
4772 Builder.CreateCondBr(Cond: NextSizeEq0, True: Exit, False: CmpGT);
4773 DstPhi->addIncoming(V: NextDst, BB: Next);
4774 SrcPhi->addIncoming(V: NextSrc, BB: Next);
4775 SizePhi->addIncoming(V: NextSize, BB: Next);
4776
4777 EmitBlock(BB: Exit);
4778 PHINode *Ret = Builder.CreatePHI(Ty: IntTy, NumReservedValues: 4);
4779 Ret->addIncoming(V: ConstantInt::get(Ty: IntTy, V: 0), BB: Entry);
4780 Ret->addIncoming(V: ConstantInt::get(Ty: IntTy, V: 1), BB: CmpGT);
4781 Ret->addIncoming(V: ConstantInt::getAllOnesValue(Ty: IntTy), BB: CmpLT);
4782 Ret->addIncoming(V: ConstantInt::get(Ty: IntTy, V: 0), BB: Next);
4783 return RValue::get(V: Ret);
4784 }
4785 case Builtin::BI__builtin_dwarf_cfa: {
4786 // The offset in bytes from the first argument to the CFA.
4787 //
4788 // Why on earth is this in the frontend? Is there any reason at
4789 // all that the backend can't reasonably determine this while
4790 // lowering llvm.eh.dwarf.cfa()?
4791 //
4792 // TODO: If there's a satisfactory reason, add a target hook for
4793 // this instead of hard-coding 0, which is correct for most targets.
4794 int32_t Offset = 0;
4795
4796 Function *F = CGM.getIntrinsic(IID: Intrinsic::eh_dwarf_cfa);
4797 return RValue::get(V: Builder.CreateCall(Callee: F,
4798 Args: llvm::ConstantInt::get(Ty: Int32Ty, V: Offset)));
4799 }
4800 case Builtin::BI__builtin_return_address: {
4801 Value *Depth = ConstantEmitter(*this).emitAbstract(E: E->getArg(Arg: 0),
4802 T: getContext().UnsignedIntTy);
4803 Function *F = CGM.getIntrinsic(IID: Intrinsic::returnaddress);
4804 return RValue::get(V: Builder.CreateCall(Callee: F, Args: Depth));
4805 }
4806 case Builtin::BI_ReturnAddress: {
4807 Function *F = CGM.getIntrinsic(IID: Intrinsic::returnaddress);
4808 return RValue::get(V: Builder.CreateCall(Callee: F, Args: Builder.getInt32(C: 0)));
4809 }
4810 case Builtin::BI__builtin_frame_address: {
4811 Value *Depth = ConstantEmitter(*this).emitAbstract(E: E->getArg(Arg: 0),
4812 T: getContext().UnsignedIntTy);
4813 Function *F = CGM.getIntrinsic(IID: Intrinsic::frameaddress, Tys: AllocaInt8PtrTy);
4814 return RValue::get(V: Builder.CreateCall(Callee: F, Args: Depth));
4815 }
4816 case Builtin::BI__builtin_stack_address: {
4817 return RValue::get(V: Builder.CreateCall(
4818 Callee: CGM.getIntrinsic(IID: Intrinsic::stackaddress, Tys: AllocaInt8PtrTy)));
4819 }
4820 case Builtin::BI__builtin_extract_return_addr: {
4821 Value *Address = EmitScalarExpr(E: E->getArg(Arg: 0));
4822 Value *Result = getTargetHooks().decodeReturnAddress(CGF&: *this, Address);
4823 return RValue::get(V: Result);
4824 }
4825 case Builtin::BI__builtin_frob_return_addr: {
4826 Value *Address = EmitScalarExpr(E: E->getArg(Arg: 0));
4827 Value *Result = getTargetHooks().encodeReturnAddress(CGF&: *this, Address);
4828 return RValue::get(V: Result);
4829 }
4830 case Builtin::BI__builtin_dwarf_sp_column: {
4831 llvm::IntegerType *Ty
4832 = cast<llvm::IntegerType>(Val: ConvertType(T: E->getType()));
4833 int Column = getTargetHooks().getDwarfEHStackPointer(M&: CGM);
4834 if (Column == -1) {
4835 CGM.ErrorUnsupported(S: E, Type: "__builtin_dwarf_sp_column");
4836 return RValue::get(V: llvm::UndefValue::get(T: Ty));
4837 }
4838 return RValue::get(V: llvm::ConstantInt::get(Ty, V: Column, IsSigned: true));
4839 }
4840 case Builtin::BI__builtin_init_dwarf_reg_size_table: {
4841 Value *Address = EmitScalarExpr(E: E->getArg(Arg: 0));
4842 if (getTargetHooks().initDwarfEHRegSizeTable(CGF&: *this, Address))
4843 CGM.ErrorUnsupported(S: E, Type: "__builtin_init_dwarf_reg_size_table");
4844 return RValue::get(V: llvm::UndefValue::get(T: ConvertType(T: E->getType())));
4845 }
4846 case Builtin::BI__builtin_eh_return: {
4847 Value *Int = EmitScalarExpr(E: E->getArg(Arg: 0));
4848 Value *Ptr = EmitScalarExpr(E: E->getArg(Arg: 1));
4849
4850 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Val: Int->getType());
4851 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) &&
4852 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants");
4853 Function *F =
4854 CGM.getIntrinsic(IID: IntTy->getBitWidth() == 32 ? Intrinsic::eh_return_i32
4855 : Intrinsic::eh_return_i64);
4856 Builder.CreateCall(Callee: F, Args: {Int, Ptr});
4857 Builder.CreateUnreachable();
4858
4859 // We do need to preserve an insertion point.
4860 EmitBlock(BB: createBasicBlock(name: "builtin_eh_return.cont"));
4861
4862 return RValue::get(V: nullptr);
4863 }
4864 case Builtin::BI__builtin_unwind_init: {
4865 Function *F = CGM.getIntrinsic(IID: Intrinsic::eh_unwind_init);
4866 Builder.CreateCall(Callee: F);
4867 return RValue::get(V: nullptr);
4868 }
4869 case Builtin::BI__builtin_extend_pointer: {
4870 // Extends a pointer to the size of an _Unwind_Word, which is
4871 // uint64_t on all platforms. Generally this gets poked into a
4872 // register and eventually used as an address, so if the
4873 // addressing registers are wider than pointers and the platform
4874 // doesn't implicitly ignore high-order bits when doing
4875 // addressing, we need to make sure we zext / sext based on
4876 // the platform's expectations.
4877 //
4878 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html
4879
4880 // Cast the pointer to intptr_t.
4881 Value *Ptr = EmitScalarExpr(E: E->getArg(Arg: 0));
4882 Value *Result = Builder.CreatePtrToInt(V: Ptr, DestTy: IntPtrTy, Name: "extend.cast");
4883
4884 // If that's 64 bits, we're done.
4885 if (IntPtrTy->getBitWidth() == 64)
4886 return RValue::get(V: Result);
4887
4888 // Otherwise, ask the codegen data what to do.
4889 if (getTargetHooks().extendPointerWithSExt())
4890 return RValue::get(V: Builder.CreateSExt(V: Result, DestTy: Int64Ty, Name: "extend.sext"));
4891 else
4892 return RValue::get(V: Builder.CreateZExt(V: Result, DestTy: Int64Ty, Name: "extend.zext"));
4893 }
4894 case Builtin::BI__builtin_setjmp: {
4895 // Buffer is a void**.
4896 Address Buf = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
4897
4898 if (getTarget().getTriple().getArch() == llvm::Triple::systemz) {
4899 // On this target, the back end fills in the context buffer completely.
4900 // It doesn't really matter if the frontend stores to the buffer before
4901 // calling setjmp, the back-end is going to overwrite them anyway.
4902 Function *F = CGM.getIntrinsic(IID: Intrinsic::eh_sjlj_setjmp);
4903 return RValue::get(V: Builder.CreateCall(Callee: F, Args: Buf.emitRawPointer(CGF&: *this)));
4904 }
4905
4906 // Store the frame pointer to the setjmp buffer.
4907 Value *FrameAddr = Builder.CreateCall(
4908 Callee: CGM.getIntrinsic(IID: Intrinsic::frameaddress, Tys: AllocaInt8PtrTy),
4909 Args: ConstantInt::get(Ty: Int32Ty, V: 0));
4910 Builder.CreateStore(Val: FrameAddr, Addr: Buf);
4911
4912 // Store the stack pointer to the setjmp buffer.
4913 Value *StackAddr = Builder.CreateStackSave();
4914 assert(Buf.emitRawPointer(*this)->getType() == StackAddr->getType());
4915
4916 Address StackSaveSlot = Builder.CreateConstInBoundsGEP(Addr: Buf, Index: 2);
4917 Builder.CreateStore(Val: StackAddr, Addr: StackSaveSlot);
4918
4919 // Call LLVM's EH setjmp, which is lightweight.
4920 Function *F = CGM.getIntrinsic(IID: Intrinsic::eh_sjlj_setjmp);
4921 return RValue::get(V: Builder.CreateCall(Callee: F, Args: Buf.emitRawPointer(CGF&: *this)));
4922 }
4923 case Builtin::BI__builtin_longjmp: {
4924 Value *Buf = EmitScalarExpr(E: E->getArg(Arg: 0));
4925
4926 // Call LLVM's EH longjmp, which is lightweight.
4927 Builder.CreateCall(Callee: CGM.getIntrinsic(IID: Intrinsic::eh_sjlj_longjmp), Args: Buf);
4928
4929 // longjmp doesn't return; mark this as unreachable.
4930 Builder.CreateUnreachable();
4931
4932 // We do need to preserve an insertion point.
4933 EmitBlock(BB: createBasicBlock(name: "longjmp.cont"));
4934
4935 return RValue::get(V: nullptr);
4936 }
4937 case Builtin::BI__builtin_launder: {
4938 const Expr *Arg = E->getArg(Arg: 0);
4939 QualType ArgTy = Arg->getType()->getPointeeType();
4940 Value *Ptr = EmitScalarExpr(E: Arg);
4941 if (TypeRequiresBuiltinLaunder(CGM, Ty: ArgTy))
4942 Ptr = Builder.CreateLaunderInvariantGroup(Ptr);
4943
4944 return RValue::get(V: Ptr);
4945 }
4946 case Builtin::BI__sync_fetch_and_add:
4947 case Builtin::BI__sync_fetch_and_sub:
4948 case Builtin::BI__sync_fetch_and_or:
4949 case Builtin::BI__sync_fetch_and_and:
4950 case Builtin::BI__sync_fetch_and_xor:
4951 case Builtin::BI__sync_fetch_and_nand:
4952 case Builtin::BI__sync_add_and_fetch:
4953 case Builtin::BI__sync_sub_and_fetch:
4954 case Builtin::BI__sync_and_and_fetch:
4955 case Builtin::BI__sync_or_and_fetch:
4956 case Builtin::BI__sync_xor_and_fetch:
4957 case Builtin::BI__sync_nand_and_fetch:
4958 case Builtin::BI__sync_val_compare_and_swap:
4959 case Builtin::BI__sync_bool_compare_and_swap:
4960 case Builtin::BI__sync_lock_test_and_set:
4961 case Builtin::BI__sync_lock_release:
4962 case Builtin::BI__sync_swap:
4963 llvm_unreachable("Shouldn't make it through sema");
4964 case Builtin::BI__sync_fetch_and_add_1:
4965 case Builtin::BI__sync_fetch_and_add_2:
4966 case Builtin::BI__sync_fetch_and_add_4:
4967 case Builtin::BI__sync_fetch_and_add_8:
4968 case Builtin::BI__sync_fetch_and_add_16:
4969 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Add, E);
4970 case Builtin::BI__sync_fetch_and_sub_1:
4971 case Builtin::BI__sync_fetch_and_sub_2:
4972 case Builtin::BI__sync_fetch_and_sub_4:
4973 case Builtin::BI__sync_fetch_and_sub_8:
4974 case Builtin::BI__sync_fetch_and_sub_16:
4975 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Sub, E);
4976 case Builtin::BI__sync_fetch_and_or_1:
4977 case Builtin::BI__sync_fetch_and_or_2:
4978 case Builtin::BI__sync_fetch_and_or_4:
4979 case Builtin::BI__sync_fetch_and_or_8:
4980 case Builtin::BI__sync_fetch_and_or_16:
4981 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Or, E);
4982 case Builtin::BI__sync_fetch_and_and_1:
4983 case Builtin::BI__sync_fetch_and_and_2:
4984 case Builtin::BI__sync_fetch_and_and_4:
4985 case Builtin::BI__sync_fetch_and_and_8:
4986 case Builtin::BI__sync_fetch_and_and_16:
4987 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::And, E);
4988 case Builtin::BI__sync_fetch_and_xor_1:
4989 case Builtin::BI__sync_fetch_and_xor_2:
4990 case Builtin::BI__sync_fetch_and_xor_4:
4991 case Builtin::BI__sync_fetch_and_xor_8:
4992 case Builtin::BI__sync_fetch_and_xor_16:
4993 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Xor, E);
4994 case Builtin::BI__sync_fetch_and_nand_1:
4995 case Builtin::BI__sync_fetch_and_nand_2:
4996 case Builtin::BI__sync_fetch_and_nand_4:
4997 case Builtin::BI__sync_fetch_and_nand_8:
4998 case Builtin::BI__sync_fetch_and_nand_16:
4999 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Nand, E);
5000
5001 // Clang extensions: not overloaded yet.
5002 case Builtin::BI__sync_fetch_and_min:
5003 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Min, E);
5004 case Builtin::BI__sync_fetch_and_max:
5005 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Max, E);
5006 case Builtin::BI__sync_fetch_and_umin:
5007 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::UMin, E);
5008 case Builtin::BI__sync_fetch_and_umax:
5009 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::UMax, E);
5010
5011 case Builtin::BI__sync_add_and_fetch_1:
5012 case Builtin::BI__sync_add_and_fetch_2:
5013 case Builtin::BI__sync_add_and_fetch_4:
5014 case Builtin::BI__sync_add_and_fetch_8:
5015 case Builtin::BI__sync_add_and_fetch_16:
5016 return EmitBinaryAtomicPost(CGF&: *this, Kind: llvm::AtomicRMWInst::Add, E,
5017 Op: llvm::Instruction::Add);
5018 case Builtin::BI__sync_sub_and_fetch_1:
5019 case Builtin::BI__sync_sub_and_fetch_2:
5020 case Builtin::BI__sync_sub_and_fetch_4:
5021 case Builtin::BI__sync_sub_and_fetch_8:
5022 case Builtin::BI__sync_sub_and_fetch_16:
5023 return EmitBinaryAtomicPost(CGF&: *this, Kind: llvm::AtomicRMWInst::Sub, E,
5024 Op: llvm::Instruction::Sub);
5025 case Builtin::BI__sync_and_and_fetch_1:
5026 case Builtin::BI__sync_and_and_fetch_2:
5027 case Builtin::BI__sync_and_and_fetch_4:
5028 case Builtin::BI__sync_and_and_fetch_8:
5029 case Builtin::BI__sync_and_and_fetch_16:
5030 return EmitBinaryAtomicPost(CGF&: *this, Kind: llvm::AtomicRMWInst::And, E,
5031 Op: llvm::Instruction::And);
5032 case Builtin::BI__sync_or_and_fetch_1:
5033 case Builtin::BI__sync_or_and_fetch_2:
5034 case Builtin::BI__sync_or_and_fetch_4:
5035 case Builtin::BI__sync_or_and_fetch_8:
5036 case Builtin::BI__sync_or_and_fetch_16:
5037 return EmitBinaryAtomicPost(CGF&: *this, Kind: llvm::AtomicRMWInst::Or, E,
5038 Op: llvm::Instruction::Or);
5039 case Builtin::BI__sync_xor_and_fetch_1:
5040 case Builtin::BI__sync_xor_and_fetch_2:
5041 case Builtin::BI__sync_xor_and_fetch_4:
5042 case Builtin::BI__sync_xor_and_fetch_8:
5043 case Builtin::BI__sync_xor_and_fetch_16:
5044 return EmitBinaryAtomicPost(CGF&: *this, Kind: llvm::AtomicRMWInst::Xor, E,
5045 Op: llvm::Instruction::Xor);
5046 case Builtin::BI__sync_nand_and_fetch_1:
5047 case Builtin::BI__sync_nand_and_fetch_2:
5048 case Builtin::BI__sync_nand_and_fetch_4:
5049 case Builtin::BI__sync_nand_and_fetch_8:
5050 case Builtin::BI__sync_nand_and_fetch_16:
5051 return EmitBinaryAtomicPost(CGF&: *this, Kind: llvm::AtomicRMWInst::Nand, E,
5052 Op: llvm::Instruction::And, Invert: true);
5053
5054 case Builtin::BI__sync_val_compare_and_swap_1:
5055 case Builtin::BI__sync_val_compare_and_swap_2:
5056 case Builtin::BI__sync_val_compare_and_swap_4:
5057 case Builtin::BI__sync_val_compare_and_swap_8:
5058 case Builtin::BI__sync_val_compare_and_swap_16:
5059 return RValue::get(V: MakeAtomicCmpXchgValue(CGF&: *this, E, ReturnBool: false));
5060
5061 case Builtin::BI__sync_bool_compare_and_swap_1:
5062 case Builtin::BI__sync_bool_compare_and_swap_2:
5063 case Builtin::BI__sync_bool_compare_and_swap_4:
5064 case Builtin::BI__sync_bool_compare_and_swap_8:
5065 case Builtin::BI__sync_bool_compare_and_swap_16:
5066 return RValue::get(V: MakeAtomicCmpXchgValue(CGF&: *this, E, ReturnBool: true));
5067
5068 case Builtin::BI__sync_swap_1:
5069 case Builtin::BI__sync_swap_2:
5070 case Builtin::BI__sync_swap_4:
5071 case Builtin::BI__sync_swap_8:
5072 case Builtin::BI__sync_swap_16:
5073 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Xchg, E);
5074
5075 case Builtin::BI__sync_lock_test_and_set_1:
5076 case Builtin::BI__sync_lock_test_and_set_2:
5077 case Builtin::BI__sync_lock_test_and_set_4:
5078 case Builtin::BI__sync_lock_test_and_set_8:
5079 case Builtin::BI__sync_lock_test_and_set_16:
5080 return EmitBinaryAtomic(CGF&: *this, Kind: llvm::AtomicRMWInst::Xchg, E);
5081
5082 case Builtin::BI__sync_lock_release_1:
5083 case Builtin::BI__sync_lock_release_2:
5084 case Builtin::BI__sync_lock_release_4:
5085 case Builtin::BI__sync_lock_release_8:
5086 case Builtin::BI__sync_lock_release_16: {
5087 Address Ptr = CheckAtomicAlignment(CGF&: *this, E);
5088 QualType ElTy = E->getArg(Arg: 0)->getType()->getPointeeType();
5089
5090 llvm::Type *ITy = llvm::IntegerType::get(C&: getLLVMContext(),
5091 NumBits: getContext().getTypeSize(T: ElTy));
5092 llvm::StoreInst *Store =
5093 Builder.CreateStore(Val: llvm::Constant::getNullValue(Ty: ITy), Addr: Ptr);
5094 Store->setAtomic(Ordering: llvm::AtomicOrdering::Release);
5095 return RValue::get(V: nullptr);
5096 }
5097
5098 case Builtin::BI__sync_synchronize: {
5099 // We assume this is supposed to correspond to a C++0x-style
5100 // sequentially-consistent fence (i.e. this is only usable for
5101 // synchronization, not device I/O or anything like that). This intrinsic
5102 // is really badly designed in the sense that in theory, there isn't
5103 // any way to safely use it... but in practice, it mostly works
5104 // to use it with non-atomic loads and stores to get acquire/release
5105 // semantics.
5106 Builder.CreateFence(Ordering: llvm::AtomicOrdering::SequentiallyConsistent);
5107 return RValue::get(V: nullptr);
5108 }
5109
5110 case Builtin::BI__builtin_nontemporal_load:
5111 return RValue::get(V: EmitNontemporalLoad(CGF&: *this, E));
5112 case Builtin::BI__builtin_nontemporal_store:
5113 return RValue::get(V: EmitNontemporalStore(CGF&: *this, E));
5114 case Builtin::BI__c11_atomic_is_lock_free:
5115 case Builtin::BI__atomic_is_lock_free: {
5116 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the
5117 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since
5118 // _Atomic(T) is always properly-aligned.
5119 const char *LibCallName = "__atomic_is_lock_free";
5120 CallArgList Args;
5121 Args.add(rvalue: RValue::get(V: EmitScalarExpr(E: E->getArg(Arg: 0))),
5122 type: getContext().getSizeType());
5123 if (BuiltinID == Builtin::BI__atomic_is_lock_free)
5124 Args.add(rvalue: RValue::get(V: EmitScalarExpr(E: E->getArg(Arg: 1))),
5125 type: getContext().VoidPtrTy);
5126 else
5127 Args.add(rvalue: RValue::get(V: llvm::Constant::getNullValue(Ty: VoidPtrTy)),
5128 type: getContext().VoidPtrTy);
5129 const CGFunctionInfo &FuncInfo =
5130 CGM.getTypes().arrangeBuiltinFunctionCall(resultType: E->getType(), args: Args);
5131 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(Info: FuncInfo);
5132 llvm::FunctionCallee Func = CGM.CreateRuntimeFunction(Ty: FTy, Name: LibCallName);
5133 return EmitCall(CallInfo: FuncInfo, Callee: CGCallee::forDirect(functionPtr: Func),
5134 ReturnValue: ReturnValueSlot(), Args);
5135 }
5136
5137 case Builtin::BI__atomic_thread_fence:
5138 case Builtin::BI__atomic_signal_fence:
5139 case Builtin::BI__c11_atomic_thread_fence:
5140 case Builtin::BI__c11_atomic_signal_fence: {
5141 llvm::SyncScope::ID SSID;
5142 if (BuiltinID == Builtin::BI__atomic_signal_fence ||
5143 BuiltinID == Builtin::BI__c11_atomic_signal_fence)
5144 SSID = llvm::SyncScope::SingleThread;
5145 else
5146 SSID = llvm::SyncScope::System;
5147 Value *Order = EmitScalarExpr(E: E->getArg(Arg: 0));
5148 if (isa<llvm::ConstantInt>(Val: Order)) {
5149 int ord = cast<llvm::ConstantInt>(Val: Order)->getZExtValue();
5150 switch (ord) {
5151 case 0: // memory_order_relaxed
5152 default: // invalid order
5153 break;
5154 case 1: // memory_order_consume
5155 case 2: // memory_order_acquire
5156 Builder.CreateFence(Ordering: llvm::AtomicOrdering::Acquire, SSID);
5157 break;
5158 case 3: // memory_order_release
5159 Builder.CreateFence(Ordering: llvm::AtomicOrdering::Release, SSID);
5160 break;
5161 case 4: // memory_order_acq_rel
5162 Builder.CreateFence(Ordering: llvm::AtomicOrdering::AcquireRelease, SSID);
5163 break;
5164 case 5: // memory_order_seq_cst
5165 Builder.CreateFence(Ordering: llvm::AtomicOrdering::SequentiallyConsistent, SSID);
5166 break;
5167 }
5168 return RValue::get(V: nullptr);
5169 }
5170
5171 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB;
5172 AcquireBB = createBasicBlock(name: "acquire", parent: CurFn);
5173 ReleaseBB = createBasicBlock(name: "release", parent: CurFn);
5174 AcqRelBB = createBasicBlock(name: "acqrel", parent: CurFn);
5175 SeqCstBB = createBasicBlock(name: "seqcst", parent: CurFn);
5176 llvm::BasicBlock *ContBB = createBasicBlock(name: "atomic.continue", parent: CurFn);
5177
5178 Order = Builder.CreateIntCast(V: Order, DestTy: Builder.getInt32Ty(), isSigned: false);
5179 llvm::SwitchInst *SI = Builder.CreateSwitch(V: Order, Dest: ContBB);
5180
5181 Builder.SetInsertPoint(AcquireBB);
5182 Builder.CreateFence(Ordering: llvm::AtomicOrdering::Acquire, SSID);
5183 Builder.CreateBr(Dest: ContBB);
5184 SI->addCase(OnVal: Builder.getInt32(C: 1), Dest: AcquireBB);
5185 SI->addCase(OnVal: Builder.getInt32(C: 2), Dest: AcquireBB);
5186
5187 Builder.SetInsertPoint(ReleaseBB);
5188 Builder.CreateFence(Ordering: llvm::AtomicOrdering::Release, SSID);
5189 Builder.CreateBr(Dest: ContBB);
5190 SI->addCase(OnVal: Builder.getInt32(C: 3), Dest: ReleaseBB);
5191
5192 Builder.SetInsertPoint(AcqRelBB);
5193 Builder.CreateFence(Ordering: llvm::AtomicOrdering::AcquireRelease, SSID);
5194 Builder.CreateBr(Dest: ContBB);
5195 SI->addCase(OnVal: Builder.getInt32(C: 4), Dest: AcqRelBB);
5196
5197 Builder.SetInsertPoint(SeqCstBB);
5198 Builder.CreateFence(Ordering: llvm::AtomicOrdering::SequentiallyConsistent, SSID);
5199 Builder.CreateBr(Dest: ContBB);
5200 SI->addCase(OnVal: Builder.getInt32(C: 5), Dest: SeqCstBB);
5201
5202 Builder.SetInsertPoint(ContBB);
5203 return RValue::get(V: nullptr);
5204 }
5205 case Builtin::BI__scoped_atomic_thread_fence: {
5206 auto ScopeModel = AtomicScopeModel::create(K: AtomicScopeModelKind::Generic);
5207
5208 Value *Order = EmitScalarExpr(E: E->getArg(Arg: 0));
5209 Value *Scope = EmitScalarExpr(E: E->getArg(Arg: 1));
5210 auto Ord = dyn_cast<llvm::ConstantInt>(Val: Order);
5211 auto Scp = dyn_cast<llvm::ConstantInt>(Val: Scope);
5212 if (Ord && Scp) {
5213 SyncScope SS = ScopeModel->isValid(S: Scp->getZExtValue())
5214 ? ScopeModel->map(S: Scp->getZExtValue())
5215 : ScopeModel->map(S: ScopeModel->getFallBackValue());
5216 switch (Ord->getZExtValue()) {
5217 case 0: // memory_order_relaxed
5218 default: // invalid order
5219 break;
5220 case 1: // memory_order_consume
5221 case 2: // memory_order_acquire
5222 Builder.CreateFence(
5223 Ordering: llvm::AtomicOrdering::Acquire,
5224 SSID: getTargetHooks().getLLVMSyncScopeID(LangOpts: getLangOpts(), Scope: SS,
5225 Ordering: llvm::AtomicOrdering::Acquire,
5226 Ctx&: getLLVMContext()));
5227 break;
5228 case 3: // memory_order_release
5229 Builder.CreateFence(
5230 Ordering: llvm::AtomicOrdering::Release,
5231 SSID: getTargetHooks().getLLVMSyncScopeID(LangOpts: getLangOpts(), Scope: SS,
5232 Ordering: llvm::AtomicOrdering::Release,
5233 Ctx&: getLLVMContext()));
5234 break;
5235 case 4: // memory_order_acq_rel
5236 Builder.CreateFence(Ordering: llvm::AtomicOrdering::AcquireRelease,
5237 SSID: getTargetHooks().getLLVMSyncScopeID(
5238 LangOpts: getLangOpts(), Scope: SS,
5239 Ordering: llvm::AtomicOrdering::AcquireRelease,
5240 Ctx&: getLLVMContext()));
5241 break;
5242 case 5: // memory_order_seq_cst
5243 Builder.CreateFence(Ordering: llvm::AtomicOrdering::SequentiallyConsistent,
5244 SSID: getTargetHooks().getLLVMSyncScopeID(
5245 LangOpts: getLangOpts(), Scope: SS,
5246 Ordering: llvm::AtomicOrdering::SequentiallyConsistent,
5247 Ctx&: getLLVMContext()));
5248 break;
5249 }
5250 return RValue::get(V: nullptr);
5251 }
5252
5253 llvm::BasicBlock *ContBB = createBasicBlock(name: "atomic.scope.continue", parent: CurFn);
5254
5255 llvm::SmallVector<std::pair<llvm::BasicBlock *, llvm::AtomicOrdering>>
5256 OrderBBs;
5257 if (Ord) {
5258 switch (Ord->getZExtValue()) {
5259 case 0: // memory_order_relaxed
5260 default: // invalid order
5261 ContBB->eraseFromParent();
5262 return RValue::get(V: nullptr);
5263 case 1: // memory_order_consume
5264 case 2: // memory_order_acquire
5265 OrderBBs.emplace_back(Args: Builder.GetInsertBlock(),
5266 Args: llvm::AtomicOrdering::Acquire);
5267 break;
5268 case 3: // memory_order_release
5269 OrderBBs.emplace_back(Args: Builder.GetInsertBlock(),
5270 Args: llvm::AtomicOrdering::Release);
5271 break;
5272 case 4: // memory_order_acq_rel
5273 OrderBBs.emplace_back(Args: Builder.GetInsertBlock(),
5274 Args: llvm::AtomicOrdering::AcquireRelease);
5275 break;
5276 case 5: // memory_order_seq_cst
5277 OrderBBs.emplace_back(Args: Builder.GetInsertBlock(),
5278 Args: llvm::AtomicOrdering::SequentiallyConsistent);
5279 break;
5280 }
5281 } else {
5282 llvm::BasicBlock *AcquireBB = createBasicBlock(name: "acquire", parent: CurFn);
5283 llvm::BasicBlock *ReleaseBB = createBasicBlock(name: "release", parent: CurFn);
5284 llvm::BasicBlock *AcqRelBB = createBasicBlock(name: "acqrel", parent: CurFn);
5285 llvm::BasicBlock *SeqCstBB = createBasicBlock(name: "seqcst", parent: CurFn);
5286
5287 Order = Builder.CreateIntCast(V: Order, DestTy: Builder.getInt32Ty(), isSigned: false);
5288 llvm::SwitchInst *SI = Builder.CreateSwitch(V: Order, Dest: ContBB);
5289 SI->addCase(OnVal: Builder.getInt32(C: 1), Dest: AcquireBB);
5290 SI->addCase(OnVal: Builder.getInt32(C: 2), Dest: AcquireBB);
5291 SI->addCase(OnVal: Builder.getInt32(C: 3), Dest: ReleaseBB);
5292 SI->addCase(OnVal: Builder.getInt32(C: 4), Dest: AcqRelBB);
5293 SI->addCase(OnVal: Builder.getInt32(C: 5), Dest: SeqCstBB);
5294
5295 OrderBBs.emplace_back(Args&: AcquireBB, Args: llvm::AtomicOrdering::Acquire);
5296 OrderBBs.emplace_back(Args&: ReleaseBB, Args: llvm::AtomicOrdering::Release);
5297 OrderBBs.emplace_back(Args&: AcqRelBB, Args: llvm::AtomicOrdering::AcquireRelease);
5298 OrderBBs.emplace_back(Args&: SeqCstBB,
5299 Args: llvm::AtomicOrdering::SequentiallyConsistent);
5300 }
5301
5302 for (auto &[OrderBB, Ordering] : OrderBBs) {
5303 Builder.SetInsertPoint(OrderBB);
5304 if (Scp) {
5305 SyncScope SS = ScopeModel->isValid(S: Scp->getZExtValue())
5306 ? ScopeModel->map(S: Scp->getZExtValue())
5307 : ScopeModel->map(S: ScopeModel->getFallBackValue());
5308 Builder.CreateFence(Ordering,
5309 SSID: getTargetHooks().getLLVMSyncScopeID(
5310 LangOpts: getLangOpts(), Scope: SS, Ordering, Ctx&: getLLVMContext()));
5311 Builder.CreateBr(Dest: ContBB);
5312 } else {
5313 llvm::DenseMap<unsigned, llvm::BasicBlock *> BBs;
5314 for (unsigned Scp : ScopeModel->getRuntimeValues())
5315 BBs[Scp] = createBasicBlock(name: getAsString(S: ScopeModel->map(S: Scp)), parent: CurFn);
5316
5317 auto *SC = Builder.CreateIntCast(V: Scope, DestTy: Builder.getInt32Ty(), isSigned: false);
5318 llvm::SwitchInst *SI = Builder.CreateSwitch(V: SC, Dest: ContBB);
5319 for (unsigned Scp : ScopeModel->getRuntimeValues()) {
5320 auto *B = BBs[Scp];
5321 SI->addCase(OnVal: Builder.getInt32(C: Scp), Dest: B);
5322
5323 Builder.SetInsertPoint(B);
5324 Builder.CreateFence(Ordering, SSID: getTargetHooks().getLLVMSyncScopeID(
5325 LangOpts: getLangOpts(), Scope: ScopeModel->map(S: Scp),
5326 Ordering, Ctx&: getLLVMContext()));
5327 Builder.CreateBr(Dest: ContBB);
5328 }
5329 }
5330 }
5331
5332 Builder.SetInsertPoint(ContBB);
5333 return RValue::get(V: nullptr);
5334 }
5335
5336 case Builtin::BI__builtin_signbit:
5337 case Builtin::BI__builtin_signbitf:
5338 case Builtin::BI__builtin_signbitl: {
5339 return RValue::get(
5340 V: Builder.CreateZExt(V: EmitSignBit(CGF&: *this, V: EmitScalarExpr(E: E->getArg(Arg: 0))),
5341 DestTy: ConvertType(T: E->getType())));
5342 }
5343 case Builtin::BI__warn_memset_zero_len:
5344 return RValue::getIgnored();
5345 case Builtin::BI__annotation: {
5346 // Re-encode each wide string to UTF8 and make an MDString.
5347 SmallVector<Metadata *, 1> Strings;
5348 for (const Expr *Arg : E->arguments()) {
5349 const auto *Str = cast<StringLiteral>(Val: Arg->IgnoreParenCasts());
5350 assert(Str->getCharByteWidth() == 2);
5351 StringRef WideBytes = Str->getBytes();
5352 std::string StrUtf8;
5353 if (!convertUTF16ToUTF8String(
5354 SrcBytes: ArrayRef(WideBytes.data(), WideBytes.size()), Out&: StrUtf8)) {
5355 CGM.ErrorUnsupported(S: E, Type: "non-UTF16 __annotation argument");
5356 continue;
5357 }
5358 Strings.push_back(Elt: llvm::MDString::get(Context&: getLLVMContext(), Str: StrUtf8));
5359 }
5360
5361 // Build and MDTuple of MDStrings and emit the intrinsic call.
5362 llvm::Function *F = CGM.getIntrinsic(IID: Intrinsic::codeview_annotation, Tys: {});
5363 MDTuple *StrTuple = MDTuple::get(Context&: getLLVMContext(), MDs: Strings);
5364 Builder.CreateCall(Callee: F, Args: MetadataAsValue::get(Context&: getLLVMContext(), MD: StrTuple));
5365 return RValue::getIgnored();
5366 }
5367 case Builtin::BI__builtin_annotation: {
5368 llvm::Value *AnnVal = EmitScalarExpr(E: E->getArg(Arg: 0));
5369 llvm::Function *F = CGM.getIntrinsic(
5370 IID: Intrinsic::annotation, Tys: {AnnVal->getType(), CGM.ConstGlobalsPtrTy});
5371
5372 // Get the annotation string, go through casts. Sema requires this to be a
5373 // non-wide string literal, potentially casted, so the cast<> is safe.
5374 const Expr *AnnotationStrExpr = E->getArg(Arg: 1)->IgnoreParenCasts();
5375 StringRef Str = cast<StringLiteral>(Val: AnnotationStrExpr)->getString();
5376 return RValue::get(
5377 V: EmitAnnotationCall(AnnotationFn: F, AnnotatedVal: AnnVal, AnnotationStr: Str, Location: E->getExprLoc(), Attr: nullptr));
5378 }
5379 case Builtin::BI__builtin_addcb:
5380 case Builtin::BI__builtin_addcs:
5381 case Builtin::BI__builtin_addc:
5382 case Builtin::BI__builtin_addcl:
5383 case Builtin::BI__builtin_addcll:
5384 case Builtin::BI__builtin_subcb:
5385 case Builtin::BI__builtin_subcs:
5386 case Builtin::BI__builtin_subc:
5387 case Builtin::BI__builtin_subcl:
5388 case Builtin::BI__builtin_subcll: {
5389
5390 // We translate all of these builtins from expressions of the form:
5391 // int x = ..., y = ..., carryin = ..., carryout, result;
5392 // result = __builtin_addc(x, y, carryin, &carryout);
5393 //
5394 // to LLVM IR of the form:
5395 //
5396 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
5397 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0
5398 // %carry1 = extractvalue {i32, i1} %tmp1, 1
5399 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1,
5400 // i32 %carryin)
5401 // %result = extractvalue {i32, i1} %tmp2, 0
5402 // %carry2 = extractvalue {i32, i1} %tmp2, 1
5403 // %tmp3 = or i1 %carry1, %carry2
5404 // %tmp4 = zext i1 %tmp3 to i32
5405 // store i32 %tmp4, i32* %carryout
5406
5407 // Scalarize our inputs.
5408 llvm::Value *X = EmitScalarExpr(E: E->getArg(Arg: 0));
5409 llvm::Value *Y = EmitScalarExpr(E: E->getArg(Arg: 1));
5410 llvm::Value *Carryin = EmitScalarExpr(E: E->getArg(Arg: 2));
5411 Address CarryOutPtr = EmitPointerWithAlignment(Addr: E->getArg(Arg: 3));
5412
5413 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow.
5414 Intrinsic::ID IntrinsicId;
5415 switch (BuiltinID) {
5416 default: llvm_unreachable("Unknown multiprecision builtin id.");
5417 case Builtin::BI__builtin_addcb:
5418 case Builtin::BI__builtin_addcs:
5419 case Builtin::BI__builtin_addc:
5420 case Builtin::BI__builtin_addcl:
5421 case Builtin::BI__builtin_addcll:
5422 IntrinsicId = Intrinsic::uadd_with_overflow;
5423 break;
5424 case Builtin::BI__builtin_subcb:
5425 case Builtin::BI__builtin_subcs:
5426 case Builtin::BI__builtin_subc:
5427 case Builtin::BI__builtin_subcl:
5428 case Builtin::BI__builtin_subcll:
5429 IntrinsicId = Intrinsic::usub_with_overflow;
5430 break;
5431 }
5432
5433 // Construct our resulting LLVM IR expression.
5434 llvm::Value *Carry1;
5435 llvm::Value *Sum1 = EmitOverflowIntrinsic(CGF&: *this, IntrinsicID: IntrinsicId,
5436 X, Y, Carry&: Carry1);
5437 llvm::Value *Carry2;
5438 llvm::Value *Sum2 = EmitOverflowIntrinsic(CGF&: *this, IntrinsicID: IntrinsicId,
5439 X: Sum1, Y: Carryin, Carry&: Carry2);
5440 llvm::Value *CarryOut = Builder.CreateZExt(V: Builder.CreateOr(LHS: Carry1, RHS: Carry2),
5441 DestTy: X->getType());
5442 Builder.CreateStore(Val: CarryOut, Addr: CarryOutPtr);
5443 return RValue::get(V: Sum2);
5444 }
5445
5446 case Builtin::BI__builtin_add_overflow:
5447 case Builtin::BI__builtin_sub_overflow:
5448 case Builtin::BI__builtin_mul_overflow: {
5449 const clang::Expr *LeftArg = E->getArg(Arg: 0);
5450 const clang::Expr *RightArg = E->getArg(Arg: 1);
5451 const clang::Expr *ResultArg = E->getArg(Arg: 2);
5452
5453 clang::QualType ResultQTy =
5454 ResultArg->getType()->castAs<PointerType>()->getPointeeType();
5455
5456 WidthAndSignedness LeftInfo =
5457 getIntegerWidthAndSignedness(context: CGM.getContext(), Type: LeftArg->getType());
5458 WidthAndSignedness RightInfo =
5459 getIntegerWidthAndSignedness(context: CGM.getContext(), Type: RightArg->getType());
5460 WidthAndSignedness ResultInfo =
5461 getIntegerWidthAndSignedness(context: CGM.getContext(), Type: ResultQTy);
5462
5463 // Handle mixed-sign multiplication as a special case, because adding
5464 // runtime or backend support for our generic irgen would be too expensive.
5465 if (isSpecialMixedSignMultiply(BuiltinID, Op1Info: LeftInfo, Op2Info: RightInfo, ResultInfo))
5466 return EmitCheckedMixedSignMultiply(CGF&: *this, Op1: LeftArg, Op1Info: LeftInfo, Op2: RightArg,
5467 Op2Info: RightInfo, ResultArg, ResultQTy,
5468 ResultInfo);
5469
5470 if (isSpecialUnsignedMultiplySignedResult(BuiltinID, Op1Info: LeftInfo, Op2Info: RightInfo,
5471 ResultInfo))
5472 return EmitCheckedUnsignedMultiplySignedResult(
5473 CGF&: *this, Op1: LeftArg, Op1Info: LeftInfo, Op2: RightArg, Op2Info: RightInfo, ResultArg, ResultQTy,
5474 ResultInfo);
5475
5476 WidthAndSignedness EncompassingInfo =
5477 EncompassingIntegerType(Types: {LeftInfo, RightInfo, ResultInfo});
5478
5479 llvm::Type *EncompassingLLVMTy =
5480 llvm::IntegerType::get(C&: CGM.getLLVMContext(), NumBits: EncompassingInfo.Width);
5481
5482 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(T: ResultQTy);
5483
5484 Intrinsic::ID IntrinsicId;
5485 switch (BuiltinID) {
5486 default:
5487 llvm_unreachable("Unknown overflow builtin id.");
5488 case Builtin::BI__builtin_add_overflow:
5489 IntrinsicId = EncompassingInfo.Signed ? Intrinsic::sadd_with_overflow
5490 : Intrinsic::uadd_with_overflow;
5491 break;
5492 case Builtin::BI__builtin_sub_overflow:
5493 IntrinsicId = EncompassingInfo.Signed ? Intrinsic::ssub_with_overflow
5494 : Intrinsic::usub_with_overflow;
5495 break;
5496 case Builtin::BI__builtin_mul_overflow:
5497 IntrinsicId = EncompassingInfo.Signed ? Intrinsic::smul_with_overflow
5498 : Intrinsic::umul_with_overflow;
5499 break;
5500 }
5501
5502 llvm::Value *Left = EmitScalarExpr(E: LeftArg);
5503 llvm::Value *Right = EmitScalarExpr(E: RightArg);
5504 Address ResultPtr = EmitPointerWithAlignment(Addr: ResultArg);
5505
5506 // Extend each operand to the encompassing type.
5507 Left = Builder.CreateIntCast(V: Left, DestTy: EncompassingLLVMTy, isSigned: LeftInfo.Signed);
5508 Right = Builder.CreateIntCast(V: Right, DestTy: EncompassingLLVMTy, isSigned: RightInfo.Signed);
5509
5510 // Perform the operation on the extended values.
5511 llvm::Value *Overflow, *Result;
5512 Result = EmitOverflowIntrinsic(CGF&: *this, IntrinsicID: IntrinsicId, X: Left, Y: Right, Carry&: Overflow);
5513
5514 if (EncompassingInfo.Width > ResultInfo.Width) {
5515 // The encompassing type is wider than the result type, so we need to
5516 // truncate it.
5517 llvm::Value *ResultTrunc = Builder.CreateTrunc(V: Result, DestTy: ResultLLVMTy);
5518
5519 // To see if the truncation caused an overflow, we will extend
5520 // the result and then compare it to the original result.
5521 llvm::Value *ResultTruncExt = Builder.CreateIntCast(
5522 V: ResultTrunc, DestTy: EncompassingLLVMTy, isSigned: ResultInfo.Signed);
5523 llvm::Value *TruncationOverflow =
5524 Builder.CreateICmpNE(LHS: Result, RHS: ResultTruncExt);
5525
5526 Overflow = Builder.CreateOr(LHS: Overflow, RHS: TruncationOverflow);
5527 Result = ResultTrunc;
5528 }
5529
5530 // Finally, store the result using the pointer.
5531 bool isVolatile =
5532 ResultArg->getType()->getPointeeType().isVolatileQualified();
5533 Builder.CreateStore(Val: EmitToMemory(Value: Result, Ty: ResultQTy), Addr: ResultPtr, IsVolatile: isVolatile);
5534
5535 return RValue::get(V: Overflow);
5536 }
5537
5538 case Builtin::BI__builtin_uadd_overflow:
5539 case Builtin::BI__builtin_uaddl_overflow:
5540 case Builtin::BI__builtin_uaddll_overflow:
5541 case Builtin::BI__builtin_usub_overflow:
5542 case Builtin::BI__builtin_usubl_overflow:
5543 case Builtin::BI__builtin_usubll_overflow:
5544 case Builtin::BI__builtin_umul_overflow:
5545 case Builtin::BI__builtin_umull_overflow:
5546 case Builtin::BI__builtin_umulll_overflow:
5547 case Builtin::BI__builtin_sadd_overflow:
5548 case Builtin::BI__builtin_saddl_overflow:
5549 case Builtin::BI__builtin_saddll_overflow:
5550 case Builtin::BI__builtin_ssub_overflow:
5551 case Builtin::BI__builtin_ssubl_overflow:
5552 case Builtin::BI__builtin_ssubll_overflow:
5553 case Builtin::BI__builtin_smul_overflow:
5554 case Builtin::BI__builtin_smull_overflow:
5555 case Builtin::BI__builtin_smulll_overflow: {
5556
5557 // We translate all of these builtins directly to the relevant llvm IR node.
5558
5559 // Scalarize our inputs.
5560 llvm::Value *X = EmitScalarExpr(E: E->getArg(Arg: 0));
5561 llvm::Value *Y = EmitScalarExpr(E: E->getArg(Arg: 1));
5562 Address SumOutPtr = EmitPointerWithAlignment(Addr: E->getArg(Arg: 2));
5563
5564 // Decide which of the overflow intrinsics we are lowering to:
5565 Intrinsic::ID IntrinsicId;
5566 switch (BuiltinID) {
5567 default: llvm_unreachable("Unknown overflow builtin id.");
5568 case Builtin::BI__builtin_uadd_overflow:
5569 case Builtin::BI__builtin_uaddl_overflow:
5570 case Builtin::BI__builtin_uaddll_overflow:
5571 IntrinsicId = Intrinsic::uadd_with_overflow;
5572 break;
5573 case Builtin::BI__builtin_usub_overflow:
5574 case Builtin::BI__builtin_usubl_overflow:
5575 case Builtin::BI__builtin_usubll_overflow:
5576 IntrinsicId = Intrinsic::usub_with_overflow;
5577 break;
5578 case Builtin::BI__builtin_umul_overflow:
5579 case Builtin::BI__builtin_umull_overflow:
5580 case Builtin::BI__builtin_umulll_overflow:
5581 IntrinsicId = Intrinsic::umul_with_overflow;
5582 break;
5583 case Builtin::BI__builtin_sadd_overflow:
5584 case Builtin::BI__builtin_saddl_overflow:
5585 case Builtin::BI__builtin_saddll_overflow:
5586 IntrinsicId = Intrinsic::sadd_with_overflow;
5587 break;
5588 case Builtin::BI__builtin_ssub_overflow:
5589 case Builtin::BI__builtin_ssubl_overflow:
5590 case Builtin::BI__builtin_ssubll_overflow:
5591 IntrinsicId = Intrinsic::ssub_with_overflow;
5592 break;
5593 case Builtin::BI__builtin_smul_overflow:
5594 case Builtin::BI__builtin_smull_overflow:
5595 case Builtin::BI__builtin_smulll_overflow:
5596 IntrinsicId = Intrinsic::smul_with_overflow;
5597 break;
5598 }
5599
5600
5601 llvm::Value *Carry;
5602 llvm::Value *Sum = EmitOverflowIntrinsic(CGF&: *this, IntrinsicID: IntrinsicId, X, Y, Carry);
5603 Builder.CreateStore(Val: Sum, Addr: SumOutPtr);
5604
5605 return RValue::get(V: Carry);
5606 }
5607 case Builtin::BIaddressof:
5608 case Builtin::BI__addressof:
5609 case Builtin::BI__builtin_addressof:
5610 return RValue::get(V: EmitLValue(E: E->getArg(Arg: 0)).getPointer(CGF&: *this));
5611 case Builtin::BI__builtin_function_start:
5612 return RValue::get(V: CGM.GetFunctionStart(
5613 Decl: E->getArg(Arg: 0)->getAsBuiltinConstantDeclRef(Context: CGM.getContext())));
5614 case Builtin::BI__builtin_operator_new:
5615 return EmitBuiltinNewDeleteCall(
5616 Type: E->getCallee()->getType()->castAs<FunctionProtoType>(), TheCallExpr: E, IsDelete: false);
5617 case Builtin::BI__builtin_operator_delete:
5618 EmitBuiltinNewDeleteCall(
5619 Type: E->getCallee()->getType()->castAs<FunctionProtoType>(), TheCallExpr: E, IsDelete: true);
5620 return RValue::get(V: nullptr);
5621
5622 case Builtin::BI__builtin_is_aligned:
5623 return EmitBuiltinIsAligned(E);
5624 case Builtin::BI__builtin_align_up:
5625 return EmitBuiltinAlignTo(E, AlignUp: true);
5626 case Builtin::BI__builtin_align_down:
5627 return EmitBuiltinAlignTo(E, AlignUp: false);
5628
5629 case Builtin::BI__noop:
5630 // __noop always evaluates to an integer literal zero.
5631 return RValue::get(V: ConstantInt::get(Ty: IntTy, V: 0));
5632 case Builtin::BI__builtin_call_with_static_chain: {
5633 const CallExpr *Call = cast<CallExpr>(Val: E->getArg(Arg: 0));
5634 const Expr *Chain = E->getArg(Arg: 1);
5635 return EmitCall(FnType: Call->getCallee()->getType(),
5636 Callee: EmitCallee(E: Call->getCallee()), E: Call, ReturnValue,
5637 Chain: EmitScalarExpr(E: Chain));
5638 }
5639 case Builtin::BI_InterlockedExchange8:
5640 case Builtin::BI_InterlockedExchange16:
5641 case Builtin::BI_InterlockedExchange:
5642 case Builtin::BI_InterlockedExchangePointer:
5643 return RValue::get(
5644 V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedExchange, E));
5645 case Builtin::BI_InterlockedCompareExchangePointer:
5646 return RValue::get(
5647 V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedCompareExchange, E));
5648 case Builtin::BI_InterlockedCompareExchangePointer_nf:
5649 return RValue::get(
5650 V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedCompareExchange_nf, E));
5651 case Builtin::BI_InterlockedCompareExchange8:
5652 case Builtin::BI_InterlockedCompareExchange16:
5653 case Builtin::BI_InterlockedCompareExchange:
5654 case Builtin::BI_InterlockedCompareExchange64:
5655 return RValue::get(V: EmitAtomicCmpXchgForMSIntrin(CGF&: *this, E));
5656 case Builtin::BI_InterlockedIncrement16:
5657 case Builtin::BI_InterlockedIncrement:
5658 return RValue::get(
5659 V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedIncrement, E));
5660 case Builtin::BI_InterlockedDecrement16:
5661 case Builtin::BI_InterlockedDecrement:
5662 return RValue::get(
5663 V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedDecrement, E));
5664 case Builtin::BI_InterlockedAnd8:
5665 case Builtin::BI_InterlockedAnd16:
5666 case Builtin::BI_InterlockedAnd:
5667 return RValue::get(V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedAnd, E));
5668 case Builtin::BI_InterlockedExchangeAdd8:
5669 case Builtin::BI_InterlockedExchangeAdd16:
5670 case Builtin::BI_InterlockedExchangeAdd:
5671 return RValue::get(
5672 V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedExchangeAdd, E));
5673 case Builtin::BI_InterlockedExchangeSub8:
5674 case Builtin::BI_InterlockedExchangeSub16:
5675 case Builtin::BI_InterlockedExchangeSub:
5676 return RValue::get(
5677 V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedExchangeSub, E));
5678 case Builtin::BI_InterlockedOr8:
5679 case Builtin::BI_InterlockedOr16:
5680 case Builtin::BI_InterlockedOr:
5681 return RValue::get(V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedOr, E));
5682 case Builtin::BI_InterlockedXor8:
5683 case Builtin::BI_InterlockedXor16:
5684 case Builtin::BI_InterlockedXor:
5685 return RValue::get(V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::_InterlockedXor, E));
5686
5687 case Builtin::BI_bittest64:
5688 case Builtin::BI_bittest:
5689 case Builtin::BI_bittestandcomplement64:
5690 case Builtin::BI_bittestandcomplement:
5691 case Builtin::BI_bittestandreset64:
5692 case Builtin::BI_bittestandreset:
5693 case Builtin::BI_bittestandset64:
5694 case Builtin::BI_bittestandset:
5695 case Builtin::BI_interlockedbittestandreset:
5696 case Builtin::BI_interlockedbittestandreset64:
5697 case Builtin::BI_interlockedbittestandreset64_acq:
5698 case Builtin::BI_interlockedbittestandreset64_rel:
5699 case Builtin::BI_interlockedbittestandreset64_nf:
5700 case Builtin::BI_interlockedbittestandset64:
5701 case Builtin::BI_interlockedbittestandset64_acq:
5702 case Builtin::BI_interlockedbittestandset64_rel:
5703 case Builtin::BI_interlockedbittestandset64_nf:
5704 case Builtin::BI_interlockedbittestandset:
5705 case Builtin::BI_interlockedbittestandset_acq:
5706 case Builtin::BI_interlockedbittestandset_rel:
5707 case Builtin::BI_interlockedbittestandset_nf:
5708 case Builtin::BI_interlockedbittestandreset_acq:
5709 case Builtin::BI_interlockedbittestandreset_rel:
5710 case Builtin::BI_interlockedbittestandreset_nf:
5711 return RValue::get(V: EmitBitTestIntrinsic(CGF&: *this, BuiltinID, E));
5712
5713 // These builtins exist to emit regular volatile loads and stores not
5714 // affected by the -fms-volatile setting.
5715 case Builtin::BI__iso_volatile_load8:
5716 case Builtin::BI__iso_volatile_load16:
5717 case Builtin::BI__iso_volatile_load32:
5718 case Builtin::BI__iso_volatile_load64:
5719 return RValue::get(V: EmitISOVolatileLoad(CGF&: *this, E));
5720 case Builtin::BI__iso_volatile_store8:
5721 case Builtin::BI__iso_volatile_store16:
5722 case Builtin::BI__iso_volatile_store32:
5723 case Builtin::BI__iso_volatile_store64:
5724 return RValue::get(V: EmitISOVolatileStore(CGF&: *this, E));
5725
5726 case Builtin::BI__builtin_ptrauth_sign_constant:
5727 return RValue::get(V: ConstantEmitter(*this).emitAbstract(E, T: E->getType()));
5728
5729 case Builtin::BI__builtin_ptrauth_auth:
5730 case Builtin::BI__builtin_ptrauth_auth_and_resign:
5731 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
5732 case Builtin::BI__builtin_ptrauth_blend_discriminator:
5733 case Builtin::BI__builtin_ptrauth_sign_generic_data:
5734 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
5735 case Builtin::BI__builtin_ptrauth_strip: {
5736 // Emit the arguments.
5737 SmallVector<llvm::Value *, 6> Args;
5738 for (auto argExpr : E->arguments())
5739 Args.push_back(Elt: EmitScalarExpr(E: argExpr));
5740
5741 // Cast the value to intptr_t, saving its original type.
5742 llvm::Type *OrigValueType = Args[0]->getType();
5743 if (OrigValueType->isPointerTy())
5744 Args[0] = Builder.CreatePtrToInt(V: Args[0], DestTy: IntPtrTy);
5745
5746 switch (BuiltinID) {
5747 case Builtin::BI__builtin_ptrauth_auth_and_resign:
5748 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
5749 if (Args[4]->getType()->isPointerTy())
5750 Args[4] = Builder.CreatePtrToInt(V: Args[4], DestTy: IntPtrTy);
5751 [[fallthrough]];
5752
5753 case Builtin::BI__builtin_ptrauth_auth:
5754 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
5755 if (Args[2]->getType()->isPointerTy())
5756 Args[2] = Builder.CreatePtrToInt(V: Args[2], DestTy: IntPtrTy);
5757 break;
5758
5759 case Builtin::BI__builtin_ptrauth_sign_generic_data:
5760 if (Args[1]->getType()->isPointerTy())
5761 Args[1] = Builder.CreatePtrToInt(V: Args[1], DestTy: IntPtrTy);
5762 break;
5763
5764 case Builtin::BI__builtin_ptrauth_blend_discriminator:
5765 case Builtin::BI__builtin_ptrauth_strip:
5766 break;
5767 }
5768
5769 // Call the intrinsic.
5770 auto IntrinsicID = [&]() -> unsigned {
5771 switch (BuiltinID) {
5772 case Builtin::BI__builtin_ptrauth_auth:
5773 return Intrinsic::ptrauth_auth;
5774 case Builtin::BI__builtin_ptrauth_auth_and_resign:
5775 return Intrinsic::ptrauth_resign;
5776 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
5777 return Intrinsic::ptrauth_resign_load_relative;
5778 case Builtin::BI__builtin_ptrauth_blend_discriminator:
5779 return Intrinsic::ptrauth_blend;
5780 case Builtin::BI__builtin_ptrauth_sign_generic_data:
5781 return Intrinsic::ptrauth_sign_generic;
5782 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
5783 return Intrinsic::ptrauth_sign;
5784 case Builtin::BI__builtin_ptrauth_strip:
5785 return Intrinsic::ptrauth_strip;
5786 }
5787 llvm_unreachable("bad ptrauth intrinsic");
5788 }();
5789 auto Intrinsic = CGM.getIntrinsic(IID: IntrinsicID);
5790 llvm::Value *Result = EmitRuntimeCall(callee: Intrinsic, args: Args);
5791
5792 if (BuiltinID != Builtin::BI__builtin_ptrauth_sign_generic_data &&
5793 BuiltinID != Builtin::BI__builtin_ptrauth_blend_discriminator &&
5794 OrigValueType->isPointerTy()) {
5795 Result = Builder.CreateIntToPtr(V: Result, DestTy: OrigValueType);
5796 }
5797 return RValue::get(V: Result);
5798 }
5799
5800 case Builtin::BI__builtin_get_vtable_pointer: {
5801 const Expr *Target = E->getArg(Arg: 0);
5802 QualType TargetType = Target->getType();
5803 const CXXRecordDecl *Decl = TargetType->getPointeeCXXRecordDecl();
5804 assert(Decl);
5805 auto ThisAddress = EmitPointerWithAlignment(Addr: Target);
5806 assert(ThisAddress.isValid());
5807 llvm::Value *VTablePointer =
5808 GetVTablePtr(This: ThisAddress, VTableTy: Int8PtrTy, VTableClass: Decl, AuthMode: VTableAuthMode::MustTrap);
5809 return RValue::get(V: VTablePointer);
5810 }
5811
5812 case Builtin::BI__exception_code:
5813 case Builtin::BI_exception_code:
5814 return RValue::get(V: EmitSEHExceptionCode());
5815 case Builtin::BI__exception_info:
5816 case Builtin::BI_exception_info:
5817 return RValue::get(V: EmitSEHExceptionInfo());
5818 case Builtin::BI__abnormal_termination:
5819 case Builtin::BI_abnormal_termination:
5820 return RValue::get(V: EmitSEHAbnormalTermination());
5821 case Builtin::BI_setjmpex:
5822 if (getTarget().getTriple().isOSMSVCRT() && E->getNumArgs() == 1 &&
5823 E->getArg(Arg: 0)->getType()->isPointerType())
5824 return EmitMSVCRTSetJmp(CGF&: *this, SJKind: MSVCSetJmpKind::_setjmpex, E);
5825 break;
5826 case Builtin::BI_setjmp:
5827 if (getTarget().getTriple().isOSMSVCRT() && E->getNumArgs() == 1 &&
5828 E->getArg(Arg: 0)->getType()->isPointerType()) {
5829 if (getTarget().getTriple().getArch() == llvm::Triple::x86)
5830 return EmitMSVCRTSetJmp(CGF&: *this, SJKind: MSVCSetJmpKind::_setjmp3, E);
5831 else if (getTarget().getTriple().getArch() == llvm::Triple::aarch64)
5832 return EmitMSVCRTSetJmp(CGF&: *this, SJKind: MSVCSetJmpKind::_setjmpex, E);
5833 return EmitMSVCRTSetJmp(CGF&: *this, SJKind: MSVCSetJmpKind::_setjmp, E);
5834 }
5835 break;
5836
5837 // C++ std:: builtins.
5838 case Builtin::BImove:
5839 case Builtin::BImove_if_noexcept:
5840 case Builtin::BIforward:
5841 case Builtin::BIforward_like:
5842 case Builtin::BIas_const:
5843 return RValue::get(V: EmitLValue(E: E->getArg(Arg: 0)).getPointer(CGF&: *this));
5844 case Builtin::BI__GetExceptionInfo: {
5845 if (llvm::GlobalVariable *GV =
5846 CGM.getCXXABI().getThrowInfo(T: FD->getParamDecl(i: 0)->getType()))
5847 return RValue::get(V: GV);
5848 break;
5849 }
5850
5851 case Builtin::BI__fastfail:
5852 return RValue::get(V: EmitMSVCBuiltinExpr(BuiltinID: MSVCIntrin::__fastfail, E));
5853
5854 case Builtin::BI__builtin_coro_id:
5855 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_id);
5856 case Builtin::BI__builtin_coro_promise:
5857 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_promise);
5858 case Builtin::BI__builtin_coro_resume:
5859 EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_resume);
5860 return RValue::get(V: nullptr);
5861 case Builtin::BI__builtin_coro_frame:
5862 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_frame);
5863 case Builtin::BI__builtin_coro_noop:
5864 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_noop);
5865 case Builtin::BI__builtin_coro_free:
5866 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_free);
5867 case Builtin::BI__builtin_coro_destroy:
5868 EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_destroy);
5869 return RValue::get(V: nullptr);
5870 case Builtin::BI__builtin_coro_done:
5871 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_done);
5872 case Builtin::BI__builtin_coro_alloc:
5873 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_alloc);
5874 case Builtin::BI__builtin_coro_begin:
5875 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_begin);
5876 case Builtin::BI__builtin_coro_end:
5877 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_end);
5878 case Builtin::BI__builtin_coro_suspend:
5879 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_suspend);
5880 case Builtin::BI__builtin_coro_size:
5881 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_size);
5882 case Builtin::BI__builtin_coro_align:
5883 return EmitCoroutineIntrinsic(E, IID: Intrinsic::coro_align);
5884
5885 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions
5886 case Builtin::BIread_pipe:
5887 case Builtin::BIwrite_pipe: {
5888 Value *Arg0 = EmitScalarExpr(E: E->getArg(Arg: 0)),
5889 *Arg1 = EmitScalarExpr(E: E->getArg(Arg: 1));
5890 CGOpenCLRuntime OpenCLRT(CGM);
5891 Value *PacketSize = OpenCLRT.getPipeElemSize(PipeArg: E->getArg(Arg: 0));
5892 Value *PacketAlign = OpenCLRT.getPipeElemAlign(PipeArg: E->getArg(Arg: 0));
5893
5894 // Type of the generic packet parameter.
5895 unsigned GenericAS =
5896 getContext().getTargetAddressSpace(AS: LangAS::opencl_generic);
5897 llvm::Type *I8PTy = llvm::PointerType::get(C&: getLLVMContext(), AddressSpace: GenericAS);
5898
5899 // Testing which overloaded version we should generate the call for.
5900 if (2U == E->getNumArgs()) {
5901 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2"
5902 : "__write_pipe_2";
5903 // Creating a generic function type to be able to call with any builtin or
5904 // user defined type.
5905 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty};
5906 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: Int32Ty, Params: ArgTys, isVarArg: false);
5907 Value *ACast = Builder.CreateAddrSpaceCast(V: Arg1, DestTy: I8PTy);
5908 return RValue::get(
5909 V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name),
5910 args: {Arg0, ACast, PacketSize, PacketAlign}));
5911 } else {
5912 assert(4 == E->getNumArgs() &&
5913 "Illegal number of parameters to pipe function");
5914 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4"
5915 : "__write_pipe_4";
5916
5917 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy,
5918 Int32Ty, Int32Ty};
5919 Value *Arg2 = EmitScalarExpr(E: E->getArg(Arg: 2)),
5920 *Arg3 = EmitScalarExpr(E: E->getArg(Arg: 3));
5921 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: Int32Ty, Params: ArgTys, isVarArg: false);
5922 Value *ACast = Builder.CreateAddrSpaceCast(V: Arg3, DestTy: I8PTy);
5923 // We know the third argument is an integer type, but we may need to cast
5924 // it to i32.
5925 if (Arg2->getType() != Int32Ty)
5926 Arg2 = Builder.CreateZExtOrTrunc(V: Arg2, DestTy: Int32Ty);
5927 return RValue::get(
5928 V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name),
5929 args: {Arg0, Arg1, Arg2, ACast, PacketSize, PacketAlign}));
5930 }
5931 }
5932 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write
5933 // functions
5934 case Builtin::BIreserve_read_pipe:
5935 case Builtin::BIreserve_write_pipe:
5936 case Builtin::BIwork_group_reserve_read_pipe:
5937 case Builtin::BIwork_group_reserve_write_pipe:
5938 case Builtin::BIsub_group_reserve_read_pipe:
5939 case Builtin::BIsub_group_reserve_write_pipe: {
5940 // Composing the mangled name for the function.
5941 const char *Name;
5942 if (BuiltinID == Builtin::BIreserve_read_pipe)
5943 Name = "__reserve_read_pipe";
5944 else if (BuiltinID == Builtin::BIreserve_write_pipe)
5945 Name = "__reserve_write_pipe";
5946 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe)
5947 Name = "__work_group_reserve_read_pipe";
5948 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe)
5949 Name = "__work_group_reserve_write_pipe";
5950 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe)
5951 Name = "__sub_group_reserve_read_pipe";
5952 else
5953 Name = "__sub_group_reserve_write_pipe";
5954
5955 Value *Arg0 = EmitScalarExpr(E: E->getArg(Arg: 0)),
5956 *Arg1 = EmitScalarExpr(E: E->getArg(Arg: 1));
5957 llvm::Type *ReservedIDTy = ConvertType(T: getContext().OCLReserveIDTy);
5958 CGOpenCLRuntime OpenCLRT(CGM);
5959 Value *PacketSize = OpenCLRT.getPipeElemSize(PipeArg: E->getArg(Arg: 0));
5960 Value *PacketAlign = OpenCLRT.getPipeElemAlign(PipeArg: E->getArg(Arg: 0));
5961
5962 // Building the generic function prototype.
5963 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty};
5964 llvm::FunctionType *FTy =
5965 llvm::FunctionType::get(Result: ReservedIDTy, Params: ArgTys, isVarArg: false);
5966 // We know the second argument is an integer type, but we may need to cast
5967 // it to i32.
5968 if (Arg1->getType() != Int32Ty)
5969 Arg1 = Builder.CreateZExtOrTrunc(V: Arg1, DestTy: Int32Ty);
5970 return RValue::get(V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name),
5971 args: {Arg0, Arg1, PacketSize, PacketAlign}));
5972 }
5973 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write
5974 // functions
5975 case Builtin::BIcommit_read_pipe:
5976 case Builtin::BIcommit_write_pipe:
5977 case Builtin::BIwork_group_commit_read_pipe:
5978 case Builtin::BIwork_group_commit_write_pipe:
5979 case Builtin::BIsub_group_commit_read_pipe:
5980 case Builtin::BIsub_group_commit_write_pipe: {
5981 const char *Name;
5982 if (BuiltinID == Builtin::BIcommit_read_pipe)
5983 Name = "__commit_read_pipe";
5984 else if (BuiltinID == Builtin::BIcommit_write_pipe)
5985 Name = "__commit_write_pipe";
5986 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe)
5987 Name = "__work_group_commit_read_pipe";
5988 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe)
5989 Name = "__work_group_commit_write_pipe";
5990 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe)
5991 Name = "__sub_group_commit_read_pipe";
5992 else
5993 Name = "__sub_group_commit_write_pipe";
5994
5995 Value *Arg0 = EmitScalarExpr(E: E->getArg(Arg: 0)),
5996 *Arg1 = EmitScalarExpr(E: E->getArg(Arg: 1));
5997 CGOpenCLRuntime OpenCLRT(CGM);
5998 Value *PacketSize = OpenCLRT.getPipeElemSize(PipeArg: E->getArg(Arg: 0));
5999 Value *PacketAlign = OpenCLRT.getPipeElemAlign(PipeArg: E->getArg(Arg: 0));
6000
6001 // Building the generic function prototype.
6002 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty};
6003 llvm::FunctionType *FTy = llvm::FunctionType::get(
6004 Result: llvm::Type::getVoidTy(C&: getLLVMContext()), Params: ArgTys, isVarArg: false);
6005
6006 return RValue::get(V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name),
6007 args: {Arg0, Arg1, PacketSize, PacketAlign}));
6008 }
6009 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions
6010 case Builtin::BIget_pipe_num_packets:
6011 case Builtin::BIget_pipe_max_packets: {
6012 const char *BaseName;
6013 const auto *PipeTy = E->getArg(Arg: 0)->getType()->castAs<PipeType>();
6014 if (BuiltinID == Builtin::BIget_pipe_num_packets)
6015 BaseName = "__get_pipe_num_packets";
6016 else
6017 BaseName = "__get_pipe_max_packets";
6018 std::string Name = std::string(BaseName) +
6019 std::string(PipeTy->isReadOnly() ? "_ro" : "_wo");
6020
6021 // Building the generic function prototype.
6022 Value *Arg0 = EmitScalarExpr(E: E->getArg(Arg: 0));
6023 CGOpenCLRuntime OpenCLRT(CGM);
6024 Value *PacketSize = OpenCLRT.getPipeElemSize(PipeArg: E->getArg(Arg: 0));
6025 Value *PacketAlign = OpenCLRT.getPipeElemAlign(PipeArg: E->getArg(Arg: 0));
6026 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty};
6027 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: Int32Ty, Params: ArgTys, isVarArg: false);
6028
6029 return RValue::get(V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name),
6030 args: {Arg0, PacketSize, PacketAlign}));
6031 }
6032
6033 // OpenCL v2.0 s6.13.9 - Address space qualifier functions.
6034 case Builtin::BIto_global:
6035 case Builtin::BIto_local:
6036 case Builtin::BIto_private: {
6037 auto Arg0 = EmitScalarExpr(E: E->getArg(Arg: 0));
6038 auto NewArgT = llvm::PointerType::get(
6039 C&: getLLVMContext(),
6040 AddressSpace: CGM.getContext().getTargetAddressSpace(AS: LangAS::opencl_generic));
6041 auto NewRetT = llvm::PointerType::get(
6042 C&: getLLVMContext(),
6043 AddressSpace: CGM.getContext().getTargetAddressSpace(
6044 AS: E->getType()->getPointeeType().getAddressSpace()));
6045 auto FTy = llvm::FunctionType::get(Result: NewRetT, Params: {NewArgT}, isVarArg: false);
6046 llvm::Value *NewArg;
6047 if (Arg0->getType()->getPointerAddressSpace() !=
6048 NewArgT->getPointerAddressSpace())
6049 NewArg = Builder.CreateAddrSpaceCast(V: Arg0, DestTy: NewArgT);
6050 else
6051 NewArg = Builder.CreateBitOrPointerCast(V: Arg0, DestTy: NewArgT);
6052 auto NewName = std::string("__") + E->getDirectCallee()->getName().str();
6053 auto NewCall =
6054 EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name: NewName), args: {NewArg});
6055 return RValue::get(V: Builder.CreateBitOrPointerCast(V: NewCall,
6056 DestTy: ConvertType(T: E->getType())));
6057 }
6058
6059 // OpenCL v2.0, s6.13.17 - Enqueue kernel function.
6060 // Table 6.13.17.1 specifies four overload forms of enqueue_kernel.
6061 // The code below expands the builtin call to a call to one of the following
6062 // functions that an OpenCL runtime library will have to provide:
6063 // __enqueue_kernel_basic
6064 // __enqueue_kernel_varargs
6065 // __enqueue_kernel_basic_events
6066 // __enqueue_kernel_events_varargs
6067 case Builtin::BIenqueue_kernel: {
6068 StringRef Name; // Generated function call name
6069 unsigned NumArgs = E->getNumArgs();
6070
6071 llvm::Type *QueueTy = ConvertType(T: getContext().OCLQueueTy);
6072 llvm::Type *GenericVoidPtrTy = Builder.getPtrTy(
6073 AddrSpace: getContext().getTargetAddressSpace(AS: LangAS::opencl_generic));
6074
6075 llvm::Value *Queue = EmitScalarExpr(E: E->getArg(Arg: 0));
6076 llvm::Value *Flags = EmitScalarExpr(E: E->getArg(Arg: 1));
6077 LValue NDRangeL = EmitAggExprToLValue(E: E->getArg(Arg: 2));
6078 llvm::Value *Range = NDRangeL.getAddress().emitRawPointer(CGF&: *this);
6079
6080 // FIXME: Look through the addrspacecast which may exist to the stack
6081 // temporary as a hack.
6082 //
6083 // This is hardcoding the assumed ABI of the target function. This assumes
6084 // direct passing for every argument except NDRange, which is assumed to be
6085 // byval or byref indirect passed.
6086 //
6087 // This should be fixed to query a signature from CGOpenCLRuntime, and go
6088 // through EmitCallArgs to get the correct target ABI.
6089 Range = Range->stripPointerCasts();
6090
6091 llvm::Type *RangePtrTy = Range->getType();
6092
6093 if (NumArgs == 4) {
6094 // The most basic form of the call with parameters:
6095 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void)
6096 Name = "__enqueue_kernel_basic";
6097 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangePtrTy, GenericVoidPtrTy,
6098 GenericVoidPtrTy};
6099 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: Int32Ty, Params: ArgTys, isVarArg: false);
6100
6101 auto Info =
6102 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(CGF&: *this, E: E->getArg(Arg: 3));
6103 llvm::Value *Kernel =
6104 Builder.CreatePointerCast(V: Info.KernelHandle, DestTy: GenericVoidPtrTy);
6105 llvm::Value *Block =
6106 Builder.CreatePointerCast(V: Info.BlockArg, DestTy: GenericVoidPtrTy);
6107
6108 auto RTCall = EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name),
6109 args: {Queue, Flags, Range, Kernel, Block});
6110 return RValue::get(V: RTCall);
6111 }
6112 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature");
6113
6114 // Create a temporary array to hold the sizes of local pointer arguments
6115 // for the block. \p First is the position of the first size argument.
6116 auto CreateArrayForSizeVar =
6117 [=](unsigned First) -> std::pair<llvm::Value *, llvm::Value *> {
6118 llvm::APInt ArraySize(32, NumArgs - First);
6119 QualType SizeArrayTy = getContext().getConstantArrayType(
6120 EltTy: getContext().getSizeType(), ArySize: ArraySize, SizeExpr: nullptr,
6121 ASM: ArraySizeModifier::Normal,
6122 /*IndexTypeQuals=*/0);
6123 auto Tmp = CreateMemTemp(T: SizeArrayTy, Name: "block_sizes");
6124 llvm::Value *TmpPtr = Tmp.getPointer();
6125 // The EmitLifetime* pair expect a naked Alloca as their last argument,
6126 // however for cases where the default AS is not the Alloca AS, Tmp is
6127 // actually the Alloca ascasted to the default AS, hence the
6128 // stripPointerCasts()
6129 llvm::Value *Alloca = TmpPtr->stripPointerCasts();
6130 llvm::Value *ElemPtr;
6131 EmitLifetimeStart(Addr: Alloca);
6132 // Each of the following arguments specifies the size of the corresponding
6133 // argument passed to the enqueued block.
6134 auto *Zero = llvm::ConstantInt::get(Ty: IntTy, V: 0);
6135 for (unsigned I = First; I < NumArgs; ++I) {
6136 auto *Index = llvm::ConstantInt::get(Ty: IntTy, V: I - First);
6137 auto *GEP =
6138 Builder.CreateGEP(Ty: Tmp.getElementType(), Ptr: Alloca, IdxList: {Zero, Index});
6139 if (I == First)
6140 ElemPtr = GEP;
6141 auto *V =
6142 Builder.CreateZExtOrTrunc(V: EmitScalarExpr(E: E->getArg(Arg: I)), DestTy: SizeTy);
6143 Builder.CreateAlignedStore(
6144 Val: V, Ptr: GEP, Align: CGM.getDataLayout().getPrefTypeAlign(Ty: SizeTy));
6145 }
6146 // Return the Alloca itself rather than a potential ascast as this is only
6147 // used by the paired EmitLifetimeEnd.
6148 return {ElemPtr, Alloca};
6149 };
6150
6151 // Could have events and/or varargs.
6152 if (E->getArg(Arg: 3)->getType()->isBlockPointerType()) {
6153 // No events passed, but has variadic arguments.
6154 Name = "__enqueue_kernel_varargs";
6155 auto Info =
6156 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(CGF&: *this, E: E->getArg(Arg: 3));
6157 llvm::Value *Kernel =
6158 Builder.CreatePointerCast(V: Info.KernelHandle, DestTy: GenericVoidPtrTy);
6159 auto *Block = Builder.CreatePointerCast(V: Info.BlockArg, DestTy: GenericVoidPtrTy);
6160 auto [ElemPtr, TmpPtr] = CreateArrayForSizeVar(4);
6161
6162 // Create a vector of the arguments, as well as a constant value to
6163 // express to the runtime the number of variadic arguments.
6164 llvm::Value *const Args[] = {Queue, Flags,
6165 Range, Kernel,
6166 Block, ConstantInt::get(Ty: IntTy, V: NumArgs - 4),
6167 ElemPtr};
6168 llvm::Type *const ArgTys[] = {
6169 QueueTy, IntTy, RangePtrTy, GenericVoidPtrTy,
6170 GenericVoidPtrTy, IntTy, ElemPtr->getType()};
6171
6172 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: Int32Ty, Params: ArgTys, isVarArg: false);
6173 auto Call = RValue::get(
6174 V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name), args: Args));
6175 EmitLifetimeEnd(Addr: TmpPtr);
6176 return Call;
6177 }
6178 // Any calls now have event arguments passed.
6179 if (NumArgs >= 7) {
6180 llvm::PointerType *PtrTy = llvm::PointerType::get(
6181 C&: CGM.getLLVMContext(),
6182 AddressSpace: CGM.getContext().getTargetAddressSpace(AS: LangAS::opencl_generic));
6183
6184 llvm::Value *NumEvents =
6185 Builder.CreateZExtOrTrunc(V: EmitScalarExpr(E: E->getArg(Arg: 3)), DestTy: Int32Ty);
6186
6187 // Since SemaOpenCLBuiltinEnqueueKernel allows fifth and sixth arguments
6188 // to be a null pointer constant (including `0` literal), we can take it
6189 // into account and emit null pointer directly.
6190 llvm::Value *EventWaitList = nullptr;
6191 if (E->getArg(Arg: 4)->isNullPointerConstant(
6192 Ctx&: getContext(), NPC: Expr::NPC_ValueDependentIsNotNull)) {
6193 EventWaitList = llvm::ConstantPointerNull::get(T: PtrTy);
6194 } else {
6195 EventWaitList =
6196 E->getArg(Arg: 4)->getType()->isArrayType()
6197 ? EmitArrayToPointerDecay(Array: E->getArg(Arg: 4)).emitRawPointer(CGF&: *this)
6198 : EmitScalarExpr(E: E->getArg(Arg: 4));
6199 // Convert to generic address space.
6200 EventWaitList = Builder.CreatePointerCast(V: EventWaitList, DestTy: PtrTy);
6201 }
6202 llvm::Value *EventRet = nullptr;
6203 if (E->getArg(Arg: 5)->isNullPointerConstant(
6204 Ctx&: getContext(), NPC: Expr::NPC_ValueDependentIsNotNull)) {
6205 EventRet = llvm::ConstantPointerNull::get(T: PtrTy);
6206 } else {
6207 EventRet =
6208 Builder.CreatePointerCast(V: EmitScalarExpr(E: E->getArg(Arg: 5)), DestTy: PtrTy);
6209 }
6210
6211 auto Info =
6212 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(CGF&: *this, E: E->getArg(Arg: 6));
6213 llvm::Value *Kernel =
6214 Builder.CreatePointerCast(V: Info.KernelHandle, DestTy: GenericVoidPtrTy);
6215 llvm::Value *Block =
6216 Builder.CreatePointerCast(V: Info.BlockArg, DestTy: GenericVoidPtrTy);
6217
6218 std::vector<llvm::Type *> ArgTys = {
6219 QueueTy, Int32Ty, RangePtrTy, Int32Ty,
6220 PtrTy, PtrTy, GenericVoidPtrTy, GenericVoidPtrTy};
6221
6222 std::vector<llvm::Value *> Args = {Queue, Flags, Range,
6223 NumEvents, EventWaitList, EventRet,
6224 Kernel, Block};
6225
6226 if (NumArgs == 7) {
6227 // Has events but no variadics.
6228 Name = "__enqueue_kernel_basic_events";
6229 llvm::FunctionType *FTy =
6230 llvm::FunctionType::get(Result: Int32Ty, Params: ArgTys, isVarArg: false);
6231 return RValue::get(
6232 V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name), args: Args));
6233 }
6234 // Has event info and variadics
6235 // Pass the number of variadics to the runtime function too.
6236 Args.push_back(x: ConstantInt::get(Ty: Int32Ty, V: NumArgs - 7));
6237 ArgTys.push_back(x: Int32Ty);
6238 Name = "__enqueue_kernel_events_varargs";
6239
6240 auto [ElemPtr, TmpPtr] = CreateArrayForSizeVar(7);
6241 Args.push_back(x: ElemPtr);
6242 ArgTys.push_back(x: ElemPtr->getType());
6243
6244 llvm::FunctionType *FTy = llvm::FunctionType::get(Result: Int32Ty, Params: ArgTys, isVarArg: false);
6245 auto Call = RValue::get(
6246 V: EmitRuntimeCall(callee: CGM.CreateRuntimeFunction(Ty: FTy, Name), args: Args));
6247 EmitLifetimeEnd(Addr: TmpPtr);
6248 return Call;
6249 }
6250 llvm_unreachable("Unexpected enqueue_kernel signature");
6251 }
6252 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
6253 // parameter.
6254 case Builtin::BIget_kernel_work_group_size: {
6255 llvm::Type *GenericVoidPtrTy = Builder.getPtrTy(
6256 AddrSpace: getContext().getTargetAddressSpace(AS: LangAS::opencl_generic));
6257 auto Info =
6258 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(CGF&: *this, E: E->getArg(Arg: 0));
6259 Value *Kernel =
6260 Builder.CreatePointerCast(V: Info.KernelHandle, DestTy: GenericVoidPtrTy);
6261 Value *Arg = Builder.CreatePointerCast(V: Info.BlockArg, DestTy: GenericVoidPtrTy);
6262 return RValue::get(V: EmitRuntimeCall(
6263 callee: CGM.CreateRuntimeFunction(
6264 Ty: llvm::FunctionType::get(Result: IntTy, Params: {GenericVoidPtrTy, GenericVoidPtrTy},
6265 isVarArg: false),
6266 Name: "__get_kernel_work_group_size_impl"),
6267 args: {Kernel, Arg}));
6268 }
6269 case Builtin::BIget_kernel_preferred_work_group_size_multiple: {
6270 llvm::Type *GenericVoidPtrTy = Builder.getPtrTy(
6271 AddrSpace: getContext().getTargetAddressSpace(AS: LangAS::opencl_generic));
6272 auto Info =
6273 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(CGF&: *this, E: E->getArg(Arg: 0));
6274 Value *Kernel =
6275 Builder.CreatePointerCast(V: Info.KernelHandle, DestTy: GenericVoidPtrTy);
6276 Value *Arg = Builder.CreatePointerCast(V: Info.BlockArg, DestTy: GenericVoidPtrTy);
6277 return RValue::get(V: EmitRuntimeCall(
6278 callee: CGM.CreateRuntimeFunction(
6279 Ty: llvm::FunctionType::get(Result: IntTy, Params: {GenericVoidPtrTy, GenericVoidPtrTy},
6280 isVarArg: false),
6281 Name: "__get_kernel_preferred_work_group_size_multiple_impl"),
6282 args: {Kernel, Arg}));
6283 }
6284 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
6285 case Builtin::BIget_kernel_sub_group_count_for_ndrange: {
6286 llvm::Type *GenericVoidPtrTy = Builder.getPtrTy(
6287 AddrSpace: getContext().getTargetAddressSpace(AS: LangAS::opencl_generic));
6288 LValue NDRangeL = EmitAggExprToLValue(E: E->getArg(Arg: 0));
6289 llvm::Value *NDRange = NDRangeL.getAddress().emitRawPointer(CGF&: *this);
6290 auto Info =
6291 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(CGF&: *this, E: E->getArg(Arg: 1));
6292 Value *Kernel =
6293 Builder.CreatePointerCast(V: Info.KernelHandle, DestTy: GenericVoidPtrTy);
6294 Value *Block = Builder.CreatePointerCast(V: Info.BlockArg, DestTy: GenericVoidPtrTy);
6295 const char *Name =
6296 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange
6297 ? "__get_kernel_max_sub_group_size_for_ndrange_impl"
6298 : "__get_kernel_sub_group_count_for_ndrange_impl";
6299 return RValue::get(V: EmitRuntimeCall(
6300 callee: CGM.CreateRuntimeFunction(
6301 Ty: llvm::FunctionType::get(
6302 Result: IntTy, Params: {NDRange->getType(), GenericVoidPtrTy, GenericVoidPtrTy},
6303 isVarArg: false),
6304 Name),
6305 args: {NDRange, Kernel, Block}));
6306 }
6307 case Builtin::BI__builtin_store_half:
6308 case Builtin::BI__builtin_store_halff: {
6309 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
6310 Value *Val = EmitScalarExpr(E: E->getArg(Arg: 0));
6311 Address Address = EmitPointerWithAlignment(Addr: E->getArg(Arg: 1));
6312 Value *HalfVal = Builder.CreateFPTrunc(V: Val, DestTy: Builder.getHalfTy());
6313 Builder.CreateStore(Val: HalfVal, Addr: Address);
6314 return RValue::get(V: nullptr);
6315 }
6316 case Builtin::BI__builtin_load_half: {
6317 Address Address = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
6318 Value *HalfVal = Builder.CreateLoad(Addr: Address);
6319 return RValue::get(V: Builder.CreateFPExt(V: HalfVal, DestTy: Builder.getDoubleTy()));
6320 }
6321 case Builtin::BI__builtin_load_halff: {
6322 Address Address = EmitPointerWithAlignment(Addr: E->getArg(Arg: 0));
6323 Value *HalfVal = Builder.CreateLoad(Addr: Address);
6324 return RValue::get(V: Builder.CreateFPExt(V: HalfVal, DestTy: Builder.getFloatTy()));
6325 }
6326 case Builtin::BI__builtin_printf:
6327 case Builtin::BIprintf:
6328 if (getTarget().getTriple().isNVPTX() ||
6329 getTarget().getTriple().isAMDGCN() ||
6330 (getTarget().getTriple().isSPIRV() &&
6331 getTarget().getTriple().getVendor() == Triple::VendorType::AMD)) {
6332 if (getTarget().getTriple().isNVPTX())
6333 return EmitNVPTXDevicePrintfCallExpr(E);
6334 if ((getTarget().getTriple().isAMDGCN() ||
6335 getTarget().getTriple().isSPIRV()) &&
6336 getLangOpts().HIP)
6337 return EmitAMDGPUDevicePrintfCallExpr(E);
6338 }
6339
6340 break;
6341 case Builtin::BI__builtin_canonicalize:
6342 case Builtin::BI__builtin_canonicalizef:
6343 case Builtin::BI__builtin_canonicalizef16:
6344 case Builtin::BI__builtin_canonicalizel:
6345 return RValue::get(
6346 V: emitBuiltinWithOneOverloadedType<1>(CGF&: *this, E, IntrinsicID: Intrinsic::canonicalize));
6347
6348 case Builtin::BI__builtin_thread_pointer: {
6349 if (!getContext().getTargetInfo().isTLSSupported())
6350 CGM.ErrorUnsupported(S: E, Type: "__builtin_thread_pointer");
6351
6352 return RValue::get(V: Builder.CreateIntrinsic(ID: llvm::Intrinsic::thread_pointer,
6353 Types: {GlobalsInt8PtrTy}, Args: {}));
6354 }
6355 case Builtin::BI__builtin_os_log_format:
6356 return emitBuiltinOSLogFormat(E: *E);
6357
6358 case Builtin::BI__xray_customevent: {
6359 if (!ShouldXRayInstrumentFunction())
6360 return RValue::getIgnored();
6361
6362 if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
6363 K: XRayInstrKind::Custom))
6364 return RValue::getIgnored();
6365
6366 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
6367 if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents())
6368 return RValue::getIgnored();
6369
6370 Function *F = CGM.getIntrinsic(IID: Intrinsic::xray_customevent);
6371 auto FTy = F->getFunctionType();
6372 auto Arg0 = E->getArg(Arg: 0);
6373 auto Arg0Val = EmitScalarExpr(E: Arg0);
6374 auto Arg0Ty = Arg0->getType();
6375 auto PTy0 = FTy->getParamType(i: 0);
6376 if (PTy0 != Arg0Val->getType()) {
6377 if (Arg0Ty->isArrayType())
6378 Arg0Val = EmitArrayToPointerDecay(Array: Arg0).emitRawPointer(CGF&: *this);
6379 else
6380 Arg0Val = Builder.CreatePointerCast(V: Arg0Val, DestTy: PTy0);
6381 }
6382 auto Arg1 = EmitScalarExpr(E: E->getArg(Arg: 1));
6383 auto PTy1 = FTy->getParamType(i: 1);
6384 if (PTy1 != Arg1->getType())
6385 Arg1 = Builder.CreateTruncOrBitCast(V: Arg1, DestTy: PTy1);
6386 return RValue::get(V: Builder.CreateCall(Callee: F, Args: {Arg0Val, Arg1}));
6387 }
6388
6389 case Builtin::BI__xray_typedevent: {
6390 // TODO: There should be a way to always emit events even if the current
6391 // function is not instrumented. Losing events in a stream can cripple
6392 // a trace.
6393 if (!ShouldXRayInstrumentFunction())
6394 return RValue::getIgnored();
6395
6396 if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
6397 K: XRayInstrKind::Typed))
6398 return RValue::getIgnored();
6399
6400 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>())
6401 if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayTypedEvents())
6402 return RValue::getIgnored();
6403
6404 Function *F = CGM.getIntrinsic(IID: Intrinsic::xray_typedevent);
6405 auto FTy = F->getFunctionType();
6406 auto Arg0 = EmitScalarExpr(E: E->getArg(Arg: 0));
6407 auto PTy0 = FTy->getParamType(i: 0);
6408 if (PTy0 != Arg0->getType())
6409 Arg0 = Builder.CreateTruncOrBitCast(V: Arg0, DestTy: PTy0);
6410 auto Arg1 = E->getArg(Arg: 1);
6411 auto Arg1Val = EmitScalarExpr(E: Arg1);
6412 auto Arg1Ty = Arg1->getType();
6413 auto PTy1 = FTy->getParamType(i: 1);
6414 if (PTy1 != Arg1Val->getType()) {
6415 if (Arg1Ty->isArrayType())
6416 Arg1Val = EmitArrayToPointerDecay(Array: Arg1).emitRawPointer(CGF&: *this);
6417 else
6418 Arg1Val = Builder.CreatePointerCast(V: Arg1Val, DestTy: PTy1);
6419 }
6420 auto Arg2 = EmitScalarExpr(E: E->getArg(Arg: 2));
6421 auto PTy2 = FTy->getParamType(i: 2);
6422 if (PTy2 != Arg2->getType())
6423 Arg2 = Builder.CreateTruncOrBitCast(V: Arg2, DestTy: PTy2);
6424 return RValue::get(V: Builder.CreateCall(Callee: F, Args: {Arg0, Arg1Val, Arg2}));
6425 }
6426
6427 case Builtin::BI__builtin_ms_va_start:
6428 case Builtin::BI__builtin_ms_va_end:
6429 return RValue::get(
6430 V: EmitVAStartEnd(ArgValue: EmitMSVAListRef(E: E->getArg(Arg: 0)).emitRawPointer(CGF&: *this),
6431 IsStart: BuiltinID == Builtin::BI__builtin_ms_va_start));
6432
6433 case Builtin::BI__builtin_ms_va_copy: {
6434 // Lower this manually. We can't reliably determine whether or not any
6435 // given va_copy() is for a Win64 va_list from the calling convention
6436 // alone, because it's legal to do this from a System V ABI function.
6437 // With opaque pointer types, we won't have enough information in LLVM
6438 // IR to determine this from the argument types, either. Best to do it
6439 // now, while we have enough information.
6440 Address DestAddr = EmitMSVAListRef(E: E->getArg(Arg: 0));
6441 Address SrcAddr = EmitMSVAListRef(E: E->getArg(Arg: 1));
6442
6443 DestAddr = DestAddr.withElementType(ElemTy: Int8PtrTy);
6444 SrcAddr = SrcAddr.withElementType(ElemTy: Int8PtrTy);
6445
6446 Value *ArgPtr = Builder.CreateLoad(Addr: SrcAddr, Name: "ap.val");
6447 return RValue::get(V: Builder.CreateStore(Val: ArgPtr, Addr: DestAddr));
6448 }
6449
6450 case Builtin::BI__builtin_get_device_side_mangled_name: {
6451 auto Name = CGM.getCUDARuntime().getDeviceSideName(
6452 ND: cast<DeclRefExpr>(Val: E->getArg(Arg: 0)->IgnoreImpCasts())->getDecl());
6453 auto Str = CGM.GetAddrOfConstantCString(Str: Name, GlobalName: "");
6454 return RValue::get(V: Str.getPointer());
6455 }
6456 }
6457
6458 // If this is an alias for a lib function (e.g. __builtin_sin), emit
6459 // the call using the normal call path, but using the unmangled
6460 // version of the function name.
6461 const auto &BI = getContext().BuiltinInfo;
6462 if (!shouldEmitBuiltinAsIR(BuiltinID, BI, CGF: *this) &&
6463 BI.isLibFunction(ID: BuiltinID))
6464 return emitLibraryCall(CGF&: *this, FD, E,
6465 calleeValue: CGM.getBuiltinLibFunction(FD, BuiltinID));
6466
6467 // If this is a predefined lib function (e.g. malloc), emit the call
6468 // using exactly the normal call path.
6469 if (BI.isPredefinedLibFunction(ID: BuiltinID))
6470 return emitLibraryCall(CGF&: *this, FD, E, calleeValue: CGM.getRawFunctionPointer(GD: FD));
6471
6472 // Check that a call to a target specific builtin has the correct target
6473 // features.
6474 // This is down here to avoid non-target specific builtins, however, if
6475 // generic builtins start to require generic target features then we
6476 // can move this up to the beginning of the function.
6477 checkTargetFeatures(E, TargetDecl: FD);
6478
6479 if (unsigned VectorWidth = getContext().BuiltinInfo.getRequiredVectorWidth(ID: BuiltinID))
6480 LargestVectorWidth = std::max(a: LargestVectorWidth, b: VectorWidth);
6481
6482 // See if we have a target specific intrinsic.
6483 std::string Name = getContext().BuiltinInfo.getName(ID: BuiltinID);
6484 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
6485 StringRef Prefix =
6486 llvm::Triple::getArchTypePrefix(Kind: getTarget().getTriple().getArch());
6487 if (!Prefix.empty()) {
6488 IntrinsicID = Intrinsic::getIntrinsicForClangBuiltin(TargetPrefix: Prefix.data(), BuiltinName: Name);
6489 if (IntrinsicID == Intrinsic::not_intrinsic && Prefix == "spv" &&
6490 getTarget().getTriple().getOS() == llvm::Triple::OSType::AMDHSA)
6491 IntrinsicID = Intrinsic::getIntrinsicForClangBuiltin(TargetPrefix: "amdgcn", BuiltinName: Name);
6492 // NOTE we don't need to perform a compatibility flag check here since the
6493 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
6494 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
6495 if (IntrinsicID == Intrinsic::not_intrinsic)
6496 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(TargetPrefix: Prefix.data(), BuiltinName: Name);
6497 }
6498
6499 if (IntrinsicID != Intrinsic::not_intrinsic) {
6500 SmallVector<Value*, 16> Args;
6501
6502 // Find out if any arguments are required to be integer constant
6503 // expressions.
6504 unsigned ICEArguments = 0;
6505 ASTContext::GetBuiltinTypeError Error;
6506 getContext().GetBuiltinType(ID: BuiltinID, Error, IntegerConstantArgs: &ICEArguments);
6507 assert(Error == ASTContext::GE_None && "Should not codegen an error");
6508
6509 Function *F = CGM.getIntrinsic(IID: IntrinsicID);
6510 llvm::FunctionType *FTy = F->getFunctionType();
6511
6512 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
6513 Value *ArgValue = EmitScalarOrConstFoldImmArg(ICEArguments, Idx: i, E);
6514 // If the intrinsic arg type is different from the builtin arg type
6515 // we need to do a bit cast.
6516 llvm::Type *PTy = FTy->getParamType(i);
6517 if (PTy != ArgValue->getType()) {
6518 // XXX - vector of pointers?
6519 if (auto *PtrTy = dyn_cast<llvm::PointerType>(Val: PTy)) {
6520 if (PtrTy->getAddressSpace() !=
6521 ArgValue->getType()->getPointerAddressSpace()) {
6522 ArgValue = Builder.CreateAddrSpaceCast(
6523 V: ArgValue, DestTy: llvm::PointerType::get(C&: getLLVMContext(),
6524 AddressSpace: PtrTy->getAddressSpace()));
6525 }
6526 }
6527
6528 // Cast vector type (e.g., v256i32) to x86_amx, this only happen
6529 // in amx intrinsics.
6530 if (PTy->isX86_AMXTy())
6531 ArgValue = Builder.CreateIntrinsic(ID: Intrinsic::x86_cast_vector_to_tile,
6532 Types: {ArgValue->getType()}, Args: {ArgValue});
6533 else
6534 ArgValue = Builder.CreateBitCast(V: ArgValue, DestTy: PTy);
6535 }
6536
6537 Args.push_back(Elt: ArgValue);
6538 }
6539
6540 Value *V = Builder.CreateCall(Callee: F, Args);
6541 QualType BuiltinRetType = E->getType();
6542
6543 llvm::Type *RetTy = VoidTy;
6544 if (!BuiltinRetType->isVoidType())
6545 RetTy = ConvertType(T: BuiltinRetType);
6546
6547 if (RetTy != V->getType()) {
6548 // XXX - vector of pointers?
6549 if (auto *PtrTy = dyn_cast<llvm::PointerType>(Val: RetTy)) {
6550 if (PtrTy->getAddressSpace() != V->getType()->getPointerAddressSpace()) {
6551 V = Builder.CreateAddrSpaceCast(
6552 V, DestTy: llvm::PointerType::get(C&: getLLVMContext(),
6553 AddressSpace: PtrTy->getAddressSpace()));
6554 }
6555 }
6556
6557 // Cast x86_amx to vector type (e.g., v256i32), this only happen
6558 // in amx intrinsics.
6559 if (V->getType()->isX86_AMXTy())
6560 V = Builder.CreateIntrinsic(ID: Intrinsic::x86_cast_tile_to_vector, Types: {RetTy},
6561 Args: {V});
6562 else
6563 V = Builder.CreateBitCast(V, DestTy: RetTy);
6564 }
6565
6566 if (RetTy->isVoidTy())
6567 return RValue::get(V: nullptr);
6568
6569 return RValue::get(V);
6570 }
6571
6572 // Some target-specific builtins can have aggregate return values, e.g.
6573 // __builtin_arm_mve_vld2q_u32. So if the result is an aggregate, force
6574 // ReturnValue to be non-null, so that the target-specific emission code can
6575 // always just emit into it.
6576 TypeEvaluationKind EvalKind = getEvaluationKind(T: E->getType());
6577 if (EvalKind == TEK_Aggregate && ReturnValue.isNull()) {
6578 Address DestPtr = CreateMemTemp(T: E->getType(), Name: "agg.tmp");
6579 ReturnValue = ReturnValueSlot(DestPtr, false);
6580 }
6581
6582 // Now see if we can emit a target-specific builtin.
6583 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E, ReturnValue)) {
6584 switch (EvalKind) {
6585 case TEK_Scalar:
6586 if (V->getType()->isVoidTy())
6587 return RValue::get(V: nullptr);
6588 return RValue::get(V);
6589 case TEK_Aggregate:
6590 return RValue::getAggregate(addr: ReturnValue.getAddress(),
6591 isVolatile: ReturnValue.isVolatile());
6592 case TEK_Complex:
6593 llvm_unreachable("No current target builtin returns complex");
6594 }
6595 llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr");
6596 }
6597
6598 // EmitHLSLBuiltinExpr will check getLangOpts().HLSL
6599 if (Value *V = EmitHLSLBuiltinExpr(BuiltinID, E, ReturnValue)) {
6600 switch (EvalKind) {
6601 case TEK_Scalar:
6602 if (V->getType()->isVoidTy())
6603 return RValue::get(V: nullptr);
6604 return RValue::get(V);
6605 case TEK_Aggregate:
6606 return RValue::getAggregate(addr: ReturnValue.getAddress(),
6607 isVolatile: ReturnValue.isVolatile());
6608 case TEK_Complex:
6609 llvm_unreachable("No current hlsl builtin returns complex");
6610 }
6611 llvm_unreachable("Bad evaluation kind in EmitBuiltinExpr");
6612 }
6613
6614 if (getLangOpts().HIPStdPar && getLangOpts().CUDAIsDevice)
6615 return EmitHipStdParUnsupportedBuiltin(CGF: this, FD);
6616
6617 ErrorUnsupported(S: E, Type: "builtin function");
6618
6619 // Unknown builtin, for now just dump it out and return undef.
6620 return GetUndefRValue(Ty: E->getType());
6621}
6622
6623namespace {
6624struct BuiltinAlignArgs {
6625 llvm::Value *Src = nullptr;
6626 llvm::Type *SrcType = nullptr;
6627 llvm::Value *Alignment = nullptr;
6628 llvm::Value *Mask = nullptr;
6629 llvm::IntegerType *IntType = nullptr;
6630
6631 BuiltinAlignArgs(const CallExpr *E, CodeGenFunction &CGF) {
6632 QualType AstType = E->getArg(Arg: 0)->getType();
6633 if (AstType->isArrayType())
6634 Src = CGF.EmitArrayToPointerDecay(Array: E->getArg(Arg: 0)).emitRawPointer(CGF);
6635 else
6636 Src = CGF.EmitScalarExpr(E: E->getArg(Arg: 0));
6637 SrcType = Src->getType();
6638 if (SrcType->isPointerTy()) {
6639 IntType = IntegerType::get(
6640 C&: CGF.getLLVMContext(),
6641 NumBits: CGF.CGM.getDataLayout().getIndexTypeSizeInBits(Ty: SrcType));
6642 } else {
6643 assert(SrcType->isIntegerTy());
6644 IntType = cast<llvm::IntegerType>(Val: SrcType);
6645 }
6646 Alignment = CGF.EmitScalarExpr(E: E->getArg(Arg: 1));
6647 Alignment = CGF.Builder.CreateZExtOrTrunc(V: Alignment, DestTy: IntType, Name: "alignment");
6648 auto *One = llvm::ConstantInt::get(Ty: IntType, V: 1);
6649 Mask = CGF.Builder.CreateSub(LHS: Alignment, RHS: One, Name: "mask");
6650 }
6651};
6652} // namespace
6653
6654/// Generate (x & (y-1)) == 0.
6655RValue CodeGenFunction::EmitBuiltinIsAligned(const CallExpr *E) {
6656 BuiltinAlignArgs Args(E, *this);
6657 llvm::Value *SrcAddress = Args.Src;
6658 if (Args.SrcType->isPointerTy())
6659 SrcAddress =
6660 Builder.CreateBitOrPointerCast(V: Args.Src, DestTy: Args.IntType, Name: "src_addr");
6661 return RValue::get(V: Builder.CreateICmpEQ(
6662 LHS: Builder.CreateAnd(LHS: SrcAddress, RHS: Args.Mask, Name: "set_bits"),
6663 RHS: llvm::Constant::getNullValue(Ty: Args.IntType), Name: "is_aligned"));
6664}
6665
6666/// Generate (x & ~(y-1)) to align down or ((x+(y-1)) & ~(y-1)) to align up.
6667/// Note: For pointer types we can avoid ptrtoint/inttoptr pairs by using the
6668/// llvm.ptrmask intrinsic (with a GEP before in the align_up case).
6669RValue CodeGenFunction::EmitBuiltinAlignTo(const CallExpr *E, bool AlignUp) {
6670 BuiltinAlignArgs Args(E, *this);
6671 llvm::Value *SrcForMask = Args.Src;
6672 if (AlignUp) {
6673 // When aligning up we have to first add the mask to ensure we go over the
6674 // next alignment value and then align down to the next valid multiple.
6675 // By adding the mask, we ensure that align_up on an already aligned
6676 // value will not change the value.
6677 if (Args.Src->getType()->isPointerTy()) {
6678 if (getLangOpts().PointerOverflowDefined)
6679 SrcForMask =
6680 Builder.CreateGEP(Ty: Int8Ty, Ptr: SrcForMask, IdxList: Args.Mask, Name: "over_boundary");
6681 else
6682 SrcForMask = EmitCheckedInBoundsGEP(ElemTy: Int8Ty, Ptr: SrcForMask, IdxList: Args.Mask,
6683 /*SignedIndices=*/true,
6684 /*isSubtraction=*/IsSubtraction: false,
6685 Loc: E->getExprLoc(), Name: "over_boundary");
6686 } else {
6687 SrcForMask = Builder.CreateAdd(LHS: SrcForMask, RHS: Args.Mask, Name: "over_boundary");
6688 }
6689 }
6690 // Invert the mask to only clear the lower bits.
6691 llvm::Value *InvertedMask = Builder.CreateNot(V: Args.Mask, Name: "inverted_mask");
6692 llvm::Value *Result = nullptr;
6693 if (Args.Src->getType()->isPointerTy()) {
6694 Result = Builder.CreateIntrinsic(
6695 ID: Intrinsic::ptrmask, Types: {Args.SrcType, Args.IntType},
6696 Args: {SrcForMask, InvertedMask}, FMFSource: nullptr, Name: "aligned_result");
6697 } else {
6698 Result = Builder.CreateAnd(LHS: SrcForMask, RHS: InvertedMask, Name: "aligned_result");
6699 }
6700 assert(Result->getType() == Args.SrcType);
6701 return RValue::get(V: Result);
6702}
6703