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