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