1 //===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This contains code to emit Builtin calls as LLVM code. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CGCXXABI.h" 15 #include "CGObjCRuntime.h" 16 #include "CGOpenCLRuntime.h" 17 #include "CodeGenFunction.h" 18 #include "CodeGenModule.h" 19 #include "TargetInfo.h" 20 #include "clang/AST/ASTContext.h" 21 #include "clang/AST/Decl.h" 22 #include "clang/Analysis/Analyses/OSLog.h" 23 #include "clang/Basic/TargetBuiltins.h" 24 #include "clang/Basic/TargetInfo.h" 25 #include "clang/CodeGen/CGFunctionInfo.h" 26 #include "llvm/ADT/StringExtras.h" 27 #include "llvm/IR/CallSite.h" 28 #include "llvm/IR/DataLayout.h" 29 #include "llvm/IR/InlineAsm.h" 30 #include "llvm/IR/Intrinsics.h" 31 #include "llvm/IR/MDBuilder.h" 32 #include <sstream> 33 34 using namespace clang; 35 using namespace CodeGen; 36 using namespace llvm; 37 38 static 39 int64_t clamp(int64_t Value, int64_t Low, int64_t High) { 40 return std::min(High, std::max(Low, Value)); 41 } 42 43 /// getBuiltinLibFunction - Given a builtin id for a function like 44 /// "__builtin_fabsf", return a Function* for "fabsf". 45 llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, 46 unsigned BuiltinID) { 47 assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); 48 49 // Get the name, skip over the __builtin_ prefix (if necessary). 50 StringRef Name; 51 GlobalDecl D(FD); 52 53 // If the builtin has been declared explicitly with an assembler label, 54 // use the mangled name. This differs from the plain label on platforms 55 // that prefix labels. 56 if (FD->hasAttr<AsmLabelAttr>()) 57 Name = getMangledName(D); 58 else 59 Name = Context.BuiltinInfo.getName(BuiltinID) + 10; 60 61 llvm::FunctionType *Ty = 62 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); 63 64 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); 65 } 66 67 /// Emit the conversions required to turn the given value into an 68 /// integer of the given size. 69 static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V, 70 QualType T, llvm::IntegerType *IntType) { 71 V = CGF.EmitToMemory(V, T); 72 73 if (V->getType()->isPointerTy()) 74 return CGF.Builder.CreatePtrToInt(V, IntType); 75 76 assert(V->getType() == IntType); 77 return V; 78 } 79 80 static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, 81 QualType T, llvm::Type *ResultType) { 82 V = CGF.EmitFromMemory(V, T); 83 84 if (ResultType->isPointerTy()) 85 return CGF.Builder.CreateIntToPtr(V, ResultType); 86 87 assert(V->getType() == ResultType); 88 return V; 89 } 90 91 /// Utility to insert an atomic instruction based on Instrinsic::ID 92 /// and the expression node. 93 static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF, 94 llvm::AtomicRMWInst::BinOp Kind, 95 const CallExpr *E) { 96 QualType T = E->getType(); 97 assert(E->getArg(0)->getType()->isPointerType()); 98 assert(CGF.getContext().hasSameUnqualifiedType(T, 99 E->getArg(0)->getType()->getPointeeType())); 100 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 101 102 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 103 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 104 105 llvm::IntegerType *IntType = 106 llvm::IntegerType::get(CGF.getLLVMContext(), 107 CGF.getContext().getTypeSize(T)); 108 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 109 110 llvm::Value *Args[2]; 111 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 112 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 113 llvm::Type *ValueType = Args[1]->getType(); 114 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 115 116 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 117 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 118 return EmitFromInt(CGF, Result, T, ValueType); 119 } 120 121 static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) { 122 Value *Val = CGF.EmitScalarExpr(E->getArg(0)); 123 Value *Address = CGF.EmitScalarExpr(E->getArg(1)); 124 125 // Convert the type of the pointer to a pointer to the stored type. 126 Val = CGF.EmitToMemory(Val, E->getArg(0)->getType()); 127 Value *BC = CGF.Builder.CreateBitCast( 128 Address, llvm::PointerType::getUnqual(Val->getType()), "cast"); 129 LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType()); 130 LV.setNontemporal(true); 131 CGF.EmitStoreOfScalar(Val, LV, false); 132 return nullptr; 133 } 134 135 static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) { 136 Value *Address = CGF.EmitScalarExpr(E->getArg(0)); 137 138 LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType()); 139 LV.setNontemporal(true); 140 return CGF.EmitLoadOfScalar(LV, E->getExprLoc()); 141 } 142 143 static RValue EmitBinaryAtomic(CodeGenFunction &CGF, 144 llvm::AtomicRMWInst::BinOp Kind, 145 const CallExpr *E) { 146 return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E)); 147 } 148 149 /// Utility to insert an atomic instruction based Instrinsic::ID and 150 /// the expression node, where the return value is the result of the 151 /// operation. 152 static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 153 llvm::AtomicRMWInst::BinOp Kind, 154 const CallExpr *E, 155 Instruction::BinaryOps Op, 156 bool Invert = false) { 157 QualType T = E->getType(); 158 assert(E->getArg(0)->getType()->isPointerType()); 159 assert(CGF.getContext().hasSameUnqualifiedType(T, 160 E->getArg(0)->getType()->getPointeeType())); 161 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 162 163 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 164 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 165 166 llvm::IntegerType *IntType = 167 llvm::IntegerType::get(CGF.getLLVMContext(), 168 CGF.getContext().getTypeSize(T)); 169 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 170 171 llvm::Value *Args[2]; 172 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 173 llvm::Type *ValueType = Args[1]->getType(); 174 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 175 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 176 177 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 178 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 179 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); 180 if (Invert) 181 Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result, 182 llvm::ConstantInt::get(IntType, -1)); 183 Result = EmitFromInt(CGF, Result, T, ValueType); 184 return RValue::get(Result); 185 } 186 187 /// @brief Utility to insert an atomic cmpxchg instruction. 188 /// 189 /// @param CGF The current codegen function. 190 /// @param E Builtin call expression to convert to cmpxchg. 191 /// arg0 - address to operate on 192 /// arg1 - value to compare with 193 /// arg2 - new value 194 /// @param ReturnBool Specifies whether to return success flag of 195 /// cmpxchg result or the old value. 196 /// 197 /// @returns result of cmpxchg, according to ReturnBool 198 static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E, 199 bool ReturnBool) { 200 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType(); 201 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 202 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 203 204 llvm::IntegerType *IntType = llvm::IntegerType::get( 205 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T)); 206 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 207 208 Value *Args[3]; 209 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 210 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 211 llvm::Type *ValueType = Args[1]->getType(); 212 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 213 Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType); 214 215 Value *Pair = CGF.Builder.CreateAtomicCmpXchg( 216 Args[0], Args[1], Args[2], llvm::AtomicOrdering::SequentiallyConsistent, 217 llvm::AtomicOrdering::SequentiallyConsistent); 218 if (ReturnBool) 219 // Extract boolean success flag and zext it to int. 220 return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1), 221 CGF.ConvertType(E->getType())); 222 else 223 // Extract old value and emit it using the same type as compare value. 224 return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T, 225 ValueType); 226 } 227 228 // Emit a simple mangled intrinsic that has 1 argument and a return type 229 // matching the argument type. 230 static Value *emitUnaryBuiltin(CodeGenFunction &CGF, 231 const CallExpr *E, 232 unsigned IntrinsicID) { 233 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 234 235 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 236 return CGF.Builder.CreateCall(F, Src0); 237 } 238 239 // Emit an intrinsic that has 2 operands of the same type as its result. 240 static Value *emitBinaryBuiltin(CodeGenFunction &CGF, 241 const CallExpr *E, 242 unsigned IntrinsicID) { 243 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 244 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 245 246 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 247 return CGF.Builder.CreateCall(F, { Src0, Src1 }); 248 } 249 250 // Emit an intrinsic that has 3 operands of the same type as its result. 251 static Value *emitTernaryBuiltin(CodeGenFunction &CGF, 252 const CallExpr *E, 253 unsigned IntrinsicID) { 254 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 255 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 256 llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2)); 257 258 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 259 return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 }); 260 } 261 262 // Emit an intrinsic that has 1 float or double operand, and 1 integer. 263 static Value *emitFPIntBuiltin(CodeGenFunction &CGF, 264 const CallExpr *E, 265 unsigned IntrinsicID) { 266 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 267 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 268 269 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 270 return CGF.Builder.CreateCall(F, {Src0, Src1}); 271 } 272 273 /// EmitFAbs - Emit a call to @llvm.fabs(). 274 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) { 275 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType()); 276 llvm::CallInst *Call = CGF.Builder.CreateCall(F, V); 277 Call->setDoesNotAccessMemory(); 278 return Call; 279 } 280 281 /// Emit the computation of the sign bit for a floating point value. Returns 282 /// the i1 sign bit value. 283 static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) { 284 LLVMContext &C = CGF.CGM.getLLVMContext(); 285 286 llvm::Type *Ty = V->getType(); 287 int Width = Ty->getPrimitiveSizeInBits(); 288 llvm::Type *IntTy = llvm::IntegerType::get(C, Width); 289 V = CGF.Builder.CreateBitCast(V, IntTy); 290 if (Ty->isPPC_FP128Ty()) { 291 // We want the sign bit of the higher-order double. The bitcast we just 292 // did works as if the double-double was stored to memory and then 293 // read as an i128. The "store" will put the higher-order double in the 294 // lower address in both little- and big-Endian modes, but the "load" 295 // will treat those bits as a different part of the i128: the low bits in 296 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian 297 // we need to shift the high bits down to the low before truncating. 298 Width >>= 1; 299 if (CGF.getTarget().isBigEndian()) { 300 Value *ShiftCst = llvm::ConstantInt::get(IntTy, Width); 301 V = CGF.Builder.CreateLShr(V, ShiftCst); 302 } 303 // We are truncating value in order to extract the higher-order 304 // double, which we will be using to extract the sign from. 305 IntTy = llvm::IntegerType::get(C, Width); 306 V = CGF.Builder.CreateTrunc(V, IntTy); 307 } 308 Value *Zero = llvm::Constant::getNullValue(IntTy); 309 return CGF.Builder.CreateICmpSLT(V, Zero); 310 } 311 312 static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, 313 const CallExpr *E, llvm::Constant *calleeValue) { 314 CGCallee callee = CGCallee::forDirect(calleeValue, FD); 315 return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); 316 } 317 318 /// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.* 319 /// depending on IntrinsicID. 320 /// 321 /// \arg CGF The current codegen function. 322 /// \arg IntrinsicID The ID for the Intrinsic we wish to generate. 323 /// \arg X The first argument to the llvm.*.with.overflow.*. 324 /// \arg Y The second argument to the llvm.*.with.overflow.*. 325 /// \arg Carry The carry returned by the llvm.*.with.overflow.*. 326 /// \returns The result (i.e. sum/product) returned by the intrinsic. 327 static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF, 328 const llvm::Intrinsic::ID IntrinsicID, 329 llvm::Value *X, llvm::Value *Y, 330 llvm::Value *&Carry) { 331 // Make sure we have integers of the same width. 332 assert(X->getType() == Y->getType() && 333 "Arguments must be the same type. (Did you forget to make sure both " 334 "arguments have the same integer width?)"); 335 336 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType()); 337 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y}); 338 Carry = CGF.Builder.CreateExtractValue(Tmp, 1); 339 return CGF.Builder.CreateExtractValue(Tmp, 0); 340 } 341 342 static Value *emitRangedBuiltin(CodeGenFunction &CGF, 343 unsigned IntrinsicID, 344 int low, int high) { 345 llvm::MDBuilder MDHelper(CGF.getLLVMContext()); 346 llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high)); 347 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {}); 348 llvm::Instruction *Call = CGF.Builder.CreateCall(F); 349 Call->setMetadata(llvm::LLVMContext::MD_range, RNode); 350 return Call; 351 } 352 353 namespace { 354 struct WidthAndSignedness { 355 unsigned Width; 356 bool Signed; 357 }; 358 } 359 360 static WidthAndSignedness 361 getIntegerWidthAndSignedness(const clang::ASTContext &context, 362 const clang::QualType Type) { 363 assert(Type->isIntegerType() && "Given type is not an integer."); 364 unsigned Width = Type->isBooleanType() ? 1 : context.getTypeInfo(Type).Width; 365 bool Signed = Type->isSignedIntegerType(); 366 return {Width, Signed}; 367 } 368 369 // Given one or more integer types, this function produces an integer type that 370 // encompasses them: any value in one of the given types could be expressed in 371 // the encompassing type. 372 static struct WidthAndSignedness 373 EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) { 374 assert(Types.size() > 0 && "Empty list of types."); 375 376 // If any of the given types is signed, we must return a signed type. 377 bool Signed = false; 378 for (const auto &Type : Types) { 379 Signed |= Type.Signed; 380 } 381 382 // The encompassing type must have a width greater than or equal to the width 383 // of the specified types. Aditionally, if the encompassing type is signed, 384 // its width must be strictly greater than the width of any unsigned types 385 // given. 386 unsigned Width = 0; 387 for (const auto &Type : Types) { 388 unsigned MinWidth = Type.Width + (Signed && !Type.Signed); 389 if (Width < MinWidth) { 390 Width = MinWidth; 391 } 392 } 393 394 return {Width, Signed}; 395 } 396 397 Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) { 398 llvm::Type *DestType = Int8PtrTy; 399 if (ArgValue->getType() != DestType) 400 ArgValue = 401 Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data()); 402 403 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend; 404 return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue); 405 } 406 407 /// Checks if using the result of __builtin_object_size(p, @p From) in place of 408 /// __builtin_object_size(p, @p To) is correct 409 static bool areBOSTypesCompatible(int From, int To) { 410 // Note: Our __builtin_object_size implementation currently treats Type=0 and 411 // Type=2 identically. Encoding this implementation detail here may make 412 // improving __builtin_object_size difficult in the future, so it's omitted. 413 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2); 414 } 415 416 static llvm::Value * 417 getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) { 418 return ConstantInt::get(ResType, (Type & 2) ? 0 : -1, /*isSigned=*/true); 419 } 420 421 llvm::Value * 422 CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, 423 llvm::IntegerType *ResType) { 424 uint64_t ObjectSize; 425 if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type)) 426 return emitBuiltinObjectSize(E, Type, ResType); 427 return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); 428 } 429 430 /// Returns a Value corresponding to the size of the given expression. 431 /// This Value may be either of the following: 432 /// - A llvm::Argument (if E is a param with the pass_object_size attribute on 433 /// it) 434 /// - A call to the @llvm.objectsize intrinsic 435 llvm::Value * 436 CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, 437 llvm::IntegerType *ResType) { 438 // We need to reference an argument if the pointer is a parameter with the 439 // pass_object_size attribute. 440 if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) { 441 auto *Param = dyn_cast<ParmVarDecl>(D->getDecl()); 442 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>(); 443 if (Param != nullptr && PS != nullptr && 444 areBOSTypesCompatible(PS->getType(), Type)) { 445 auto Iter = SizeArguments.find(Param); 446 assert(Iter != SizeArguments.end()); 447 448 const ImplicitParamDecl *D = Iter->second; 449 auto DIter = LocalDeclMap.find(D); 450 assert(DIter != LocalDeclMap.end()); 451 452 return EmitLoadOfScalar(DIter->second, /*volatile=*/false, 453 getContext().getSizeType(), E->getLocStart()); 454 } 455 } 456 457 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't 458 // evaluate E for side-effects. In either case, we shouldn't lower to 459 // @llvm.objectsize. 460 if (Type == 3 || E->HasSideEffects(getContext())) 461 return getDefaultBuiltinObjectSizeResult(Type, ResType); 462 463 // LLVM only supports 0 and 2, make sure that we pass along that 464 // as a boolean. 465 auto *CI = ConstantInt::get(Builder.getInt1Ty(), (Type & 2) >> 1); 466 // FIXME: Get right address space. 467 llvm::Type *Tys[] = {ResType, Builder.getInt8PtrTy(0)}; 468 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, Tys); 469 return Builder.CreateCall(F, {EmitScalarExpr(E), CI}); 470 } 471 472 // Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we 473 // handle them here. 474 enum class CodeGenFunction::MSVCIntrin { 475 _BitScanForward, 476 _BitScanReverse, 477 _InterlockedAnd, 478 _InterlockedDecrement, 479 _InterlockedExchange, 480 _InterlockedExchangeAdd, 481 _InterlockedExchangeSub, 482 _InterlockedIncrement, 483 _InterlockedOr, 484 _InterlockedXor, 485 __fastfail, 486 }; 487 488 Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, 489 const CallExpr *E) { 490 switch (BuiltinID) { 491 case MSVCIntrin::_BitScanForward: 492 case MSVCIntrin::_BitScanReverse: { 493 Value *ArgValue = EmitScalarExpr(E->getArg(1)); 494 495 llvm::Type *ArgType = ArgValue->getType(); 496 llvm::Type *IndexType = 497 EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); 498 llvm::Type *ResultType = ConvertType(E->getType()); 499 500 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 501 Value *ResZero = llvm::Constant::getNullValue(ResultType); 502 Value *ResOne = llvm::ConstantInt::get(ResultType, 1); 503 504 BasicBlock *Begin = Builder.GetInsertBlock(); 505 BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn); 506 Builder.SetInsertPoint(End); 507 PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result"); 508 509 Builder.SetInsertPoint(Begin); 510 Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); 511 BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn); 512 Builder.CreateCondBr(IsZero, End, NotZero); 513 Result->addIncoming(ResZero, Begin); 514 515 Builder.SetInsertPoint(NotZero); 516 Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); 517 518 if (BuiltinID == MSVCIntrin::_BitScanForward) { 519 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 520 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 521 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 522 Builder.CreateStore(ZeroCount, IndexAddress, false); 523 } else { 524 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 525 Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); 526 527 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 528 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 529 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 530 Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); 531 Builder.CreateStore(Index, IndexAddress, false); 532 } 533 Builder.CreateBr(End); 534 Result->addIncoming(ResOne, NotZero); 535 536 Builder.SetInsertPoint(End); 537 return Result; 538 } 539 case MSVCIntrin::_InterlockedAnd: 540 return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E); 541 case MSVCIntrin::_InterlockedExchange: 542 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E); 543 case MSVCIntrin::_InterlockedExchangeAdd: 544 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E); 545 case MSVCIntrin::_InterlockedExchangeSub: 546 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Sub, E); 547 case MSVCIntrin::_InterlockedOr: 548 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E); 549 case MSVCIntrin::_InterlockedXor: 550 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E); 551 552 case MSVCIntrin::_InterlockedDecrement: { 553 llvm::Type *IntTy = ConvertType(E->getType()); 554 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 555 AtomicRMWInst::Sub, 556 EmitScalarExpr(E->getArg(0)), 557 ConstantInt::get(IntTy, 1), 558 llvm::AtomicOrdering::SequentiallyConsistent); 559 return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1)); 560 } 561 case MSVCIntrin::_InterlockedIncrement: { 562 llvm::Type *IntTy = ConvertType(E->getType()); 563 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 564 AtomicRMWInst::Add, 565 EmitScalarExpr(E->getArg(0)), 566 ConstantInt::get(IntTy, 1), 567 llvm::AtomicOrdering::SequentiallyConsistent); 568 return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1)); 569 } 570 571 case MSVCIntrin::__fastfail: { 572 // Request immediate process termination from the kernel. The instruction 573 // sequences to do this are documented on MSDN: 574 // https://msdn.microsoft.com/en-us/library/dn774154.aspx 575 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch(); 576 StringRef Asm, Constraints; 577 switch (ISA) { 578 default: 579 ErrorUnsupported(E, "__fastfail call for this architecture"); 580 break; 581 case llvm::Triple::x86: 582 case llvm::Triple::x86_64: 583 Asm = "int $$0x29"; 584 Constraints = "{cx}"; 585 break; 586 case llvm::Triple::thumb: 587 Asm = "udf #251"; 588 Constraints = "{r0}"; 589 break; 590 } 591 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false); 592 llvm::InlineAsm *IA = 593 llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true); 594 llvm::AttributeSet NoReturnAttr = 595 AttributeSet::get(getLLVMContext(), llvm::AttributeSet::FunctionIndex, 596 llvm::Attribute::NoReturn); 597 CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0))); 598 CS.setAttributes(NoReturnAttr); 599 return CS.getInstruction(); 600 } 601 } 602 llvm_unreachable("Incorrect MSVC intrinsic!"); 603 } 604 605 namespace { 606 // ARC cleanup for __builtin_os_log_format 607 struct CallObjCArcUse final : EHScopeStack::Cleanup { 608 CallObjCArcUse(llvm::Value *object) : object(object) {} 609 llvm::Value *object; 610 611 void Emit(CodeGenFunction &CGF, Flags flags) override { 612 CGF.EmitARCIntrinsicUse(object); 613 } 614 }; 615 } 616 617 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 618 unsigned BuiltinID, const CallExpr *E, 619 ReturnValueSlot ReturnValue) { 620 // See if we can constant fold this builtin. If so, don't emit it at all. 621 Expr::EvalResult Result; 622 if (E->EvaluateAsRValue(Result, CGM.getContext()) && 623 !Result.hasSideEffects()) { 624 if (Result.Val.isInt()) 625 return RValue::get(llvm::ConstantInt::get(getLLVMContext(), 626 Result.Val.getInt())); 627 if (Result.Val.isFloat()) 628 return RValue::get(llvm::ConstantFP::get(getLLVMContext(), 629 Result.Val.getFloat())); 630 } 631 632 switch (BuiltinID) { 633 default: break; // Handle intrinsics and libm functions below. 634 case Builtin::BI__builtin___CFStringMakeConstantString: 635 case Builtin::BI__builtin___NSStringMakeConstantString: 636 return RValue::get(CGM.EmitConstantExpr(E, E->getType(), nullptr)); 637 case Builtin::BI__builtin_stdarg_start: 638 case Builtin::BI__builtin_va_start: 639 case Builtin::BI__va_start: 640 case Builtin::BI__builtin_va_end: 641 return RValue::get( 642 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start 643 ? EmitScalarExpr(E->getArg(0)) 644 : EmitVAListRef(E->getArg(0)).getPointer(), 645 BuiltinID != Builtin::BI__builtin_va_end)); 646 case Builtin::BI__builtin_va_copy: { 647 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer(); 648 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer(); 649 650 llvm::Type *Type = Int8PtrTy; 651 652 DstPtr = Builder.CreateBitCast(DstPtr, Type); 653 SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 654 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), 655 {DstPtr, SrcPtr})); 656 } 657 case Builtin::BI__builtin_abs: 658 case Builtin::BI__builtin_labs: 659 case Builtin::BI__builtin_llabs: { 660 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 661 662 Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 663 Value *CmpResult = 664 Builder.CreateICmpSGE(ArgValue, 665 llvm::Constant::getNullValue(ArgValue->getType()), 666 "abscond"); 667 Value *Result = 668 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 669 670 return RValue::get(Result); 671 } 672 case Builtin::BI__builtin_fabs: 673 case Builtin::BI__builtin_fabsf: 674 case Builtin::BI__builtin_fabsl: { 675 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs)); 676 } 677 case Builtin::BI__builtin_fmod: 678 case Builtin::BI__builtin_fmodf: 679 case Builtin::BI__builtin_fmodl: { 680 Value *Arg1 = EmitScalarExpr(E->getArg(0)); 681 Value *Arg2 = EmitScalarExpr(E->getArg(1)); 682 Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod"); 683 return RValue::get(Result); 684 } 685 case Builtin::BI__builtin_copysign: 686 case Builtin::BI__builtin_copysignf: 687 case Builtin::BI__builtin_copysignl: { 688 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign)); 689 } 690 case Builtin::BI__builtin_ceil: 691 case Builtin::BI__builtin_ceilf: 692 case Builtin::BI__builtin_ceill: { 693 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil)); 694 } 695 case Builtin::BI__builtin_floor: 696 case Builtin::BI__builtin_floorf: 697 case Builtin::BI__builtin_floorl: { 698 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor)); 699 } 700 case Builtin::BI__builtin_trunc: 701 case Builtin::BI__builtin_truncf: 702 case Builtin::BI__builtin_truncl: { 703 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc)); 704 } 705 case Builtin::BI__builtin_rint: 706 case Builtin::BI__builtin_rintf: 707 case Builtin::BI__builtin_rintl: { 708 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint)); 709 } 710 case Builtin::BI__builtin_nearbyint: 711 case Builtin::BI__builtin_nearbyintf: 712 case Builtin::BI__builtin_nearbyintl: { 713 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint)); 714 } 715 case Builtin::BI__builtin_round: 716 case Builtin::BI__builtin_roundf: 717 case Builtin::BI__builtin_roundl: { 718 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round)); 719 } 720 case Builtin::BI__builtin_fmin: 721 case Builtin::BI__builtin_fminf: 722 case Builtin::BI__builtin_fminl: { 723 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum)); 724 } 725 case Builtin::BI__builtin_fmax: 726 case Builtin::BI__builtin_fmaxf: 727 case Builtin::BI__builtin_fmaxl: { 728 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum)); 729 } 730 case Builtin::BI__builtin_conj: 731 case Builtin::BI__builtin_conjf: 732 case Builtin::BI__builtin_conjl: { 733 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 734 Value *Real = ComplexVal.first; 735 Value *Imag = ComplexVal.second; 736 Value *Zero = 737 Imag->getType()->isFPOrFPVectorTy() 738 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) 739 : llvm::Constant::getNullValue(Imag->getType()); 740 741 Imag = Builder.CreateFSub(Zero, Imag, "sub"); 742 return RValue::getComplex(std::make_pair(Real, Imag)); 743 } 744 case Builtin::BI__builtin_creal: 745 case Builtin::BI__builtin_crealf: 746 case Builtin::BI__builtin_creall: 747 case Builtin::BIcreal: 748 case Builtin::BIcrealf: 749 case Builtin::BIcreall: { 750 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 751 return RValue::get(ComplexVal.first); 752 } 753 754 case Builtin::BI__builtin_cimag: 755 case Builtin::BI__builtin_cimagf: 756 case Builtin::BI__builtin_cimagl: 757 case Builtin::BIcimag: 758 case Builtin::BIcimagf: 759 case Builtin::BIcimagl: { 760 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 761 return RValue::get(ComplexVal.second); 762 } 763 764 case Builtin::BI__builtin_ctzs: 765 case Builtin::BI__builtin_ctz: 766 case Builtin::BI__builtin_ctzl: 767 case Builtin::BI__builtin_ctzll: { 768 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 769 770 llvm::Type *ArgType = ArgValue->getType(); 771 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 772 773 llvm::Type *ResultType = ConvertType(E->getType()); 774 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 775 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 776 if (Result->getType() != ResultType) 777 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 778 "cast"); 779 return RValue::get(Result); 780 } 781 case Builtin::BI__builtin_clzs: 782 case Builtin::BI__builtin_clz: 783 case Builtin::BI__builtin_clzl: 784 case Builtin::BI__builtin_clzll: { 785 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 786 787 llvm::Type *ArgType = ArgValue->getType(); 788 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 789 790 llvm::Type *ResultType = ConvertType(E->getType()); 791 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 792 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 793 if (Result->getType() != ResultType) 794 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 795 "cast"); 796 return RValue::get(Result); 797 } 798 case Builtin::BI__builtin_ffs: 799 case Builtin::BI__builtin_ffsl: 800 case Builtin::BI__builtin_ffsll: { 801 // ffs(x) -> x ? cttz(x) + 1 : 0 802 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 803 804 llvm::Type *ArgType = ArgValue->getType(); 805 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 806 807 llvm::Type *ResultType = ConvertType(E->getType()); 808 Value *Tmp = 809 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}), 810 llvm::ConstantInt::get(ArgType, 1)); 811 Value *Zero = llvm::Constant::getNullValue(ArgType); 812 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 813 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 814 if (Result->getType() != ResultType) 815 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 816 "cast"); 817 return RValue::get(Result); 818 } 819 case Builtin::BI__builtin_parity: 820 case Builtin::BI__builtin_parityl: 821 case Builtin::BI__builtin_parityll: { 822 // parity(x) -> ctpop(x) & 1 823 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 824 825 llvm::Type *ArgType = ArgValue->getType(); 826 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 827 828 llvm::Type *ResultType = ConvertType(E->getType()); 829 Value *Tmp = Builder.CreateCall(F, ArgValue); 830 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1)); 831 if (Result->getType() != ResultType) 832 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 833 "cast"); 834 return RValue::get(Result); 835 } 836 case Builtin::BI__popcnt16: 837 case Builtin::BI__popcnt: 838 case Builtin::BI__popcnt64: 839 case Builtin::BI__builtin_popcount: 840 case Builtin::BI__builtin_popcountl: 841 case Builtin::BI__builtin_popcountll: { 842 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 843 844 llvm::Type *ArgType = ArgValue->getType(); 845 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 846 847 llvm::Type *ResultType = ConvertType(E->getType()); 848 Value *Result = Builder.CreateCall(F, ArgValue); 849 if (Result->getType() != ResultType) 850 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 851 "cast"); 852 return RValue::get(Result); 853 } 854 case Builtin::BI_rotr8: 855 case Builtin::BI_rotr16: 856 case Builtin::BI_rotr: 857 case Builtin::BI_lrotr: 858 case Builtin::BI_rotr64: { 859 Value *Val = EmitScalarExpr(E->getArg(0)); 860 Value *Shift = EmitScalarExpr(E->getArg(1)); 861 862 llvm::Type *ArgType = Val->getType(); 863 Shift = Builder.CreateIntCast(Shift, ArgType, false); 864 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 865 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 866 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 867 868 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 869 Shift = Builder.CreateAnd(Shift, Mask); 870 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); 871 872 Value *RightShifted = Builder.CreateLShr(Val, Shift); 873 Value *LeftShifted = Builder.CreateShl(Val, LeftShift); 874 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 875 876 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 877 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 878 return RValue::get(Result); 879 } 880 case Builtin::BI_rotl8: 881 case Builtin::BI_rotl16: 882 case Builtin::BI_rotl: 883 case Builtin::BI_lrotl: 884 case Builtin::BI_rotl64: { 885 Value *Val = EmitScalarExpr(E->getArg(0)); 886 Value *Shift = EmitScalarExpr(E->getArg(1)); 887 888 llvm::Type *ArgType = Val->getType(); 889 Shift = Builder.CreateIntCast(Shift, ArgType, false); 890 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 891 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 892 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 893 894 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 895 Shift = Builder.CreateAnd(Shift, Mask); 896 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); 897 898 Value *LeftShifted = Builder.CreateShl(Val, Shift); 899 Value *RightShifted = Builder.CreateLShr(Val, RightShift); 900 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 901 902 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 903 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 904 return RValue::get(Result); 905 } 906 case Builtin::BI__builtin_unpredictable: { 907 // Always return the argument of __builtin_unpredictable. LLVM does not 908 // handle this builtin. Metadata for this builtin should be added directly 909 // to instructions such as branches or switches that use it. 910 return RValue::get(EmitScalarExpr(E->getArg(0))); 911 } 912 case Builtin::BI__builtin_expect: { 913 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 914 llvm::Type *ArgType = ArgValue->getType(); 915 916 Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); 917 // Don't generate llvm.expect on -O0 as the backend won't use it for 918 // anything. 919 // Note, we still IRGen ExpectedValue because it could have side-effects. 920 if (CGM.getCodeGenOpts().OptimizationLevel == 0) 921 return RValue::get(ArgValue); 922 923 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType); 924 Value *Result = 925 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval"); 926 return RValue::get(Result); 927 } 928 case Builtin::BI__builtin_assume_aligned: { 929 Value *PtrValue = EmitScalarExpr(E->getArg(0)); 930 Value *OffsetValue = 931 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr; 932 933 Value *AlignmentValue = EmitScalarExpr(E->getArg(1)); 934 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue); 935 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue(); 936 937 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue); 938 return RValue::get(PtrValue); 939 } 940 case Builtin::BI__assume: 941 case Builtin::BI__builtin_assume: { 942 if (E->getArg(0)->HasSideEffects(getContext())) 943 return RValue::get(nullptr); 944 945 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 946 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume); 947 return RValue::get(Builder.CreateCall(FnAssume, ArgValue)); 948 } 949 case Builtin::BI__builtin_bswap16: 950 case Builtin::BI__builtin_bswap32: 951 case Builtin::BI__builtin_bswap64: { 952 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap)); 953 } 954 case Builtin::BI__builtin_bitreverse8: 955 case Builtin::BI__builtin_bitreverse16: 956 case Builtin::BI__builtin_bitreverse32: 957 case Builtin::BI__builtin_bitreverse64: { 958 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse)); 959 } 960 case Builtin::BI__builtin_object_size: { 961 unsigned Type = 962 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); 963 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType())); 964 965 // We pass this builtin onto the optimizer so that it can figure out the 966 // object size in more complex cases. 967 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType)); 968 } 969 case Builtin::BI__builtin_prefetch: { 970 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 971 // FIXME: Technically these constants should of type 'int', yes? 972 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 973 llvm::ConstantInt::get(Int32Ty, 0); 974 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 975 llvm::ConstantInt::get(Int32Ty, 3); 976 Value *Data = llvm::ConstantInt::get(Int32Ty, 1); 977 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 978 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data})); 979 } 980 case Builtin::BI__builtin_readcyclecounter: { 981 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter); 982 return RValue::get(Builder.CreateCall(F)); 983 } 984 case Builtin::BI__builtin___clear_cache: { 985 Value *Begin = EmitScalarExpr(E->getArg(0)); 986 Value *End = EmitScalarExpr(E->getArg(1)); 987 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache); 988 return RValue::get(Builder.CreateCall(F, {Begin, End})); 989 } 990 case Builtin::BI__builtin_trap: 991 return RValue::get(EmitTrapCall(Intrinsic::trap)); 992 case Builtin::BI__debugbreak: 993 return RValue::get(EmitTrapCall(Intrinsic::debugtrap)); 994 case Builtin::BI__builtin_unreachable: { 995 if (SanOpts.has(SanitizerKind::Unreachable)) { 996 SanitizerScope SanScope(this); 997 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()), 998 SanitizerKind::Unreachable), 999 SanitizerHandler::BuiltinUnreachable, 1000 EmitCheckSourceLocation(E->getExprLoc()), None); 1001 } else 1002 Builder.CreateUnreachable(); 1003 1004 // We do need to preserve an insertion point. 1005 EmitBlock(createBasicBlock("unreachable.cont")); 1006 1007 return RValue::get(nullptr); 1008 } 1009 1010 case Builtin::BI__builtin_powi: 1011 case Builtin::BI__builtin_powif: 1012 case Builtin::BI__builtin_powil: { 1013 Value *Base = EmitScalarExpr(E->getArg(0)); 1014 Value *Exponent = EmitScalarExpr(E->getArg(1)); 1015 llvm::Type *ArgType = Base->getType(); 1016 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType); 1017 return RValue::get(Builder.CreateCall(F, {Base, Exponent})); 1018 } 1019 1020 case Builtin::BI__builtin_isgreater: 1021 case Builtin::BI__builtin_isgreaterequal: 1022 case Builtin::BI__builtin_isless: 1023 case Builtin::BI__builtin_islessequal: 1024 case Builtin::BI__builtin_islessgreater: 1025 case Builtin::BI__builtin_isunordered: { 1026 // Ordered comparisons: we know the arguments to these are matching scalar 1027 // floating point values. 1028 Value *LHS = EmitScalarExpr(E->getArg(0)); 1029 Value *RHS = EmitScalarExpr(E->getArg(1)); 1030 1031 switch (BuiltinID) { 1032 default: llvm_unreachable("Unknown ordered comparison"); 1033 case Builtin::BI__builtin_isgreater: 1034 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 1035 break; 1036 case Builtin::BI__builtin_isgreaterequal: 1037 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 1038 break; 1039 case Builtin::BI__builtin_isless: 1040 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 1041 break; 1042 case Builtin::BI__builtin_islessequal: 1043 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 1044 break; 1045 case Builtin::BI__builtin_islessgreater: 1046 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 1047 break; 1048 case Builtin::BI__builtin_isunordered: 1049 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 1050 break; 1051 } 1052 // ZExt bool to int type. 1053 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()))); 1054 } 1055 case Builtin::BI__builtin_isnan: { 1056 Value *V = EmitScalarExpr(E->getArg(0)); 1057 V = Builder.CreateFCmpUNO(V, V, "cmp"); 1058 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1059 } 1060 1061 case Builtin::BIfinite: 1062 case Builtin::BI__finite: 1063 case Builtin::BIfinitef: 1064 case Builtin::BI__finitef: 1065 case Builtin::BIfinitel: 1066 case Builtin::BI__finitel: 1067 case Builtin::BI__builtin_isinf: 1068 case Builtin::BI__builtin_isfinite: { 1069 // isinf(x) --> fabs(x) == infinity 1070 // isfinite(x) --> fabs(x) != infinity 1071 // x != NaN via the ordered compare in either case. 1072 Value *V = EmitScalarExpr(E->getArg(0)); 1073 Value *Fabs = EmitFAbs(*this, V); 1074 Constant *Infinity = ConstantFP::getInfinity(V->getType()); 1075 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf) 1076 ? CmpInst::FCMP_OEQ 1077 : CmpInst::FCMP_ONE; 1078 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf"); 1079 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType()))); 1080 } 1081 1082 case Builtin::BI__builtin_isinf_sign: { 1083 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0 1084 Value *Arg = EmitScalarExpr(E->getArg(0)); 1085 Value *AbsArg = EmitFAbs(*this, Arg); 1086 Value *IsInf = Builder.CreateFCmpOEQ( 1087 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf"); 1088 Value *IsNeg = EmitSignBit(*this, Arg); 1089 1090 llvm::Type *IntTy = ConvertType(E->getType()); 1091 Value *Zero = Constant::getNullValue(IntTy); 1092 Value *One = ConstantInt::get(IntTy, 1); 1093 Value *NegativeOne = ConstantInt::get(IntTy, -1); 1094 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One); 1095 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero); 1096 return RValue::get(Result); 1097 } 1098 1099 case Builtin::BI__builtin_isnormal: { 1100 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 1101 Value *V = EmitScalarExpr(E->getArg(0)); 1102 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 1103 1104 Value *Abs = EmitFAbs(*this, V); 1105 Value *IsLessThanInf = 1106 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 1107 APFloat Smallest = APFloat::getSmallestNormalized( 1108 getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 1109 Value *IsNormal = 1110 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 1111 "isnormal"); 1112 V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 1113 V = Builder.CreateAnd(V, IsNormal, "and"); 1114 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1115 } 1116 1117 case Builtin::BI__builtin_fpclassify: { 1118 Value *V = EmitScalarExpr(E->getArg(5)); 1119 llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 1120 1121 // Create Result 1122 BasicBlock *Begin = Builder.GetInsertBlock(); 1123 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 1124 Builder.SetInsertPoint(End); 1125 PHINode *Result = 1126 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4, 1127 "fpclassify_result"); 1128 1129 // if (V==0) return FP_ZERO 1130 Builder.SetInsertPoint(Begin); 1131 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 1132 "iszero"); 1133 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 1134 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 1135 Builder.CreateCondBr(IsZero, End, NotZero); 1136 Result->addIncoming(ZeroLiteral, Begin); 1137 1138 // if (V != V) return FP_NAN 1139 Builder.SetInsertPoint(NotZero); 1140 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 1141 Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 1142 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 1143 Builder.CreateCondBr(IsNan, End, NotNan); 1144 Result->addIncoming(NanLiteral, NotZero); 1145 1146 // if (fabs(V) == infinity) return FP_INFINITY 1147 Builder.SetInsertPoint(NotNan); 1148 Value *VAbs = EmitFAbs(*this, V); 1149 Value *IsInf = 1150 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 1151 "isinf"); 1152 Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 1153 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 1154 Builder.CreateCondBr(IsInf, End, NotInf); 1155 Result->addIncoming(InfLiteral, NotNan); 1156 1157 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 1158 Builder.SetInsertPoint(NotInf); 1159 APFloat Smallest = APFloat::getSmallestNormalized( 1160 getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 1161 Value *IsNormal = 1162 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 1163 "isnormal"); 1164 Value *NormalResult = 1165 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 1166 EmitScalarExpr(E->getArg(3))); 1167 Builder.CreateBr(End); 1168 Result->addIncoming(NormalResult, NotInf); 1169 1170 // return Result 1171 Builder.SetInsertPoint(End); 1172 return RValue::get(Result); 1173 } 1174 1175 case Builtin::BIalloca: 1176 case Builtin::BI_alloca: 1177 case Builtin::BI__builtin_alloca: { 1178 Value *Size = EmitScalarExpr(E->getArg(0)); 1179 const TargetInfo &TI = getContext().getTargetInfo(); 1180 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__. 1181 unsigned SuitableAlignmentInBytes = 1182 CGM.getContext() 1183 .toCharUnitsFromBits(TI.getSuitableAlign()) 1184 .getQuantity(); 1185 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1186 AI->setAlignment(SuitableAlignmentInBytes); 1187 return RValue::get(AI); 1188 } 1189 1190 case Builtin::BI__builtin_alloca_with_align: { 1191 Value *Size = EmitScalarExpr(E->getArg(0)); 1192 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1)); 1193 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue); 1194 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue(); 1195 unsigned AlignmentInBytes = 1196 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity(); 1197 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1198 AI->setAlignment(AlignmentInBytes); 1199 return RValue::get(AI); 1200 } 1201 1202 case Builtin::BIbzero: 1203 case Builtin::BI__builtin_bzero: { 1204 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1205 Value *SizeVal = EmitScalarExpr(E->getArg(1)); 1206 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1207 E->getArg(0)->getExprLoc(), FD, 0); 1208 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false); 1209 return RValue::get(Dest.getPointer()); 1210 } 1211 case Builtin::BImemcpy: 1212 case Builtin::BI__builtin_memcpy: { 1213 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1214 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1215 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1216 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1217 E->getArg(0)->getExprLoc(), FD, 0); 1218 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1219 E->getArg(1)->getExprLoc(), FD, 1); 1220 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1221 return RValue::get(Dest.getPointer()); 1222 } 1223 1224 case Builtin::BI__builtin_char_memchr: 1225 BuiltinID = Builtin::BI__builtin_memchr; 1226 break; 1227 1228 case Builtin::BI__builtin___memcpy_chk: { 1229 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. 1230 llvm::APSInt Size, DstSize; 1231 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1232 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1233 break; 1234 if (Size.ugt(DstSize)) 1235 break; 1236 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1237 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1238 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1239 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1240 return RValue::get(Dest.getPointer()); 1241 } 1242 1243 case Builtin::BI__builtin_objc_memmove_collectable: { 1244 Address DestAddr = EmitPointerWithAlignment(E->getArg(0)); 1245 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1)); 1246 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1247 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 1248 DestAddr, SrcAddr, SizeVal); 1249 return RValue::get(DestAddr.getPointer()); 1250 } 1251 1252 case Builtin::BI__builtin___memmove_chk: { 1253 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. 1254 llvm::APSInt Size, DstSize; 1255 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1256 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1257 break; 1258 if (Size.ugt(DstSize)) 1259 break; 1260 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1261 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1262 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1263 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1264 return RValue::get(Dest.getPointer()); 1265 } 1266 1267 case Builtin::BImemmove: 1268 case Builtin::BI__builtin_memmove: { 1269 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1270 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1271 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1272 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1273 E->getArg(0)->getExprLoc(), FD, 0); 1274 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1275 E->getArg(1)->getExprLoc(), FD, 1); 1276 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1277 return RValue::get(Dest.getPointer()); 1278 } 1279 case Builtin::BImemset: 1280 case Builtin::BI__builtin_memset: { 1281 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1282 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1283 Builder.getInt8Ty()); 1284 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1285 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1286 E->getArg(0)->getExprLoc(), FD, 0); 1287 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1288 return RValue::get(Dest.getPointer()); 1289 } 1290 case Builtin::BI__builtin___memset_chk: { 1291 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. 1292 llvm::APSInt Size, DstSize; 1293 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1294 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1295 break; 1296 if (Size.ugt(DstSize)) 1297 break; 1298 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1299 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1300 Builder.getInt8Ty()); 1301 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1302 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1303 return RValue::get(Dest.getPointer()); 1304 } 1305 case Builtin::BI__builtin_dwarf_cfa: { 1306 // The offset in bytes from the first argument to the CFA. 1307 // 1308 // Why on earth is this in the frontend? Is there any reason at 1309 // all that the backend can't reasonably determine this while 1310 // lowering llvm.eh.dwarf.cfa()? 1311 // 1312 // TODO: If there's a satisfactory reason, add a target hook for 1313 // this instead of hard-coding 0, which is correct for most targets. 1314 int32_t Offset = 0; 1315 1316 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa); 1317 return RValue::get(Builder.CreateCall(F, 1318 llvm::ConstantInt::get(Int32Ty, Offset))); 1319 } 1320 case Builtin::BI__builtin_return_address: { 1321 Value *Depth = 1322 CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this); 1323 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1324 return RValue::get(Builder.CreateCall(F, Depth)); 1325 } 1326 case Builtin::BI_ReturnAddress: { 1327 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1328 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0))); 1329 } 1330 case Builtin::BI__builtin_frame_address: { 1331 Value *Depth = 1332 CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this); 1333 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress); 1334 return RValue::get(Builder.CreateCall(F, Depth)); 1335 } 1336 case Builtin::BI__builtin_extract_return_addr: { 1337 Value *Address = EmitScalarExpr(E->getArg(0)); 1338 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 1339 return RValue::get(Result); 1340 } 1341 case Builtin::BI__builtin_frob_return_addr: { 1342 Value *Address = EmitScalarExpr(E->getArg(0)); 1343 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 1344 return RValue::get(Result); 1345 } 1346 case Builtin::BI__builtin_dwarf_sp_column: { 1347 llvm::IntegerType *Ty 1348 = cast<llvm::IntegerType>(ConvertType(E->getType())); 1349 int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 1350 if (Column == -1) { 1351 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 1352 return RValue::get(llvm::UndefValue::get(Ty)); 1353 } 1354 return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 1355 } 1356 case Builtin::BI__builtin_init_dwarf_reg_size_table: { 1357 Value *Address = EmitScalarExpr(E->getArg(0)); 1358 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 1359 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 1360 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 1361 } 1362 case Builtin::BI__builtin_eh_return: { 1363 Value *Int = EmitScalarExpr(E->getArg(0)); 1364 Value *Ptr = EmitScalarExpr(E->getArg(1)); 1365 1366 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 1367 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 1368 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 1369 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 1370 ? Intrinsic::eh_return_i32 1371 : Intrinsic::eh_return_i64); 1372 Builder.CreateCall(F, {Int, Ptr}); 1373 Builder.CreateUnreachable(); 1374 1375 // We do need to preserve an insertion point. 1376 EmitBlock(createBasicBlock("builtin_eh_return.cont")); 1377 1378 return RValue::get(nullptr); 1379 } 1380 case Builtin::BI__builtin_unwind_init: { 1381 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init); 1382 return RValue::get(Builder.CreateCall(F)); 1383 } 1384 case Builtin::BI__builtin_extend_pointer: { 1385 // Extends a pointer to the size of an _Unwind_Word, which is 1386 // uint64_t on all platforms. Generally this gets poked into a 1387 // register and eventually used as an address, so if the 1388 // addressing registers are wider than pointers and the platform 1389 // doesn't implicitly ignore high-order bits when doing 1390 // addressing, we need to make sure we zext / sext based on 1391 // the platform's expectations. 1392 // 1393 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 1394 1395 // Cast the pointer to intptr_t. 1396 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1397 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 1398 1399 // If that's 64 bits, we're done. 1400 if (IntPtrTy->getBitWidth() == 64) 1401 return RValue::get(Result); 1402 1403 // Otherwise, ask the codegen data what to do. 1404 if (getTargetHooks().extendPointerWithSExt()) 1405 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 1406 else 1407 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 1408 } 1409 case Builtin::BI__builtin_setjmp: { 1410 // Buffer is a void**. 1411 Address Buf = EmitPointerWithAlignment(E->getArg(0)); 1412 1413 // Store the frame pointer to the setjmp buffer. 1414 Value *FrameAddr = 1415 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 1416 ConstantInt::get(Int32Ty, 0)); 1417 Builder.CreateStore(FrameAddr, Buf); 1418 1419 // Store the stack pointer to the setjmp buffer. 1420 Value *StackAddr = 1421 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 1422 Address StackSaveSlot = 1423 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize()); 1424 Builder.CreateStore(StackAddr, StackSaveSlot); 1425 1426 // Call LLVM's EH setjmp, which is lightweight. 1427 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 1428 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1429 return RValue::get(Builder.CreateCall(F, Buf.getPointer())); 1430 } 1431 case Builtin::BI__builtin_longjmp: { 1432 Value *Buf = EmitScalarExpr(E->getArg(0)); 1433 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1434 1435 // Call LLVM's EH longjmp, which is lightweight. 1436 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 1437 1438 // longjmp doesn't return; mark this as unreachable. 1439 Builder.CreateUnreachable(); 1440 1441 // We do need to preserve an insertion point. 1442 EmitBlock(createBasicBlock("longjmp.cont")); 1443 1444 return RValue::get(nullptr); 1445 } 1446 case Builtin::BI__sync_fetch_and_add: 1447 case Builtin::BI__sync_fetch_and_sub: 1448 case Builtin::BI__sync_fetch_and_or: 1449 case Builtin::BI__sync_fetch_and_and: 1450 case Builtin::BI__sync_fetch_and_xor: 1451 case Builtin::BI__sync_fetch_and_nand: 1452 case Builtin::BI__sync_add_and_fetch: 1453 case Builtin::BI__sync_sub_and_fetch: 1454 case Builtin::BI__sync_and_and_fetch: 1455 case Builtin::BI__sync_or_and_fetch: 1456 case Builtin::BI__sync_xor_and_fetch: 1457 case Builtin::BI__sync_nand_and_fetch: 1458 case Builtin::BI__sync_val_compare_and_swap: 1459 case Builtin::BI__sync_bool_compare_and_swap: 1460 case Builtin::BI__sync_lock_test_and_set: 1461 case Builtin::BI__sync_lock_release: 1462 case Builtin::BI__sync_swap: 1463 llvm_unreachable("Shouldn't make it through sema"); 1464 case Builtin::BI__sync_fetch_and_add_1: 1465 case Builtin::BI__sync_fetch_and_add_2: 1466 case Builtin::BI__sync_fetch_and_add_4: 1467 case Builtin::BI__sync_fetch_and_add_8: 1468 case Builtin::BI__sync_fetch_and_add_16: 1469 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E); 1470 case Builtin::BI__sync_fetch_and_sub_1: 1471 case Builtin::BI__sync_fetch_and_sub_2: 1472 case Builtin::BI__sync_fetch_and_sub_4: 1473 case Builtin::BI__sync_fetch_and_sub_8: 1474 case Builtin::BI__sync_fetch_and_sub_16: 1475 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E); 1476 case Builtin::BI__sync_fetch_and_or_1: 1477 case Builtin::BI__sync_fetch_and_or_2: 1478 case Builtin::BI__sync_fetch_and_or_4: 1479 case Builtin::BI__sync_fetch_and_or_8: 1480 case Builtin::BI__sync_fetch_and_or_16: 1481 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E); 1482 case Builtin::BI__sync_fetch_and_and_1: 1483 case Builtin::BI__sync_fetch_and_and_2: 1484 case Builtin::BI__sync_fetch_and_and_4: 1485 case Builtin::BI__sync_fetch_and_and_8: 1486 case Builtin::BI__sync_fetch_and_and_16: 1487 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E); 1488 case Builtin::BI__sync_fetch_and_xor_1: 1489 case Builtin::BI__sync_fetch_and_xor_2: 1490 case Builtin::BI__sync_fetch_and_xor_4: 1491 case Builtin::BI__sync_fetch_and_xor_8: 1492 case Builtin::BI__sync_fetch_and_xor_16: 1493 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E); 1494 case Builtin::BI__sync_fetch_and_nand_1: 1495 case Builtin::BI__sync_fetch_and_nand_2: 1496 case Builtin::BI__sync_fetch_and_nand_4: 1497 case Builtin::BI__sync_fetch_and_nand_8: 1498 case Builtin::BI__sync_fetch_and_nand_16: 1499 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E); 1500 1501 // Clang extensions: not overloaded yet. 1502 case Builtin::BI__sync_fetch_and_min: 1503 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E); 1504 case Builtin::BI__sync_fetch_and_max: 1505 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E); 1506 case Builtin::BI__sync_fetch_and_umin: 1507 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E); 1508 case Builtin::BI__sync_fetch_and_umax: 1509 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E); 1510 1511 case Builtin::BI__sync_add_and_fetch_1: 1512 case Builtin::BI__sync_add_and_fetch_2: 1513 case Builtin::BI__sync_add_and_fetch_4: 1514 case Builtin::BI__sync_add_and_fetch_8: 1515 case Builtin::BI__sync_add_and_fetch_16: 1516 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E, 1517 llvm::Instruction::Add); 1518 case Builtin::BI__sync_sub_and_fetch_1: 1519 case Builtin::BI__sync_sub_and_fetch_2: 1520 case Builtin::BI__sync_sub_and_fetch_4: 1521 case Builtin::BI__sync_sub_and_fetch_8: 1522 case Builtin::BI__sync_sub_and_fetch_16: 1523 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E, 1524 llvm::Instruction::Sub); 1525 case Builtin::BI__sync_and_and_fetch_1: 1526 case Builtin::BI__sync_and_and_fetch_2: 1527 case Builtin::BI__sync_and_and_fetch_4: 1528 case Builtin::BI__sync_and_and_fetch_8: 1529 case Builtin::BI__sync_and_and_fetch_16: 1530 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E, 1531 llvm::Instruction::And); 1532 case Builtin::BI__sync_or_and_fetch_1: 1533 case Builtin::BI__sync_or_and_fetch_2: 1534 case Builtin::BI__sync_or_and_fetch_4: 1535 case Builtin::BI__sync_or_and_fetch_8: 1536 case Builtin::BI__sync_or_and_fetch_16: 1537 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E, 1538 llvm::Instruction::Or); 1539 case Builtin::BI__sync_xor_and_fetch_1: 1540 case Builtin::BI__sync_xor_and_fetch_2: 1541 case Builtin::BI__sync_xor_and_fetch_4: 1542 case Builtin::BI__sync_xor_and_fetch_8: 1543 case Builtin::BI__sync_xor_and_fetch_16: 1544 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E, 1545 llvm::Instruction::Xor); 1546 case Builtin::BI__sync_nand_and_fetch_1: 1547 case Builtin::BI__sync_nand_and_fetch_2: 1548 case Builtin::BI__sync_nand_and_fetch_4: 1549 case Builtin::BI__sync_nand_and_fetch_8: 1550 case Builtin::BI__sync_nand_and_fetch_16: 1551 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E, 1552 llvm::Instruction::And, true); 1553 1554 case Builtin::BI__sync_val_compare_and_swap_1: 1555 case Builtin::BI__sync_val_compare_and_swap_2: 1556 case Builtin::BI__sync_val_compare_and_swap_4: 1557 case Builtin::BI__sync_val_compare_and_swap_8: 1558 case Builtin::BI__sync_val_compare_and_swap_16: 1559 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false)); 1560 1561 case Builtin::BI__sync_bool_compare_and_swap_1: 1562 case Builtin::BI__sync_bool_compare_and_swap_2: 1563 case Builtin::BI__sync_bool_compare_and_swap_4: 1564 case Builtin::BI__sync_bool_compare_and_swap_8: 1565 case Builtin::BI__sync_bool_compare_and_swap_16: 1566 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true)); 1567 1568 case Builtin::BI__sync_swap_1: 1569 case Builtin::BI__sync_swap_2: 1570 case Builtin::BI__sync_swap_4: 1571 case Builtin::BI__sync_swap_8: 1572 case Builtin::BI__sync_swap_16: 1573 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1574 1575 case Builtin::BI__sync_lock_test_and_set_1: 1576 case Builtin::BI__sync_lock_test_and_set_2: 1577 case Builtin::BI__sync_lock_test_and_set_4: 1578 case Builtin::BI__sync_lock_test_and_set_8: 1579 case Builtin::BI__sync_lock_test_and_set_16: 1580 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1581 1582 case Builtin::BI__sync_lock_release_1: 1583 case Builtin::BI__sync_lock_release_2: 1584 case Builtin::BI__sync_lock_release_4: 1585 case Builtin::BI__sync_lock_release_8: 1586 case Builtin::BI__sync_lock_release_16: { 1587 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1588 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 1589 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 1590 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 1591 StoreSize.getQuantity() * 8); 1592 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 1593 llvm::StoreInst *Store = 1594 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr, 1595 StoreSize); 1596 Store->setAtomic(llvm::AtomicOrdering::Release); 1597 return RValue::get(nullptr); 1598 } 1599 1600 case Builtin::BI__sync_synchronize: { 1601 // We assume this is supposed to correspond to a C++0x-style 1602 // sequentially-consistent fence (i.e. this is only usable for 1603 // synchonization, not device I/O or anything like that). This intrinsic 1604 // is really badly designed in the sense that in theory, there isn't 1605 // any way to safely use it... but in practice, it mostly works 1606 // to use it with non-atomic loads and stores to get acquire/release 1607 // semantics. 1608 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent); 1609 return RValue::get(nullptr); 1610 } 1611 1612 case Builtin::BI__builtin_nontemporal_load: 1613 return RValue::get(EmitNontemporalLoad(*this, E)); 1614 case Builtin::BI__builtin_nontemporal_store: 1615 return RValue::get(EmitNontemporalStore(*this, E)); 1616 case Builtin::BI__c11_atomic_is_lock_free: 1617 case Builtin::BI__atomic_is_lock_free: { 1618 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the 1619 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since 1620 // _Atomic(T) is always properly-aligned. 1621 const char *LibCallName = "__atomic_is_lock_free"; 1622 CallArgList Args; 1623 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))), 1624 getContext().getSizeType()); 1625 if (BuiltinID == Builtin::BI__atomic_is_lock_free) 1626 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))), 1627 getContext().VoidPtrTy); 1628 else 1629 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)), 1630 getContext().VoidPtrTy); 1631 const CGFunctionInfo &FuncInfo = 1632 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args); 1633 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); 1634 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); 1635 return EmitCall(FuncInfo, CGCallee::forDirect(Func), 1636 ReturnValueSlot(), Args); 1637 } 1638 1639 case Builtin::BI__atomic_test_and_set: { 1640 // Look at the argument type to determine whether this is a volatile 1641 // operation. The parameter type is always volatile. 1642 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1643 bool Volatile = 1644 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1645 1646 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1647 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 1648 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1649 Value *NewVal = Builder.getInt8(1); 1650 Value *Order = EmitScalarExpr(E->getArg(1)); 1651 if (isa<llvm::ConstantInt>(Order)) { 1652 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1653 AtomicRMWInst *Result = nullptr; 1654 switch (ord) { 1655 case 0: // memory_order_relaxed 1656 default: // invalid order 1657 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1658 llvm::AtomicOrdering::Monotonic); 1659 break; 1660 case 1: // memory_order_consume 1661 case 2: // memory_order_acquire 1662 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1663 llvm::AtomicOrdering::Acquire); 1664 break; 1665 case 3: // memory_order_release 1666 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1667 llvm::AtomicOrdering::Release); 1668 break; 1669 case 4: // memory_order_acq_rel 1670 1671 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1672 llvm::AtomicOrdering::AcquireRelease); 1673 break; 1674 case 5: // memory_order_seq_cst 1675 Result = Builder.CreateAtomicRMW( 1676 llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1677 llvm::AtomicOrdering::SequentiallyConsistent); 1678 break; 1679 } 1680 Result->setVolatile(Volatile); 1681 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1682 } 1683 1684 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1685 1686 llvm::BasicBlock *BBs[5] = { 1687 createBasicBlock("monotonic", CurFn), 1688 createBasicBlock("acquire", CurFn), 1689 createBasicBlock("release", CurFn), 1690 createBasicBlock("acqrel", CurFn), 1691 createBasicBlock("seqcst", CurFn) 1692 }; 1693 llvm::AtomicOrdering Orders[5] = { 1694 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire, 1695 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease, 1696 llvm::AtomicOrdering::SequentiallyConsistent}; 1697 1698 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1699 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1700 1701 Builder.SetInsertPoint(ContBB); 1702 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set"); 1703 1704 for (unsigned i = 0; i < 5; ++i) { 1705 Builder.SetInsertPoint(BBs[i]); 1706 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1707 Ptr, NewVal, Orders[i]); 1708 RMW->setVolatile(Volatile); 1709 Result->addIncoming(RMW, BBs[i]); 1710 Builder.CreateBr(ContBB); 1711 } 1712 1713 SI->addCase(Builder.getInt32(0), BBs[0]); 1714 SI->addCase(Builder.getInt32(1), BBs[1]); 1715 SI->addCase(Builder.getInt32(2), BBs[1]); 1716 SI->addCase(Builder.getInt32(3), BBs[2]); 1717 SI->addCase(Builder.getInt32(4), BBs[3]); 1718 SI->addCase(Builder.getInt32(5), BBs[4]); 1719 1720 Builder.SetInsertPoint(ContBB); 1721 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1722 } 1723 1724 case Builtin::BI__atomic_clear: { 1725 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1726 bool Volatile = 1727 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1728 1729 Address Ptr = EmitPointerWithAlignment(E->getArg(0)); 1730 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace(); 1731 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1732 Value *NewVal = Builder.getInt8(0); 1733 Value *Order = EmitScalarExpr(E->getArg(1)); 1734 if (isa<llvm::ConstantInt>(Order)) { 1735 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1736 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1737 switch (ord) { 1738 case 0: // memory_order_relaxed 1739 default: // invalid order 1740 Store->setOrdering(llvm::AtomicOrdering::Monotonic); 1741 break; 1742 case 3: // memory_order_release 1743 Store->setOrdering(llvm::AtomicOrdering::Release); 1744 break; 1745 case 5: // memory_order_seq_cst 1746 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent); 1747 break; 1748 } 1749 return RValue::get(nullptr); 1750 } 1751 1752 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1753 1754 llvm::BasicBlock *BBs[3] = { 1755 createBasicBlock("monotonic", CurFn), 1756 createBasicBlock("release", CurFn), 1757 createBasicBlock("seqcst", CurFn) 1758 }; 1759 llvm::AtomicOrdering Orders[3] = { 1760 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release, 1761 llvm::AtomicOrdering::SequentiallyConsistent}; 1762 1763 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1764 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1765 1766 for (unsigned i = 0; i < 3; ++i) { 1767 Builder.SetInsertPoint(BBs[i]); 1768 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1769 Store->setOrdering(Orders[i]); 1770 Builder.CreateBr(ContBB); 1771 } 1772 1773 SI->addCase(Builder.getInt32(0), BBs[0]); 1774 SI->addCase(Builder.getInt32(3), BBs[1]); 1775 SI->addCase(Builder.getInt32(5), BBs[2]); 1776 1777 Builder.SetInsertPoint(ContBB); 1778 return RValue::get(nullptr); 1779 } 1780 1781 case Builtin::BI__atomic_thread_fence: 1782 case Builtin::BI__atomic_signal_fence: 1783 case Builtin::BI__c11_atomic_thread_fence: 1784 case Builtin::BI__c11_atomic_signal_fence: { 1785 llvm::SynchronizationScope Scope; 1786 if (BuiltinID == Builtin::BI__atomic_signal_fence || 1787 BuiltinID == Builtin::BI__c11_atomic_signal_fence) 1788 Scope = llvm::SingleThread; 1789 else 1790 Scope = llvm::CrossThread; 1791 Value *Order = EmitScalarExpr(E->getArg(0)); 1792 if (isa<llvm::ConstantInt>(Order)) { 1793 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1794 switch (ord) { 1795 case 0: // memory_order_relaxed 1796 default: // invalid order 1797 break; 1798 case 1: // memory_order_consume 1799 case 2: // memory_order_acquire 1800 Builder.CreateFence(llvm::AtomicOrdering::Acquire, Scope); 1801 break; 1802 case 3: // memory_order_release 1803 Builder.CreateFence(llvm::AtomicOrdering::Release, Scope); 1804 break; 1805 case 4: // memory_order_acq_rel 1806 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, Scope); 1807 break; 1808 case 5: // memory_order_seq_cst 1809 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 1810 Scope); 1811 break; 1812 } 1813 return RValue::get(nullptr); 1814 } 1815 1816 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB; 1817 AcquireBB = createBasicBlock("acquire", CurFn); 1818 ReleaseBB = createBasicBlock("release", CurFn); 1819 AcqRelBB = createBasicBlock("acqrel", CurFn); 1820 SeqCstBB = createBasicBlock("seqcst", CurFn); 1821 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1822 1823 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1824 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB); 1825 1826 Builder.SetInsertPoint(AcquireBB); 1827 Builder.CreateFence(llvm::AtomicOrdering::Acquire, Scope); 1828 Builder.CreateBr(ContBB); 1829 SI->addCase(Builder.getInt32(1), AcquireBB); 1830 SI->addCase(Builder.getInt32(2), AcquireBB); 1831 1832 Builder.SetInsertPoint(ReleaseBB); 1833 Builder.CreateFence(llvm::AtomicOrdering::Release, Scope); 1834 Builder.CreateBr(ContBB); 1835 SI->addCase(Builder.getInt32(3), ReleaseBB); 1836 1837 Builder.SetInsertPoint(AcqRelBB); 1838 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, Scope); 1839 Builder.CreateBr(ContBB); 1840 SI->addCase(Builder.getInt32(4), AcqRelBB); 1841 1842 Builder.SetInsertPoint(SeqCstBB); 1843 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, Scope); 1844 Builder.CreateBr(ContBB); 1845 SI->addCase(Builder.getInt32(5), SeqCstBB); 1846 1847 Builder.SetInsertPoint(ContBB); 1848 return RValue::get(nullptr); 1849 } 1850 1851 // Library functions with special handling. 1852 case Builtin::BIsqrt: 1853 case Builtin::BIsqrtf: 1854 case Builtin::BIsqrtl: { 1855 // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only 1856 // in finite- or unsafe-math mode (the intrinsic has different semantics 1857 // for handling negative numbers compared to the library function, so 1858 // -fmath-errno=0 is not enough). 1859 if (!FD->hasAttr<ConstAttr>()) 1860 break; 1861 if (!(CGM.getCodeGenOpts().UnsafeFPMath || 1862 CGM.getCodeGenOpts().NoNaNsFPMath)) 1863 break; 1864 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 1865 llvm::Type *ArgType = Arg0->getType(); 1866 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType); 1867 return RValue::get(Builder.CreateCall(F, Arg0)); 1868 } 1869 1870 case Builtin::BI__builtin_pow: 1871 case Builtin::BI__builtin_powf: 1872 case Builtin::BI__builtin_powl: 1873 case Builtin::BIpow: 1874 case Builtin::BIpowf: 1875 case Builtin::BIpowl: { 1876 // Transform a call to pow* into a @llvm.pow.* intrinsic call. 1877 if (!FD->hasAttr<ConstAttr>()) 1878 break; 1879 Value *Base = EmitScalarExpr(E->getArg(0)); 1880 Value *Exponent = EmitScalarExpr(E->getArg(1)); 1881 llvm::Type *ArgType = Base->getType(); 1882 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 1883 return RValue::get(Builder.CreateCall(F, {Base, Exponent})); 1884 } 1885 1886 case Builtin::BIfma: 1887 case Builtin::BIfmaf: 1888 case Builtin::BIfmal: 1889 case Builtin::BI__builtin_fma: 1890 case Builtin::BI__builtin_fmaf: 1891 case Builtin::BI__builtin_fmal: { 1892 // Rewrite fma to intrinsic. 1893 Value *FirstArg = EmitScalarExpr(E->getArg(0)); 1894 llvm::Type *ArgType = FirstArg->getType(); 1895 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 1896 return RValue::get( 1897 Builder.CreateCall(F, {FirstArg, EmitScalarExpr(E->getArg(1)), 1898 EmitScalarExpr(E->getArg(2))})); 1899 } 1900 1901 case Builtin::BI__builtin_signbit: 1902 case Builtin::BI__builtin_signbitf: 1903 case Builtin::BI__builtin_signbitl: { 1904 return RValue::get( 1905 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))), 1906 ConvertType(E->getType()))); 1907 } 1908 case Builtin::BI__builtin_annotation: { 1909 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 1910 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 1911 AnnVal->getType()); 1912 1913 // Get the annotation string, go through casts. Sema requires this to be a 1914 // non-wide string literal, potentially casted, so the cast<> is safe. 1915 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 1916 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 1917 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 1918 } 1919 case Builtin::BI__builtin_addcb: 1920 case Builtin::BI__builtin_addcs: 1921 case Builtin::BI__builtin_addc: 1922 case Builtin::BI__builtin_addcl: 1923 case Builtin::BI__builtin_addcll: 1924 case Builtin::BI__builtin_subcb: 1925 case Builtin::BI__builtin_subcs: 1926 case Builtin::BI__builtin_subc: 1927 case Builtin::BI__builtin_subcl: 1928 case Builtin::BI__builtin_subcll: { 1929 1930 // We translate all of these builtins from expressions of the form: 1931 // int x = ..., y = ..., carryin = ..., carryout, result; 1932 // result = __builtin_addc(x, y, carryin, &carryout); 1933 // 1934 // to LLVM IR of the form: 1935 // 1936 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 1937 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 1938 // %carry1 = extractvalue {i32, i1} %tmp1, 1 1939 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 1940 // i32 %carryin) 1941 // %result = extractvalue {i32, i1} %tmp2, 0 1942 // %carry2 = extractvalue {i32, i1} %tmp2, 1 1943 // %tmp3 = or i1 %carry1, %carry2 1944 // %tmp4 = zext i1 %tmp3 to i32 1945 // store i32 %tmp4, i32* %carryout 1946 1947 // Scalarize our inputs. 1948 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 1949 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 1950 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 1951 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3)); 1952 1953 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 1954 llvm::Intrinsic::ID IntrinsicId; 1955 switch (BuiltinID) { 1956 default: llvm_unreachable("Unknown multiprecision builtin id."); 1957 case Builtin::BI__builtin_addcb: 1958 case Builtin::BI__builtin_addcs: 1959 case Builtin::BI__builtin_addc: 1960 case Builtin::BI__builtin_addcl: 1961 case Builtin::BI__builtin_addcll: 1962 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 1963 break; 1964 case Builtin::BI__builtin_subcb: 1965 case Builtin::BI__builtin_subcs: 1966 case Builtin::BI__builtin_subc: 1967 case Builtin::BI__builtin_subcl: 1968 case Builtin::BI__builtin_subcll: 1969 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 1970 break; 1971 } 1972 1973 // Construct our resulting LLVM IR expression. 1974 llvm::Value *Carry1; 1975 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 1976 X, Y, Carry1); 1977 llvm::Value *Carry2; 1978 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 1979 Sum1, Carryin, Carry2); 1980 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 1981 X->getType()); 1982 Builder.CreateStore(CarryOut, CarryOutPtr); 1983 return RValue::get(Sum2); 1984 } 1985 1986 case Builtin::BI__builtin_add_overflow: 1987 case Builtin::BI__builtin_sub_overflow: 1988 case Builtin::BI__builtin_mul_overflow: { 1989 const clang::Expr *LeftArg = E->getArg(0); 1990 const clang::Expr *RightArg = E->getArg(1); 1991 const clang::Expr *ResultArg = E->getArg(2); 1992 1993 clang::QualType ResultQTy = 1994 ResultArg->getType()->castAs<PointerType>()->getPointeeType(); 1995 1996 WidthAndSignedness LeftInfo = 1997 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType()); 1998 WidthAndSignedness RightInfo = 1999 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType()); 2000 WidthAndSignedness ResultInfo = 2001 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy); 2002 WidthAndSignedness EncompassingInfo = 2003 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo}); 2004 2005 llvm::Type *EncompassingLLVMTy = 2006 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width); 2007 2008 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy); 2009 2010 llvm::Intrinsic::ID IntrinsicId; 2011 switch (BuiltinID) { 2012 default: 2013 llvm_unreachable("Unknown overflow builtin id."); 2014 case Builtin::BI__builtin_add_overflow: 2015 IntrinsicId = EncompassingInfo.Signed 2016 ? llvm::Intrinsic::sadd_with_overflow 2017 : llvm::Intrinsic::uadd_with_overflow; 2018 break; 2019 case Builtin::BI__builtin_sub_overflow: 2020 IntrinsicId = EncompassingInfo.Signed 2021 ? llvm::Intrinsic::ssub_with_overflow 2022 : llvm::Intrinsic::usub_with_overflow; 2023 break; 2024 case Builtin::BI__builtin_mul_overflow: 2025 IntrinsicId = EncompassingInfo.Signed 2026 ? llvm::Intrinsic::smul_with_overflow 2027 : llvm::Intrinsic::umul_with_overflow; 2028 break; 2029 } 2030 2031 llvm::Value *Left = EmitScalarExpr(LeftArg); 2032 llvm::Value *Right = EmitScalarExpr(RightArg); 2033 Address ResultPtr = EmitPointerWithAlignment(ResultArg); 2034 2035 // Extend each operand to the encompassing type. 2036 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed); 2037 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed); 2038 2039 // Perform the operation on the extended values. 2040 llvm::Value *Overflow, *Result; 2041 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow); 2042 2043 if (EncompassingInfo.Width > ResultInfo.Width) { 2044 // The encompassing type is wider than the result type, so we need to 2045 // truncate it. 2046 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy); 2047 2048 // To see if the truncation caused an overflow, we will extend 2049 // the result and then compare it to the original result. 2050 llvm::Value *ResultTruncExt = Builder.CreateIntCast( 2051 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed); 2052 llvm::Value *TruncationOverflow = 2053 Builder.CreateICmpNE(Result, ResultTruncExt); 2054 2055 Overflow = Builder.CreateOr(Overflow, TruncationOverflow); 2056 Result = ResultTrunc; 2057 } 2058 2059 // Finally, store the result using the pointer. 2060 bool isVolatile = 2061 ResultArg->getType()->getPointeeType().isVolatileQualified(); 2062 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile); 2063 2064 return RValue::get(Overflow); 2065 } 2066 2067 case Builtin::BI__builtin_uadd_overflow: 2068 case Builtin::BI__builtin_uaddl_overflow: 2069 case Builtin::BI__builtin_uaddll_overflow: 2070 case Builtin::BI__builtin_usub_overflow: 2071 case Builtin::BI__builtin_usubl_overflow: 2072 case Builtin::BI__builtin_usubll_overflow: 2073 case Builtin::BI__builtin_umul_overflow: 2074 case Builtin::BI__builtin_umull_overflow: 2075 case Builtin::BI__builtin_umulll_overflow: 2076 case Builtin::BI__builtin_sadd_overflow: 2077 case Builtin::BI__builtin_saddl_overflow: 2078 case Builtin::BI__builtin_saddll_overflow: 2079 case Builtin::BI__builtin_ssub_overflow: 2080 case Builtin::BI__builtin_ssubl_overflow: 2081 case Builtin::BI__builtin_ssubll_overflow: 2082 case Builtin::BI__builtin_smul_overflow: 2083 case Builtin::BI__builtin_smull_overflow: 2084 case Builtin::BI__builtin_smulll_overflow: { 2085 2086 // We translate all of these builtins directly to the relevant llvm IR node. 2087 2088 // Scalarize our inputs. 2089 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2090 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2091 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2)); 2092 2093 // Decide which of the overflow intrinsics we are lowering to: 2094 llvm::Intrinsic::ID IntrinsicId; 2095 switch (BuiltinID) { 2096 default: llvm_unreachable("Unknown overflow builtin id."); 2097 case Builtin::BI__builtin_uadd_overflow: 2098 case Builtin::BI__builtin_uaddl_overflow: 2099 case Builtin::BI__builtin_uaddll_overflow: 2100 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2101 break; 2102 case Builtin::BI__builtin_usub_overflow: 2103 case Builtin::BI__builtin_usubl_overflow: 2104 case Builtin::BI__builtin_usubll_overflow: 2105 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2106 break; 2107 case Builtin::BI__builtin_umul_overflow: 2108 case Builtin::BI__builtin_umull_overflow: 2109 case Builtin::BI__builtin_umulll_overflow: 2110 IntrinsicId = llvm::Intrinsic::umul_with_overflow; 2111 break; 2112 case Builtin::BI__builtin_sadd_overflow: 2113 case Builtin::BI__builtin_saddl_overflow: 2114 case Builtin::BI__builtin_saddll_overflow: 2115 IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 2116 break; 2117 case Builtin::BI__builtin_ssub_overflow: 2118 case Builtin::BI__builtin_ssubl_overflow: 2119 case Builtin::BI__builtin_ssubll_overflow: 2120 IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 2121 break; 2122 case Builtin::BI__builtin_smul_overflow: 2123 case Builtin::BI__builtin_smull_overflow: 2124 case Builtin::BI__builtin_smulll_overflow: 2125 IntrinsicId = llvm::Intrinsic::smul_with_overflow; 2126 break; 2127 } 2128 2129 2130 llvm::Value *Carry; 2131 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 2132 Builder.CreateStore(Sum, SumOutPtr); 2133 2134 return RValue::get(Carry); 2135 } 2136 case Builtin::BI__builtin_addressof: 2137 return RValue::get(EmitLValue(E->getArg(0)).getPointer()); 2138 case Builtin::BI__builtin_operator_new: 2139 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2140 E->getArg(0), false); 2141 case Builtin::BI__builtin_operator_delete: 2142 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2143 E->getArg(0), true); 2144 case Builtin::BI__noop: 2145 // __noop always evaluates to an integer literal zero. 2146 return RValue::get(ConstantInt::get(IntTy, 0)); 2147 case Builtin::BI__builtin_call_with_static_chain: { 2148 const CallExpr *Call = cast<CallExpr>(E->getArg(0)); 2149 const Expr *Chain = E->getArg(1); 2150 return EmitCall(Call->getCallee()->getType(), 2151 EmitCallee(Call->getCallee()), Call, ReturnValue, 2152 EmitScalarExpr(Chain)); 2153 } 2154 case Builtin::BI_InterlockedExchange8: 2155 case Builtin::BI_InterlockedExchange16: 2156 case Builtin::BI_InterlockedExchange: 2157 case Builtin::BI_InterlockedExchangePointer: 2158 return RValue::get( 2159 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E)); 2160 case Builtin::BI_InterlockedCompareExchangePointer: { 2161 llvm::Type *RTy; 2162 llvm::IntegerType *IntType = 2163 IntegerType::get(getLLVMContext(), 2164 getContext().getTypeSize(E->getType())); 2165 llvm::Type *IntPtrType = IntType->getPointerTo(); 2166 2167 llvm::Value *Destination = 2168 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType); 2169 2170 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1)); 2171 RTy = Exchange->getType(); 2172 Exchange = Builder.CreatePtrToInt(Exchange, IntType); 2173 2174 llvm::Value *Comparand = 2175 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType); 2176 2177 auto Result = 2178 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange, 2179 AtomicOrdering::SequentiallyConsistent, 2180 AtomicOrdering::SequentiallyConsistent); 2181 Result->setVolatile(true); 2182 2183 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result, 2184 0), 2185 RTy)); 2186 } 2187 case Builtin::BI_InterlockedCompareExchange8: 2188 case Builtin::BI_InterlockedCompareExchange16: 2189 case Builtin::BI_InterlockedCompareExchange: 2190 case Builtin::BI_InterlockedCompareExchange64: { 2191 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg( 2192 EmitScalarExpr(E->getArg(0)), 2193 EmitScalarExpr(E->getArg(2)), 2194 EmitScalarExpr(E->getArg(1)), 2195 AtomicOrdering::SequentiallyConsistent, 2196 AtomicOrdering::SequentiallyConsistent); 2197 CXI->setVolatile(true); 2198 return RValue::get(Builder.CreateExtractValue(CXI, 0)); 2199 } 2200 case Builtin::BI_InterlockedIncrement16: 2201 case Builtin::BI_InterlockedIncrement: 2202 return RValue::get( 2203 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E)); 2204 case Builtin::BI_InterlockedDecrement16: 2205 case Builtin::BI_InterlockedDecrement: 2206 return RValue::get( 2207 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E)); 2208 case Builtin::BI_InterlockedAnd8: 2209 case Builtin::BI_InterlockedAnd16: 2210 case Builtin::BI_InterlockedAnd: 2211 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E)); 2212 case Builtin::BI_InterlockedExchangeAdd8: 2213 case Builtin::BI_InterlockedExchangeAdd16: 2214 case Builtin::BI_InterlockedExchangeAdd: 2215 return RValue::get( 2216 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E)); 2217 case Builtin::BI_InterlockedExchangeSub8: 2218 case Builtin::BI_InterlockedExchangeSub16: 2219 case Builtin::BI_InterlockedExchangeSub: 2220 return RValue::get( 2221 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E)); 2222 case Builtin::BI_InterlockedOr8: 2223 case Builtin::BI_InterlockedOr16: 2224 case Builtin::BI_InterlockedOr: 2225 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E)); 2226 case Builtin::BI_InterlockedXor8: 2227 case Builtin::BI_InterlockedXor16: 2228 case Builtin::BI_InterlockedXor: 2229 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E)); 2230 case Builtin::BI__readfsdword: { 2231 llvm::Type *IntTy = ConvertType(E->getType()); 2232 Value *IntToPtr = 2233 Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 2234 llvm::PointerType::get(IntTy, 257)); 2235 LoadInst *Load = Builder.CreateAlignedLoad( 2236 IntTy, IntToPtr, getContext().getTypeAlignInChars(E->getType())); 2237 Load->setVolatile(true); 2238 return RValue::get(Load); 2239 } 2240 2241 case Builtin::BI__exception_code: 2242 case Builtin::BI_exception_code: 2243 return RValue::get(EmitSEHExceptionCode()); 2244 case Builtin::BI__exception_info: 2245 case Builtin::BI_exception_info: 2246 return RValue::get(EmitSEHExceptionInfo()); 2247 case Builtin::BI__abnormal_termination: 2248 case Builtin::BI_abnormal_termination: 2249 return RValue::get(EmitSEHAbnormalTermination()); 2250 case Builtin::BI_setjmpex: { 2251 if (getTarget().getTriple().isOSMSVCRT()) { 2252 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2253 llvm::AttributeSet ReturnsTwiceAttr = 2254 AttributeSet::get(getLLVMContext(), llvm::AttributeSet::FunctionIndex, 2255 llvm::Attribute::ReturnsTwice); 2256 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction( 2257 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2258 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true); 2259 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2260 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2261 llvm::Value *FrameAddr = 2262 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2263 ConstantInt::get(Int32Ty, 0)); 2264 llvm::Value *Args[] = {Buf, FrameAddr}; 2265 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args); 2266 CS.setAttributes(ReturnsTwiceAttr); 2267 return RValue::get(CS.getInstruction()); 2268 } 2269 break; 2270 } 2271 case Builtin::BI_setjmp: { 2272 if (getTarget().getTriple().isOSMSVCRT()) { 2273 llvm::AttributeSet ReturnsTwiceAttr = 2274 AttributeSet::get(getLLVMContext(), llvm::AttributeSet::FunctionIndex, 2275 llvm::Attribute::ReturnsTwice); 2276 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2277 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2278 llvm::CallSite CS; 2279 if (getTarget().getTriple().getArch() == llvm::Triple::x86) { 2280 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy}; 2281 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction( 2282 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true), 2283 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true); 2284 llvm::Value *Count = ConstantInt::get(IntTy, 0); 2285 llvm::Value *Args[] = {Buf, Count}; 2286 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args); 2287 } else { 2288 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2289 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( 2290 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2291 "_setjmp", ReturnsTwiceAttr, /*Local=*/true); 2292 llvm::Value *FrameAddr = 2293 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2294 ConstantInt::get(Int32Ty, 0)); 2295 llvm::Value *Args[] = {Buf, FrameAddr}; 2296 CS = EmitRuntimeCallOrInvoke(SetJmp, Args); 2297 } 2298 CS.setAttributes(ReturnsTwiceAttr); 2299 return RValue::get(CS.getInstruction()); 2300 } 2301 break; 2302 } 2303 2304 case Builtin::BI__GetExceptionInfo: { 2305 if (llvm::GlobalVariable *GV = 2306 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType())) 2307 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy)); 2308 break; 2309 } 2310 2311 case Builtin::BI__fastfail: { 2312 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E)); 2313 break; 2314 } 2315 2316 case Builtin::BI__builtin_coro_size: { 2317 auto & Context = getContext(); 2318 auto SizeTy = Context.getSizeType(); 2319 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy)); 2320 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T); 2321 return RValue::get(Builder.CreateCall(F)); 2322 } 2323 2324 case Builtin::BI__builtin_coro_id: 2325 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id); 2326 case Builtin::BI__builtin_coro_promise: 2327 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise); 2328 case Builtin::BI__builtin_coro_resume: 2329 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume); 2330 case Builtin::BI__builtin_coro_frame: 2331 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame); 2332 case Builtin::BI__builtin_coro_free: 2333 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free); 2334 case Builtin::BI__builtin_coro_destroy: 2335 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy); 2336 case Builtin::BI__builtin_coro_done: 2337 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done); 2338 case Builtin::BI__builtin_coro_alloc: 2339 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc); 2340 case Builtin::BI__builtin_coro_begin: 2341 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin); 2342 case Builtin::BI__builtin_coro_end: 2343 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end); 2344 case Builtin::BI__builtin_coro_suspend: 2345 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend); 2346 case Builtin::BI__builtin_coro_param: 2347 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param); 2348 2349 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions 2350 case Builtin::BIread_pipe: 2351 case Builtin::BIwrite_pipe: { 2352 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2353 *Arg1 = EmitScalarExpr(E->getArg(1)); 2354 CGOpenCLRuntime OpenCLRT(CGM); 2355 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2356 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2357 2358 // Type of the generic packet parameter. 2359 unsigned GenericAS = 2360 getContext().getTargetAddressSpace(LangAS::opencl_generic); 2361 llvm::Type *I8PTy = llvm::PointerType::get( 2362 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS); 2363 2364 // Testing which overloaded version we should generate the call for. 2365 if (2U == E->getNumArgs()) { 2366 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2" 2367 : "__write_pipe_2"; 2368 // Creating a generic function type to be able to call with any builtin or 2369 // user defined type. 2370 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty}; 2371 llvm::FunctionType *FTy = llvm::FunctionType::get( 2372 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2373 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy); 2374 return RValue::get( 2375 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2376 {Arg0, BCast, PacketSize, PacketAlign})); 2377 } else { 2378 assert(4 == E->getNumArgs() && 2379 "Illegal number of parameters to pipe function"); 2380 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4" 2381 : "__write_pipe_4"; 2382 2383 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy, 2384 Int32Ty, Int32Ty}; 2385 Value *Arg2 = EmitScalarExpr(E->getArg(2)), 2386 *Arg3 = EmitScalarExpr(E->getArg(3)); 2387 llvm::FunctionType *FTy = llvm::FunctionType::get( 2388 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2389 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy); 2390 // We know the third argument is an integer type, but we may need to cast 2391 // it to i32. 2392 if (Arg2->getType() != Int32Ty) 2393 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty); 2394 return RValue::get(Builder.CreateCall( 2395 CGM.CreateRuntimeFunction(FTy, Name), 2396 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign})); 2397 } 2398 } 2399 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write 2400 // functions 2401 case Builtin::BIreserve_read_pipe: 2402 case Builtin::BIreserve_write_pipe: 2403 case Builtin::BIwork_group_reserve_read_pipe: 2404 case Builtin::BIwork_group_reserve_write_pipe: 2405 case Builtin::BIsub_group_reserve_read_pipe: 2406 case Builtin::BIsub_group_reserve_write_pipe: { 2407 // Composing the mangled name for the function. 2408 const char *Name; 2409 if (BuiltinID == Builtin::BIreserve_read_pipe) 2410 Name = "__reserve_read_pipe"; 2411 else if (BuiltinID == Builtin::BIreserve_write_pipe) 2412 Name = "__reserve_write_pipe"; 2413 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe) 2414 Name = "__work_group_reserve_read_pipe"; 2415 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe) 2416 Name = "__work_group_reserve_write_pipe"; 2417 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe) 2418 Name = "__sub_group_reserve_read_pipe"; 2419 else 2420 Name = "__sub_group_reserve_write_pipe"; 2421 2422 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2423 *Arg1 = EmitScalarExpr(E->getArg(1)); 2424 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy); 2425 CGOpenCLRuntime OpenCLRT(CGM); 2426 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2427 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2428 2429 // Building the generic function prototype. 2430 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty}; 2431 llvm::FunctionType *FTy = llvm::FunctionType::get( 2432 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2433 // We know the second argument is an integer type, but we may need to cast 2434 // it to i32. 2435 if (Arg1->getType() != Int32Ty) 2436 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty); 2437 return RValue::get( 2438 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2439 {Arg0, Arg1, PacketSize, PacketAlign})); 2440 } 2441 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write 2442 // functions 2443 case Builtin::BIcommit_read_pipe: 2444 case Builtin::BIcommit_write_pipe: 2445 case Builtin::BIwork_group_commit_read_pipe: 2446 case Builtin::BIwork_group_commit_write_pipe: 2447 case Builtin::BIsub_group_commit_read_pipe: 2448 case Builtin::BIsub_group_commit_write_pipe: { 2449 const char *Name; 2450 if (BuiltinID == Builtin::BIcommit_read_pipe) 2451 Name = "__commit_read_pipe"; 2452 else if (BuiltinID == Builtin::BIcommit_write_pipe) 2453 Name = "__commit_write_pipe"; 2454 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe) 2455 Name = "__work_group_commit_read_pipe"; 2456 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe) 2457 Name = "__work_group_commit_write_pipe"; 2458 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe) 2459 Name = "__sub_group_commit_read_pipe"; 2460 else 2461 Name = "__sub_group_commit_write_pipe"; 2462 2463 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2464 *Arg1 = EmitScalarExpr(E->getArg(1)); 2465 CGOpenCLRuntime OpenCLRT(CGM); 2466 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2467 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2468 2469 // Building the generic function prototype. 2470 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty}; 2471 llvm::FunctionType *FTy = 2472 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 2473 llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2474 2475 return RValue::get( 2476 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2477 {Arg0, Arg1, PacketSize, PacketAlign})); 2478 } 2479 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions 2480 case Builtin::BIget_pipe_num_packets: 2481 case Builtin::BIget_pipe_max_packets: { 2482 const char *Name; 2483 if (BuiltinID == Builtin::BIget_pipe_num_packets) 2484 Name = "__get_pipe_num_packets"; 2485 else 2486 Name = "__get_pipe_max_packets"; 2487 2488 // Building the generic function prototype. 2489 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 2490 CGOpenCLRuntime OpenCLRT(CGM); 2491 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2492 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2493 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty}; 2494 llvm::FunctionType *FTy = llvm::FunctionType::get( 2495 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2496 2497 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2498 {Arg0, PacketSize, PacketAlign})); 2499 } 2500 2501 // OpenCL v2.0 s6.13.9 - Address space qualifier functions. 2502 case Builtin::BIto_global: 2503 case Builtin::BIto_local: 2504 case Builtin::BIto_private: { 2505 auto Arg0 = EmitScalarExpr(E->getArg(0)); 2506 auto NewArgT = llvm::PointerType::get(Int8Ty, 2507 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2508 auto NewRetT = llvm::PointerType::get(Int8Ty, 2509 CGM.getContext().getTargetAddressSpace( 2510 E->getType()->getPointeeType().getAddressSpace())); 2511 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false); 2512 llvm::Value *NewArg; 2513 if (Arg0->getType()->getPointerAddressSpace() != 2514 NewArgT->getPointerAddressSpace()) 2515 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT); 2516 else 2517 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT); 2518 auto NewName = std::string("__") + E->getDirectCallee()->getName().str(); 2519 auto NewCall = 2520 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg}); 2521 return RValue::get(Builder.CreateBitOrPointerCast(NewCall, 2522 ConvertType(E->getType()))); 2523 } 2524 2525 // OpenCL v2.0, s6.13.17 - Enqueue kernel function. 2526 // It contains four different overload formats specified in Table 6.13.17.1. 2527 case Builtin::BIenqueue_kernel: { 2528 StringRef Name; // Generated function call name 2529 unsigned NumArgs = E->getNumArgs(); 2530 2531 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy); 2532 llvm::Type *RangeTy = ConvertType(getContext().OCLNDRangeTy); 2533 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2534 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2535 2536 llvm::Value *Queue = EmitScalarExpr(E->getArg(0)); 2537 llvm::Value *Flags = EmitScalarExpr(E->getArg(1)); 2538 llvm::Value *Range = EmitScalarExpr(E->getArg(2)); 2539 2540 if (NumArgs == 4) { 2541 // The most basic form of the call with parameters: 2542 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void) 2543 Name = "__enqueue_kernel_basic"; 2544 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy}; 2545 llvm::FunctionType *FTy = llvm::FunctionType::get( 2546 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys, 4), false); 2547 2548 llvm::Value *Block = Builder.CreatePointerCast( 2549 EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy); 2550 2551 return RValue::get(Builder.CreateCall( 2552 CGM.CreateRuntimeFunction(FTy, Name), {Queue, Flags, Range, Block})); 2553 } 2554 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature"); 2555 2556 // Could have events and/or vaargs. 2557 if (E->getArg(3)->getType()->isBlockPointerType()) { 2558 // No events passed, but has variadic arguments. 2559 Name = "__enqueue_kernel_vaargs"; 2560 llvm::Value *Block = Builder.CreatePointerCast( 2561 EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy); 2562 // Create a vector of the arguments, as well as a constant value to 2563 // express to the runtime the number of variadic arguments. 2564 std::vector<llvm::Value *> Args = {Queue, Flags, Range, Block, 2565 ConstantInt::get(IntTy, NumArgs - 4)}; 2566 std::vector<llvm::Type *> ArgTys = {QueueTy, IntTy, RangeTy, 2567 GenericVoidPtrTy, IntTy}; 2568 2569 // Each of the following arguments specifies the size of the corresponding 2570 // argument passed to the enqueued block. 2571 for (unsigned I = 4/*Position of the first size arg*/; I < NumArgs; ++I) 2572 Args.push_back( 2573 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy)); 2574 2575 llvm::FunctionType *FTy = llvm::FunctionType::get( 2576 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), true); 2577 return RValue::get( 2578 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2579 llvm::ArrayRef<llvm::Value *>(Args))); 2580 } 2581 // Any calls now have event arguments passed. 2582 if (NumArgs >= 7) { 2583 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy); 2584 llvm::Type *EventPtrTy = EventTy->getPointerTo( 2585 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2586 2587 llvm::Value *NumEvents = 2588 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty); 2589 llvm::Value *EventList = 2590 E->getArg(4)->getType()->isArrayType() 2591 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer() 2592 : EmitScalarExpr(E->getArg(4)); 2593 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5)); 2594 // Convert to generic address space. 2595 EventList = Builder.CreatePointerCast(EventList, EventPtrTy); 2596 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy); 2597 llvm::Value *Block = Builder.CreatePointerCast( 2598 EmitScalarExpr(E->getArg(6)), GenericVoidPtrTy); 2599 2600 std::vector<llvm::Type *> ArgTys = { 2601 QueueTy, Int32Ty, RangeTy, Int32Ty, 2602 EventPtrTy, EventPtrTy, GenericVoidPtrTy}; 2603 2604 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents, 2605 EventList, ClkEvent, Block}; 2606 2607 if (NumArgs == 7) { 2608 // Has events but no variadics. 2609 Name = "__enqueue_kernel_basic_events"; 2610 llvm::FunctionType *FTy = llvm::FunctionType::get( 2611 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2612 return RValue::get( 2613 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2614 llvm::ArrayRef<llvm::Value *>(Args))); 2615 } 2616 // Has event info and variadics 2617 // Pass the number of variadics to the runtime function too. 2618 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7)); 2619 ArgTys.push_back(Int32Ty); 2620 Name = "__enqueue_kernel_events_vaargs"; 2621 2622 // Each of the following arguments specifies the size of the corresponding 2623 // argument passed to the enqueued block. 2624 for (unsigned I = 7/*Position of the first size arg*/; I < NumArgs; ++I) 2625 Args.push_back( 2626 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy)); 2627 2628 llvm::FunctionType *FTy = llvm::FunctionType::get( 2629 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), true); 2630 return RValue::get( 2631 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2632 llvm::ArrayRef<llvm::Value *>(Args))); 2633 } 2634 } 2635 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block 2636 // parameter. 2637 case Builtin::BIget_kernel_work_group_size: { 2638 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2639 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2640 Value *Arg = EmitScalarExpr(E->getArg(0)); 2641 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy); 2642 return RValue::get(Builder.CreateCall( 2643 CGM.CreateRuntimeFunction( 2644 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false), 2645 "__get_kernel_work_group_size_impl"), 2646 Arg)); 2647 } 2648 case Builtin::BIget_kernel_preferred_work_group_size_multiple: { 2649 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2650 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2651 Value *Arg = EmitScalarExpr(E->getArg(0)); 2652 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy); 2653 return RValue::get(Builder.CreateCall( 2654 CGM.CreateRuntimeFunction( 2655 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false), 2656 "__get_kernel_preferred_work_group_multiple_impl"), 2657 Arg)); 2658 } 2659 case Builtin::BIprintf: 2660 if (getTarget().getTriple().isNVPTX()) 2661 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue); 2662 break; 2663 case Builtin::BI__builtin_canonicalize: 2664 case Builtin::BI__builtin_canonicalizef: 2665 case Builtin::BI__builtin_canonicalizel: 2666 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize)); 2667 2668 case Builtin::BI__builtin_thread_pointer: { 2669 if (!getContext().getTargetInfo().isTLSSupported()) 2670 CGM.ErrorUnsupported(E, "__builtin_thread_pointer"); 2671 // Fall through - it's already mapped to the intrinsic by GCCBuiltin. 2672 break; 2673 } 2674 case Builtin::BI__builtin_os_log_format: { 2675 assert(E->getNumArgs() >= 2 && 2676 "__builtin_os_log_format takes at least 2 arguments"); 2677 analyze_os_log::OSLogBufferLayout Layout; 2678 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); 2679 Address BufAddr = EmitPointerWithAlignment(E->getArg(0)); 2680 // Ignore argument 1, the format string. It is not currently used. 2681 CharUnits Offset; 2682 Builder.CreateStore( 2683 Builder.getInt8(Layout.getSummaryByte()), 2684 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary")); 2685 Builder.CreateStore( 2686 Builder.getInt8(Layout.getNumArgsByte()), 2687 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs")); 2688 2689 llvm::SmallVector<llvm::Value *, 4> RetainableOperands; 2690 for (const auto &Item : Layout.Items) { 2691 Builder.CreateStore( 2692 Builder.getInt8(Item.getDescriptorByte()), 2693 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor")); 2694 Builder.CreateStore( 2695 Builder.getInt8(Item.getSizeByte()), 2696 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize")); 2697 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset); 2698 if (const Expr *TheExpr = Item.getExpr()) { 2699 Addr = Builder.CreateElementBitCast( 2700 Addr, ConvertTypeForMem(TheExpr->getType())); 2701 // Check if this is a retainable type. 2702 if (TheExpr->getType()->isObjCRetainableType()) { 2703 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar && 2704 "Only scalar can be a ObjC retainable type"); 2705 llvm::Value *SV = EmitScalarExpr(TheExpr, /*Ignore*/ false); 2706 RValue RV = RValue::get(SV); 2707 LValue LV = MakeAddrLValue(Addr, TheExpr->getType()); 2708 EmitStoreThroughLValue(RV, LV); 2709 // Check if the object is constant, if not, save it in 2710 // RetainableOperands. 2711 if (!isa<Constant>(SV)) 2712 RetainableOperands.push_back(SV); 2713 } else { 2714 EmitAnyExprToMem(TheExpr, Addr, Qualifiers(), /*isInit*/ true); 2715 } 2716 } else { 2717 Addr = Builder.CreateElementBitCast(Addr, Int32Ty); 2718 Builder.CreateStore( 2719 Builder.getInt32(Item.getConstValue().getQuantity()), Addr); 2720 } 2721 Offset += Item.size(); 2722 } 2723 2724 // Push a clang.arc.use cleanup for each object in RetainableOperands. The 2725 // cleanup will cause the use to appear after the final log call, keeping 2726 // the object valid while it’s held in the log buffer. Note that if there’s 2727 // a release cleanup on the object, it will already be active; since 2728 // cleanups are emitted in reverse order, the use will occur before the 2729 // object is released. 2730 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount && 2731 CGM.getCodeGenOpts().OptimizationLevel != 0) 2732 for (llvm::Value *object : RetainableOperands) 2733 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), object); 2734 2735 return RValue::get(BufAddr.getPointer()); 2736 } 2737 2738 case Builtin::BI__builtin_os_log_format_buffer_size: { 2739 analyze_os_log::OSLogBufferLayout Layout; 2740 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); 2741 return RValue::get(ConstantInt::get(ConvertType(E->getType()), 2742 Layout.size().getQuantity())); 2743 } 2744 } 2745 2746 // If this is an alias for a lib function (e.g. __builtin_sin), emit 2747 // the call using the normal call path, but using the unmangled 2748 // version of the function name. 2749 if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 2750 return emitLibraryCall(*this, FD, E, 2751 CGM.getBuiltinLibFunction(FD, BuiltinID)); 2752 2753 // If this is a predefined lib function (e.g. malloc), emit the call 2754 // using exactly the normal call path. 2755 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 2756 return emitLibraryCall(*this, FD, E, 2757 cast<llvm::Constant>(EmitScalarExpr(E->getCallee()))); 2758 2759 // Check that a call to a target specific builtin has the correct target 2760 // features. 2761 // This is down here to avoid non-target specific builtins, however, if 2762 // generic builtins start to require generic target features then we 2763 // can move this up to the beginning of the function. 2764 checkTargetFeatures(E, FD); 2765 2766 // See if we have a target specific intrinsic. 2767 const char *Name = getContext().BuiltinInfo.getName(BuiltinID); 2768 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 2769 StringRef Prefix = 2770 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); 2771 if (!Prefix.empty()) { 2772 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name); 2773 // NOTE we dont need to perform a compatibility flag check here since the 2774 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the 2775 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. 2776 if (IntrinsicID == Intrinsic::not_intrinsic) 2777 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name); 2778 } 2779 2780 if (IntrinsicID != Intrinsic::not_intrinsic) { 2781 SmallVector<Value*, 16> Args; 2782 2783 // Find out if any arguments are required to be integer constant 2784 // expressions. 2785 unsigned ICEArguments = 0; 2786 ASTContext::GetBuiltinTypeError Error; 2787 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 2788 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 2789 2790 Function *F = CGM.getIntrinsic(IntrinsicID); 2791 llvm::FunctionType *FTy = F->getFunctionType(); 2792 2793 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 2794 Value *ArgValue; 2795 // If this is a normal argument, just emit it as a scalar. 2796 if ((ICEArguments & (1 << i)) == 0) { 2797 ArgValue = EmitScalarExpr(E->getArg(i)); 2798 } else { 2799 // If this is required to be a constant, constant fold it so that we 2800 // know that the generated intrinsic gets a ConstantInt. 2801 llvm::APSInt Result; 2802 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 2803 assert(IsConst && "Constant arg isn't actually constant?"); 2804 (void)IsConst; 2805 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 2806 } 2807 2808 // If the intrinsic arg type is different from the builtin arg type 2809 // we need to do a bit cast. 2810 llvm::Type *PTy = FTy->getParamType(i); 2811 if (PTy != ArgValue->getType()) { 2812 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 2813 "Must be able to losslessly bit cast to param"); 2814 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 2815 } 2816 2817 Args.push_back(ArgValue); 2818 } 2819 2820 Value *V = Builder.CreateCall(F, Args); 2821 QualType BuiltinRetType = E->getType(); 2822 2823 llvm::Type *RetTy = VoidTy; 2824 if (!BuiltinRetType->isVoidType()) 2825 RetTy = ConvertType(BuiltinRetType); 2826 2827 if (RetTy != V->getType()) { 2828 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 2829 "Must be able to losslessly bit cast result type"); 2830 V = Builder.CreateBitCast(V, RetTy); 2831 } 2832 2833 return RValue::get(V); 2834 } 2835 2836 // See if we have a target specific builtin that needs to be lowered. 2837 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 2838 return RValue::get(V); 2839 2840 ErrorUnsupported(E, "builtin function"); 2841 2842 // Unknown builtin, for now just dump it out and return undef. 2843 return GetUndefRValue(E->getType()); 2844 } 2845 2846 static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, 2847 unsigned BuiltinID, const CallExpr *E, 2848 llvm::Triple::ArchType Arch) { 2849 switch (Arch) { 2850 case llvm::Triple::arm: 2851 case llvm::Triple::armeb: 2852 case llvm::Triple::thumb: 2853 case llvm::Triple::thumbeb: 2854 return CGF->EmitARMBuiltinExpr(BuiltinID, E); 2855 case llvm::Triple::aarch64: 2856 case llvm::Triple::aarch64_be: 2857 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E); 2858 case llvm::Triple::x86: 2859 case llvm::Triple::x86_64: 2860 return CGF->EmitX86BuiltinExpr(BuiltinID, E); 2861 case llvm::Triple::ppc: 2862 case llvm::Triple::ppc64: 2863 case llvm::Triple::ppc64le: 2864 return CGF->EmitPPCBuiltinExpr(BuiltinID, E); 2865 case llvm::Triple::r600: 2866 case llvm::Triple::amdgcn: 2867 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E); 2868 case llvm::Triple::systemz: 2869 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E); 2870 case llvm::Triple::nvptx: 2871 case llvm::Triple::nvptx64: 2872 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E); 2873 case llvm::Triple::wasm32: 2874 case llvm::Triple::wasm64: 2875 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E); 2876 default: 2877 return nullptr; 2878 } 2879 } 2880 2881 Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 2882 const CallExpr *E) { 2883 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { 2884 assert(getContext().getAuxTargetInfo() && "Missing aux target info"); 2885 return EmitTargetArchBuiltinExpr( 2886 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E, 2887 getContext().getAuxTargetInfo()->getTriple().getArch()); 2888 } 2889 2890 return EmitTargetArchBuiltinExpr(this, BuiltinID, E, 2891 getTarget().getTriple().getArch()); 2892 } 2893 2894 static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 2895 NeonTypeFlags TypeFlags, 2896 bool V1Ty=false) { 2897 int IsQuad = TypeFlags.isQuad(); 2898 switch (TypeFlags.getEltType()) { 2899 case NeonTypeFlags::Int8: 2900 case NeonTypeFlags::Poly8: 2901 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); 2902 case NeonTypeFlags::Int16: 2903 case NeonTypeFlags::Poly16: 2904 case NeonTypeFlags::Float16: 2905 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); 2906 case NeonTypeFlags::Int32: 2907 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); 2908 case NeonTypeFlags::Int64: 2909 case NeonTypeFlags::Poly64: 2910 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad)); 2911 case NeonTypeFlags::Poly128: 2912 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm. 2913 // There is a lot of i128 and f128 API missing. 2914 // so we use v16i8 to represent poly128 and get pattern matched. 2915 return llvm::VectorType::get(CGF->Int8Ty, 16); 2916 case NeonTypeFlags::Float32: 2917 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); 2918 case NeonTypeFlags::Float64: 2919 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad)); 2920 } 2921 llvm_unreachable("Unknown vector element type!"); 2922 } 2923 2924 static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF, 2925 NeonTypeFlags IntTypeFlags) { 2926 int IsQuad = IntTypeFlags.isQuad(); 2927 switch (IntTypeFlags.getEltType()) { 2928 case NeonTypeFlags::Int32: 2929 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad)); 2930 case NeonTypeFlags::Int64: 2931 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad)); 2932 default: 2933 llvm_unreachable("Type can't be converted to floating-point!"); 2934 } 2935 } 2936 2937 Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 2938 unsigned nElts = V->getType()->getVectorNumElements(); 2939 Value* SV = llvm::ConstantVector::getSplat(nElts, C); 2940 return Builder.CreateShuffleVector(V, V, SV, "lane"); 2941 } 2942 2943 Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 2944 const char *name, 2945 unsigned shift, bool rightshift) { 2946 unsigned j = 0; 2947 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 2948 ai != ae; ++ai, ++j) 2949 if (shift > 0 && shift == j) 2950 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 2951 else 2952 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 2953 2954 return Builder.CreateCall(F, Ops, name); 2955 } 2956 2957 Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 2958 bool neg) { 2959 int SV = cast<ConstantInt>(V)->getSExtValue(); 2960 return ConstantInt::get(Ty, neg ? -SV : SV); 2961 } 2962 2963 // \brief Right-shift a vector by a constant. 2964 Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, 2965 llvm::Type *Ty, bool usgn, 2966 const char *name) { 2967 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 2968 2969 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); 2970 int EltSize = VTy->getScalarSizeInBits(); 2971 2972 Vec = Builder.CreateBitCast(Vec, Ty); 2973 2974 // lshr/ashr are undefined when the shift amount is equal to the vector 2975 // element size. 2976 if (ShiftAmt == EltSize) { 2977 if (usgn) { 2978 // Right-shifting an unsigned value by its size yields 0. 2979 return llvm::ConstantAggregateZero::get(VTy); 2980 } else { 2981 // Right-shifting a signed value by its size is equivalent 2982 // to a shift of size-1. 2983 --ShiftAmt; 2984 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); 2985 } 2986 } 2987 2988 Shift = EmitNeonShiftVector(Shift, Ty, false); 2989 if (usgn) 2990 return Builder.CreateLShr(Vec, Shift, name); 2991 else 2992 return Builder.CreateAShr(Vec, Shift, name); 2993 } 2994 2995 enum { 2996 AddRetType = (1 << 0), 2997 Add1ArgType = (1 << 1), 2998 Add2ArgTypes = (1 << 2), 2999 3000 VectorizeRetType = (1 << 3), 3001 VectorizeArgTypes = (1 << 4), 3002 3003 InventFloatType = (1 << 5), 3004 UnsignedAlts = (1 << 6), 3005 3006 Use64BitVectors = (1 << 7), 3007 Use128BitVectors = (1 << 8), 3008 3009 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes, 3010 VectorRet = AddRetType | VectorizeRetType, 3011 VectorRetGetArgs01 = 3012 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes, 3013 FpCmpzModifiers = 3014 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType 3015 }; 3016 3017 namespace { 3018 struct NeonIntrinsicInfo { 3019 const char *NameHint; 3020 unsigned BuiltinID; 3021 unsigned LLVMIntrinsic; 3022 unsigned AltLLVMIntrinsic; 3023 unsigned TypeModifier; 3024 3025 bool operator<(unsigned RHSBuiltinID) const { 3026 return BuiltinID < RHSBuiltinID; 3027 } 3028 bool operator<(const NeonIntrinsicInfo &TE) const { 3029 return BuiltinID < TE.BuiltinID; 3030 } 3031 }; 3032 } // end anonymous namespace 3033 3034 #define NEONMAP0(NameBase) \ 3035 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 } 3036 3037 #define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ 3038 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3039 Intrinsic::LLVMIntrinsic, 0, TypeModifier } 3040 3041 #define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \ 3042 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3043 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ 3044 TypeModifier } 3045 3046 static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { 3047 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3048 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3049 NEONMAP1(vabs_v, arm_neon_vabs, 0), 3050 NEONMAP1(vabsq_v, arm_neon_vabs, 0), 3051 NEONMAP0(vaddhn_v), 3052 NEONMAP1(vaesdq_v, arm_neon_aesd, 0), 3053 NEONMAP1(vaeseq_v, arm_neon_aese, 0), 3054 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), 3055 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), 3056 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), 3057 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), 3058 NEONMAP1(vcage_v, arm_neon_vacge, 0), 3059 NEONMAP1(vcageq_v, arm_neon_vacge, 0), 3060 NEONMAP1(vcagt_v, arm_neon_vacgt, 0), 3061 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0), 3062 NEONMAP1(vcale_v, arm_neon_vacge, 0), 3063 NEONMAP1(vcaleq_v, arm_neon_vacge, 0), 3064 NEONMAP1(vcalt_v, arm_neon_vacgt, 0), 3065 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0), 3066 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType), 3067 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType), 3068 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3069 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3070 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3071 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3072 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0), 3073 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), 3074 NEONMAP0(vcvt_f32_v), 3075 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3076 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3077 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3078 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3079 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3080 NEONMAP0(vcvt_s32_v), 3081 NEONMAP0(vcvt_s64_v), 3082 NEONMAP0(vcvt_u32_v), 3083 NEONMAP0(vcvt_u64_v), 3084 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), 3085 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), 3086 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), 3087 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), 3088 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), 3089 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), 3090 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), 3091 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), 3092 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), 3093 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), 3094 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), 3095 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), 3096 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), 3097 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), 3098 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), 3099 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), 3100 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), 3101 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), 3102 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), 3103 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), 3104 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), 3105 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), 3106 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), 3107 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), 3108 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), 3109 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), 3110 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), 3111 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), 3112 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), 3113 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), 3114 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), 3115 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), 3116 NEONMAP0(vcvtq_f32_v), 3117 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3118 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3119 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3120 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3121 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3122 NEONMAP0(vcvtq_s32_v), 3123 NEONMAP0(vcvtq_s64_v), 3124 NEONMAP0(vcvtq_u32_v), 3125 NEONMAP0(vcvtq_u64_v), 3126 NEONMAP0(vext_v), 3127 NEONMAP0(vextq_v), 3128 NEONMAP0(vfma_v), 3129 NEONMAP0(vfmaq_v), 3130 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3131 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3132 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3133 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3134 NEONMAP0(vld1_dup_v), 3135 NEONMAP1(vld1_v, arm_neon_vld1, 0), 3136 NEONMAP0(vld1q_dup_v), 3137 NEONMAP1(vld1q_v, arm_neon_vld1, 0), 3138 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0), 3139 NEONMAP1(vld2_v, arm_neon_vld2, 0), 3140 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0), 3141 NEONMAP1(vld2q_v, arm_neon_vld2, 0), 3142 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0), 3143 NEONMAP1(vld3_v, arm_neon_vld3, 0), 3144 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0), 3145 NEONMAP1(vld3q_v, arm_neon_vld3, 0), 3146 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0), 3147 NEONMAP1(vld4_v, arm_neon_vld4, 0), 3148 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0), 3149 NEONMAP1(vld4q_v, arm_neon_vld4, 0), 3150 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3151 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType), 3152 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType), 3153 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3154 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3155 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType), 3156 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType), 3157 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3158 NEONMAP0(vmovl_v), 3159 NEONMAP0(vmovn_v), 3160 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType), 3161 NEONMAP0(vmull_v), 3162 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType), 3163 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3164 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3165 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType), 3166 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3167 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3168 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType), 3169 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts), 3170 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts), 3171 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType), 3172 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType), 3173 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3174 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3175 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0), 3176 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0), 3177 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType), 3178 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType), 3179 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType), 3180 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts), 3181 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), 3182 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), 3183 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), 3184 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), 3185 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), 3186 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3187 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3188 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3189 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3190 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3191 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3192 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0), 3193 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0), 3194 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3195 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3196 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType), 3197 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3198 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3199 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType), 3200 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType), 3201 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3202 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3203 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType), 3204 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType), 3205 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType), 3206 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType), 3207 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType), 3208 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType), 3209 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType), 3210 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType), 3211 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType), 3212 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType), 3213 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType), 3214 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType), 3215 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3216 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3217 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3218 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3219 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3220 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3221 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType), 3222 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType), 3223 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType), 3224 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0), 3225 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0), 3226 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0), 3227 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0), 3228 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0), 3229 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0), 3230 NEONMAP0(vshl_n_v), 3231 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3232 NEONMAP0(vshll_n_v), 3233 NEONMAP0(vshlq_n_v), 3234 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3235 NEONMAP0(vshr_n_v), 3236 NEONMAP0(vshrn_n_v), 3237 NEONMAP0(vshrq_n_v), 3238 NEONMAP1(vst1_v, arm_neon_vst1, 0), 3239 NEONMAP1(vst1q_v, arm_neon_vst1, 0), 3240 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0), 3241 NEONMAP1(vst2_v, arm_neon_vst2, 0), 3242 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0), 3243 NEONMAP1(vst2q_v, arm_neon_vst2, 0), 3244 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0), 3245 NEONMAP1(vst3_v, arm_neon_vst3, 0), 3246 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0), 3247 NEONMAP1(vst3q_v, arm_neon_vst3, 0), 3248 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0), 3249 NEONMAP1(vst4_v, arm_neon_vst4, 0), 3250 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0), 3251 NEONMAP1(vst4q_v, arm_neon_vst4, 0), 3252 NEONMAP0(vsubhn_v), 3253 NEONMAP0(vtrn_v), 3254 NEONMAP0(vtrnq_v), 3255 NEONMAP0(vtst_v), 3256 NEONMAP0(vtstq_v), 3257 NEONMAP0(vuzp_v), 3258 NEONMAP0(vuzpq_v), 3259 NEONMAP0(vzip_v), 3260 NEONMAP0(vzipq_v) 3261 }; 3262 3263 static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = { 3264 NEONMAP1(vabs_v, aarch64_neon_abs, 0), 3265 NEONMAP1(vabsq_v, aarch64_neon_abs, 0), 3266 NEONMAP0(vaddhn_v), 3267 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0), 3268 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0), 3269 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0), 3270 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0), 3271 NEONMAP1(vcage_v, aarch64_neon_facge, 0), 3272 NEONMAP1(vcageq_v, aarch64_neon_facge, 0), 3273 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0), 3274 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0), 3275 NEONMAP1(vcale_v, aarch64_neon_facge, 0), 3276 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0), 3277 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0), 3278 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0), 3279 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType), 3280 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType), 3281 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3282 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3283 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3284 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3285 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0), 3286 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0), 3287 NEONMAP0(vcvt_f32_v), 3288 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3289 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3290 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3291 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3292 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3293 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3294 NEONMAP0(vcvtq_f32_v), 3295 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3296 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3297 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3298 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3299 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3300 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3301 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType), 3302 NEONMAP0(vext_v), 3303 NEONMAP0(vextq_v), 3304 NEONMAP0(vfma_v), 3305 NEONMAP0(vfmaq_v), 3306 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3307 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3308 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3309 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3310 NEONMAP0(vmovl_v), 3311 NEONMAP0(vmovn_v), 3312 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType), 3313 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType), 3314 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType), 3315 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3316 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3317 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType), 3318 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType), 3319 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType), 3320 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3321 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3322 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0), 3323 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0), 3324 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType), 3325 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType), 3326 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType), 3327 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts), 3328 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType), 3329 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType), 3330 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType), 3331 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType), 3332 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType), 3333 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3334 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3335 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts), 3336 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3337 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts), 3338 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3339 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0), 3340 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0), 3341 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3342 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3343 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType), 3344 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3345 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3346 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType), 3347 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType), 3348 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3349 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3350 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3351 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3352 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3353 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3354 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3355 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3356 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType), 3357 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType), 3358 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType), 3359 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0), 3360 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0), 3361 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0), 3362 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0), 3363 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0), 3364 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0), 3365 NEONMAP0(vshl_n_v), 3366 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3367 NEONMAP0(vshll_n_v), 3368 NEONMAP0(vshlq_n_v), 3369 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3370 NEONMAP0(vshr_n_v), 3371 NEONMAP0(vshrn_n_v), 3372 NEONMAP0(vshrq_n_v), 3373 NEONMAP0(vsubhn_v), 3374 NEONMAP0(vtst_v), 3375 NEONMAP0(vtstq_v), 3376 }; 3377 3378 static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = { 3379 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType), 3380 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType), 3381 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType), 3382 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3383 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3384 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3385 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3386 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3387 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3388 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3389 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3390 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType), 3391 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3392 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType), 3393 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3394 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3395 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3396 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3397 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3398 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3399 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3400 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3401 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3402 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3403 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3404 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3405 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3406 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3407 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3408 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3409 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3410 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3411 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3412 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3413 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3414 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3415 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3416 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3417 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3418 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3419 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3420 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3421 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3422 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3423 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3424 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3425 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3426 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3427 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0), 3428 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3429 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3430 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3431 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3432 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3433 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3434 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3435 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3436 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3437 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3438 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3439 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3440 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3441 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3442 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3443 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3444 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3445 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3446 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3447 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3448 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0), 3449 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType), 3450 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType), 3451 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3452 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3453 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3454 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3455 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3456 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3457 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3458 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3459 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3460 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3461 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3462 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType), 3463 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3464 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType), 3465 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3466 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3467 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType), 3468 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType), 3469 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3470 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3471 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType), 3472 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType), 3473 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors), 3474 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType), 3475 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors), 3476 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0), 3477 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType), 3478 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType), 3479 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3480 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3481 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3482 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3483 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType), 3484 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3485 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3486 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3487 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType), 3488 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3489 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType), 3490 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors), 3491 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType), 3492 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3493 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3494 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType), 3495 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType), 3496 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3497 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3498 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType), 3499 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType), 3500 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType), 3501 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType), 3502 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3503 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3504 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3505 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3506 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType), 3507 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3508 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3509 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3510 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3511 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3512 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3513 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType), 3514 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType), 3515 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3516 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3517 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3518 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3519 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType), 3520 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType), 3521 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType), 3522 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType), 3523 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3524 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3525 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType), 3526 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType), 3527 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType), 3528 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3529 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3530 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3531 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3532 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType), 3533 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3534 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3535 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3536 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3537 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType), 3538 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType), 3539 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3540 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3541 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType), 3542 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType), 3543 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType), 3544 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType), 3545 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType), 3546 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType), 3547 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType), 3548 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType), 3549 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType), 3550 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType), 3551 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType), 3552 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType), 3553 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0), 3554 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0), 3555 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0), 3556 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0), 3557 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType), 3558 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType), 3559 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType), 3560 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType), 3561 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3562 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType), 3563 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3564 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType), 3565 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType), 3566 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType), 3567 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3568 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType), 3569 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3570 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType), 3571 }; 3572 3573 #undef NEONMAP0 3574 #undef NEONMAP1 3575 #undef NEONMAP2 3576 3577 static bool NEONSIMDIntrinsicsProvenSorted = false; 3578 3579 static bool AArch64SIMDIntrinsicsProvenSorted = false; 3580 static bool AArch64SISDIntrinsicsProvenSorted = false; 3581 3582 3583 static const NeonIntrinsicInfo * 3584 findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap, 3585 unsigned BuiltinID, bool &MapProvenSorted) { 3586 3587 #ifndef NDEBUG 3588 if (!MapProvenSorted) { 3589 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap))); 3590 MapProvenSorted = true; 3591 } 3592 #endif 3593 3594 const NeonIntrinsicInfo *Builtin = 3595 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID); 3596 3597 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) 3598 return Builtin; 3599 3600 return nullptr; 3601 } 3602 3603 Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 3604 unsigned Modifier, 3605 llvm::Type *ArgType, 3606 const CallExpr *E) { 3607 int VectorSize = 0; 3608 if (Modifier & Use64BitVectors) 3609 VectorSize = 64; 3610 else if (Modifier & Use128BitVectors) 3611 VectorSize = 128; 3612 3613 // Return type. 3614 SmallVector<llvm::Type *, 3> Tys; 3615 if (Modifier & AddRetType) { 3616 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 3617 if (Modifier & VectorizeRetType) 3618 Ty = llvm::VectorType::get( 3619 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1); 3620 3621 Tys.push_back(Ty); 3622 } 3623 3624 // Arguments. 3625 if (Modifier & VectorizeArgTypes) { 3626 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1; 3627 ArgType = llvm::VectorType::get(ArgType, Elts); 3628 } 3629 3630 if (Modifier & (Add1ArgType | Add2ArgTypes)) 3631 Tys.push_back(ArgType); 3632 3633 if (Modifier & Add2ArgTypes) 3634 Tys.push_back(ArgType); 3635 3636 if (Modifier & InventFloatType) 3637 Tys.push_back(FloatTy); 3638 3639 return CGM.getIntrinsic(IntrinsicID, Tys); 3640 } 3641 3642 static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF, 3643 const NeonIntrinsicInfo &SISDInfo, 3644 SmallVectorImpl<Value *> &Ops, 3645 const CallExpr *E) { 3646 unsigned BuiltinID = SISDInfo.BuiltinID; 3647 unsigned int Int = SISDInfo.LLVMIntrinsic; 3648 unsigned Modifier = SISDInfo.TypeModifier; 3649 const char *s = SISDInfo.NameHint; 3650 3651 switch (BuiltinID) { 3652 case NEON::BI__builtin_neon_vcled_s64: 3653 case NEON::BI__builtin_neon_vcled_u64: 3654 case NEON::BI__builtin_neon_vcles_f32: 3655 case NEON::BI__builtin_neon_vcled_f64: 3656 case NEON::BI__builtin_neon_vcltd_s64: 3657 case NEON::BI__builtin_neon_vcltd_u64: 3658 case NEON::BI__builtin_neon_vclts_f32: 3659 case NEON::BI__builtin_neon_vcltd_f64: 3660 case NEON::BI__builtin_neon_vcales_f32: 3661 case NEON::BI__builtin_neon_vcaled_f64: 3662 case NEON::BI__builtin_neon_vcalts_f32: 3663 case NEON::BI__builtin_neon_vcaltd_f64: 3664 // Only one direction of comparisons actually exist, cmle is actually a cmge 3665 // with swapped operands. The table gives us the right intrinsic but we 3666 // still need to do the swap. 3667 std::swap(Ops[0], Ops[1]); 3668 break; 3669 } 3670 3671 assert(Int && "Generic code assumes a valid intrinsic"); 3672 3673 // Determine the type(s) of this overloaded AArch64 intrinsic. 3674 const Expr *Arg = E->getArg(0); 3675 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType()); 3676 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E); 3677 3678 int j = 0; 3679 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0); 3680 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3681 ai != ae; ++ai, ++j) { 3682 llvm::Type *ArgTy = ai->getType(); 3683 if (Ops[j]->getType()->getPrimitiveSizeInBits() == 3684 ArgTy->getPrimitiveSizeInBits()) 3685 continue; 3686 3687 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy()); 3688 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate 3689 // it before inserting. 3690 Ops[j] = 3691 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType()); 3692 Ops[j] = 3693 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0); 3694 } 3695 3696 Value *Result = CGF.EmitNeonCall(F, Ops, s); 3697 llvm::Type *ResultType = CGF.ConvertType(E->getType()); 3698 if (ResultType->getPrimitiveSizeInBits() < 3699 Result->getType()->getPrimitiveSizeInBits()) 3700 return CGF.Builder.CreateExtractElement(Result, C0); 3701 3702 return CGF.Builder.CreateBitCast(Result, ResultType, s); 3703 } 3704 3705 Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( 3706 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, 3707 const char *NameHint, unsigned Modifier, const CallExpr *E, 3708 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) { 3709 // Get the last argument, which specifies the vector type. 3710 llvm::APSInt NeonTypeConst; 3711 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 3712 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext())) 3713 return nullptr; 3714 3715 // Determine the type of this overloaded NEON intrinsic. 3716 NeonTypeFlags Type(NeonTypeConst.getZExtValue()); 3717 bool Usgn = Type.isUnsigned(); 3718 bool Quad = Type.isQuad(); 3719 3720 llvm::VectorType *VTy = GetNeonType(this, Type); 3721 llvm::Type *Ty = VTy; 3722 if (!Ty) 3723 return nullptr; 3724 3725 auto getAlignmentValue32 = [&](Address addr) -> Value* { 3726 return Builder.getInt32(addr.getAlignment().getQuantity()); 3727 }; 3728 3729 unsigned Int = LLVMIntrinsic; 3730 if ((Modifier & UnsignedAlts) && !Usgn) 3731 Int = AltLLVMIntrinsic; 3732 3733 switch (BuiltinID) { 3734 default: break; 3735 case NEON::BI__builtin_neon_vabs_v: 3736 case NEON::BI__builtin_neon_vabsq_v: 3737 if (VTy->getElementType()->isFloatingPointTy()) 3738 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); 3739 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs"); 3740 case NEON::BI__builtin_neon_vaddhn_v: { 3741 llvm::VectorType *SrcTy = 3742 llvm::VectorType::getExtendedElementVectorType(VTy); 3743 3744 // %sum = add <4 x i32> %lhs, %rhs 3745 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 3746 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 3747 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 3748 3749 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 3750 Constant *ShiftAmt = 3751 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 3752 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 3753 3754 // %res = trunc <4 x i32> %high to <4 x i16> 3755 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 3756 } 3757 case NEON::BI__builtin_neon_vcale_v: 3758 case NEON::BI__builtin_neon_vcaleq_v: 3759 case NEON::BI__builtin_neon_vcalt_v: 3760 case NEON::BI__builtin_neon_vcaltq_v: 3761 std::swap(Ops[0], Ops[1]); 3762 case NEON::BI__builtin_neon_vcage_v: 3763 case NEON::BI__builtin_neon_vcageq_v: 3764 case NEON::BI__builtin_neon_vcagt_v: 3765 case NEON::BI__builtin_neon_vcagtq_v: { 3766 llvm::Type *VecFlt = llvm::VectorType::get( 3767 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, 3768 VTy->getNumElements()); 3769 llvm::Type *Tys[] = { VTy, VecFlt }; 3770 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 3771 return EmitNeonCall(F, Ops, NameHint); 3772 } 3773 case NEON::BI__builtin_neon_vclz_v: 3774 case NEON::BI__builtin_neon_vclzq_v: 3775 // We generate target-independent intrinsic, which needs a second argument 3776 // for whether or not clz of zero is undefined; on ARM it isn't. 3777 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 3778 break; 3779 case NEON::BI__builtin_neon_vcvt_f32_v: 3780 case NEON::BI__builtin_neon_vcvtq_f32_v: 3781 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3782 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); 3783 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 3784 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 3785 case NEON::BI__builtin_neon_vcvt_n_f32_v: 3786 case NEON::BI__builtin_neon_vcvt_n_f64_v: 3787 case NEON::BI__builtin_neon_vcvtq_n_f32_v: 3788 case NEON::BI__builtin_neon_vcvtq_n_f64_v: { 3789 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty }; 3790 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic; 3791 Function *F = CGM.getIntrinsic(Int, Tys); 3792 return EmitNeonCall(F, Ops, "vcvt_n"); 3793 } 3794 case NEON::BI__builtin_neon_vcvt_n_s32_v: 3795 case NEON::BI__builtin_neon_vcvt_n_u32_v: 3796 case NEON::BI__builtin_neon_vcvt_n_s64_v: 3797 case NEON::BI__builtin_neon_vcvt_n_u64_v: 3798 case NEON::BI__builtin_neon_vcvtq_n_s32_v: 3799 case NEON::BI__builtin_neon_vcvtq_n_u32_v: 3800 case NEON::BI__builtin_neon_vcvtq_n_s64_v: 3801 case NEON::BI__builtin_neon_vcvtq_n_u64_v: { 3802 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 3803 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 3804 return EmitNeonCall(F, Ops, "vcvt_n"); 3805 } 3806 case NEON::BI__builtin_neon_vcvt_s32_v: 3807 case NEON::BI__builtin_neon_vcvt_u32_v: 3808 case NEON::BI__builtin_neon_vcvt_s64_v: 3809 case NEON::BI__builtin_neon_vcvt_u64_v: 3810 case NEON::BI__builtin_neon_vcvtq_s32_v: 3811 case NEON::BI__builtin_neon_vcvtq_u32_v: 3812 case NEON::BI__builtin_neon_vcvtq_s64_v: 3813 case NEON::BI__builtin_neon_vcvtq_u64_v: { 3814 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 3815 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 3816 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 3817 } 3818 case NEON::BI__builtin_neon_vcvta_s32_v: 3819 case NEON::BI__builtin_neon_vcvta_s64_v: 3820 case NEON::BI__builtin_neon_vcvta_u32_v: 3821 case NEON::BI__builtin_neon_vcvta_u64_v: 3822 case NEON::BI__builtin_neon_vcvtaq_s32_v: 3823 case NEON::BI__builtin_neon_vcvtaq_s64_v: 3824 case NEON::BI__builtin_neon_vcvtaq_u32_v: 3825 case NEON::BI__builtin_neon_vcvtaq_u64_v: 3826 case NEON::BI__builtin_neon_vcvtn_s32_v: 3827 case NEON::BI__builtin_neon_vcvtn_s64_v: 3828 case NEON::BI__builtin_neon_vcvtn_u32_v: 3829 case NEON::BI__builtin_neon_vcvtn_u64_v: 3830 case NEON::BI__builtin_neon_vcvtnq_s32_v: 3831 case NEON::BI__builtin_neon_vcvtnq_s64_v: 3832 case NEON::BI__builtin_neon_vcvtnq_u32_v: 3833 case NEON::BI__builtin_neon_vcvtnq_u64_v: 3834 case NEON::BI__builtin_neon_vcvtp_s32_v: 3835 case NEON::BI__builtin_neon_vcvtp_s64_v: 3836 case NEON::BI__builtin_neon_vcvtp_u32_v: 3837 case NEON::BI__builtin_neon_vcvtp_u64_v: 3838 case NEON::BI__builtin_neon_vcvtpq_s32_v: 3839 case NEON::BI__builtin_neon_vcvtpq_s64_v: 3840 case NEON::BI__builtin_neon_vcvtpq_u32_v: 3841 case NEON::BI__builtin_neon_vcvtpq_u64_v: 3842 case NEON::BI__builtin_neon_vcvtm_s32_v: 3843 case NEON::BI__builtin_neon_vcvtm_s64_v: 3844 case NEON::BI__builtin_neon_vcvtm_u32_v: 3845 case NEON::BI__builtin_neon_vcvtm_u64_v: 3846 case NEON::BI__builtin_neon_vcvtmq_s32_v: 3847 case NEON::BI__builtin_neon_vcvtmq_s64_v: 3848 case NEON::BI__builtin_neon_vcvtmq_u32_v: 3849 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 3850 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 3851 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint); 3852 } 3853 case NEON::BI__builtin_neon_vext_v: 3854 case NEON::BI__builtin_neon_vextq_v: { 3855 int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 3856 SmallVector<uint32_t, 16> Indices; 3857 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 3858 Indices.push_back(i+CV); 3859 3860 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3861 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3862 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext"); 3863 } 3864 case NEON::BI__builtin_neon_vfma_v: 3865 case NEON::BI__builtin_neon_vfmaq_v: { 3866 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 3867 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3868 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 3869 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 3870 3871 // NEON intrinsic puts accumulator first, unlike the LLVM fma. 3872 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 3873 } 3874 case NEON::BI__builtin_neon_vld1_v: 3875 case NEON::BI__builtin_neon_vld1q_v: { 3876 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 3877 Ops.push_back(getAlignmentValue32(PtrOp0)); 3878 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1"); 3879 } 3880 case NEON::BI__builtin_neon_vld2_v: 3881 case NEON::BI__builtin_neon_vld2q_v: 3882 case NEON::BI__builtin_neon_vld3_v: 3883 case NEON::BI__builtin_neon_vld3q_v: 3884 case NEON::BI__builtin_neon_vld4_v: 3885 case NEON::BI__builtin_neon_vld4q_v: { 3886 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 3887 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 3888 Value *Align = getAlignmentValue32(PtrOp1); 3889 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint); 3890 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3891 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3892 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 3893 } 3894 case NEON::BI__builtin_neon_vld1_dup_v: 3895 case NEON::BI__builtin_neon_vld1q_dup_v: { 3896 Value *V = UndefValue::get(Ty); 3897 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 3898 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty); 3899 LoadInst *Ld = Builder.CreateLoad(PtrOp0); 3900 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 3901 Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 3902 return EmitNeonSplat(Ops[0], CI); 3903 } 3904 case NEON::BI__builtin_neon_vld2_lane_v: 3905 case NEON::BI__builtin_neon_vld2q_lane_v: 3906 case NEON::BI__builtin_neon_vld3_lane_v: 3907 case NEON::BI__builtin_neon_vld3q_lane_v: 3908 case NEON::BI__builtin_neon_vld4_lane_v: 3909 case NEON::BI__builtin_neon_vld4q_lane_v: { 3910 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 3911 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 3912 for (unsigned I = 2; I < Ops.size() - 1; ++I) 3913 Ops[I] = Builder.CreateBitCast(Ops[I], Ty); 3914 Ops.push_back(getAlignmentValue32(PtrOp1)); 3915 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint); 3916 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 3917 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 3918 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 3919 } 3920 case NEON::BI__builtin_neon_vmovl_v: { 3921 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 3922 Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 3923 if (Usgn) 3924 return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 3925 return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 3926 } 3927 case NEON::BI__builtin_neon_vmovn_v: { 3928 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 3929 Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 3930 return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 3931 } 3932 case NEON::BI__builtin_neon_vmull_v: 3933 // FIXME: the integer vmull operations could be emitted in terms of pure 3934 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 3935 // hoisting the exts outside loops. Until global ISel comes along that can 3936 // see through such movement this leads to bad CodeGen. So we need an 3937 // intrinsic for now. 3938 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 3939 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 3940 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 3941 case NEON::BI__builtin_neon_vpadal_v: 3942 case NEON::BI__builtin_neon_vpadalq_v: { 3943 // The source operand type has twice as many elements of half the size. 3944 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 3945 llvm::Type *EltTy = 3946 llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 3947 llvm::Type *NarrowTy = 3948 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 3949 llvm::Type *Tys[2] = { Ty, NarrowTy }; 3950 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); 3951 } 3952 case NEON::BI__builtin_neon_vpaddl_v: 3953 case NEON::BI__builtin_neon_vpaddlq_v: { 3954 // The source operand type has twice as many elements of half the size. 3955 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 3956 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 3957 llvm::Type *NarrowTy = 3958 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 3959 llvm::Type *Tys[2] = { Ty, NarrowTy }; 3960 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 3961 } 3962 case NEON::BI__builtin_neon_vqdmlal_v: 3963 case NEON::BI__builtin_neon_vqdmlsl_v: { 3964 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 3965 Ops[1] = 3966 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal"); 3967 Ops.resize(2); 3968 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint); 3969 } 3970 case NEON::BI__builtin_neon_vqshl_n_v: 3971 case NEON::BI__builtin_neon_vqshlq_n_v: 3972 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 3973 1, false); 3974 case NEON::BI__builtin_neon_vqshlu_n_v: 3975 case NEON::BI__builtin_neon_vqshluq_n_v: 3976 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n", 3977 1, false); 3978 case NEON::BI__builtin_neon_vrecpe_v: 3979 case NEON::BI__builtin_neon_vrecpeq_v: 3980 case NEON::BI__builtin_neon_vrsqrte_v: 3981 case NEON::BI__builtin_neon_vrsqrteq_v: 3982 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic; 3983 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint); 3984 3985 case NEON::BI__builtin_neon_vrshr_n_v: 3986 case NEON::BI__builtin_neon_vrshrq_n_v: 3987 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 3988 1, true); 3989 case NEON::BI__builtin_neon_vshl_n_v: 3990 case NEON::BI__builtin_neon_vshlq_n_v: 3991 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 3992 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 3993 "vshl_n"); 3994 case NEON::BI__builtin_neon_vshll_n_v: { 3995 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 3996 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 3997 if (Usgn) 3998 Ops[0] = Builder.CreateZExt(Ops[0], VTy); 3999 else 4000 Ops[0] = Builder.CreateSExt(Ops[0], VTy); 4001 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 4002 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 4003 } 4004 case NEON::BI__builtin_neon_vshrn_n_v: { 4005 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4006 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4007 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 4008 if (Usgn) 4009 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 4010 else 4011 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 4012 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 4013 } 4014 case NEON::BI__builtin_neon_vshr_n_v: 4015 case NEON::BI__builtin_neon_vshrq_n_v: 4016 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n"); 4017 case NEON::BI__builtin_neon_vst1_v: 4018 case NEON::BI__builtin_neon_vst1q_v: 4019 case NEON::BI__builtin_neon_vst2_v: 4020 case NEON::BI__builtin_neon_vst2q_v: 4021 case NEON::BI__builtin_neon_vst3_v: 4022 case NEON::BI__builtin_neon_vst3q_v: 4023 case NEON::BI__builtin_neon_vst4_v: 4024 case NEON::BI__builtin_neon_vst4q_v: 4025 case NEON::BI__builtin_neon_vst2_lane_v: 4026 case NEON::BI__builtin_neon_vst2q_lane_v: 4027 case NEON::BI__builtin_neon_vst3_lane_v: 4028 case NEON::BI__builtin_neon_vst3q_lane_v: 4029 case NEON::BI__builtin_neon_vst4_lane_v: 4030 case NEON::BI__builtin_neon_vst4q_lane_v: { 4031 llvm::Type *Tys[] = {Int8PtrTy, Ty}; 4032 Ops.push_back(getAlignmentValue32(PtrOp0)); 4033 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 4034 } 4035 case NEON::BI__builtin_neon_vsubhn_v: { 4036 llvm::VectorType *SrcTy = 4037 llvm::VectorType::getExtendedElementVectorType(VTy); 4038 4039 // %sum = add <4 x i32> %lhs, %rhs 4040 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4041 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4042 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 4043 4044 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4045 Constant *ShiftAmt = 4046 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4047 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 4048 4049 // %res = trunc <4 x i32> %high to <4 x i16> 4050 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 4051 } 4052 case NEON::BI__builtin_neon_vtrn_v: 4053 case NEON::BI__builtin_neon_vtrnq_v: { 4054 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4055 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4056 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4057 Value *SV = nullptr; 4058 4059 for (unsigned vi = 0; vi != 2; ++vi) { 4060 SmallVector<uint32_t, 16> Indices; 4061 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4062 Indices.push_back(i+vi); 4063 Indices.push_back(i+e+vi); 4064 } 4065 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4066 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 4067 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4068 } 4069 return SV; 4070 } 4071 case NEON::BI__builtin_neon_vtst_v: 4072 case NEON::BI__builtin_neon_vtstq_v: { 4073 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4074 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4075 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 4076 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 4077 ConstantAggregateZero::get(Ty)); 4078 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 4079 } 4080 case NEON::BI__builtin_neon_vuzp_v: 4081 case NEON::BI__builtin_neon_vuzpq_v: { 4082 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4083 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4084 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4085 Value *SV = nullptr; 4086 4087 for (unsigned vi = 0; vi != 2; ++vi) { 4088 SmallVector<uint32_t, 16> Indices; 4089 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4090 Indices.push_back(2*i+vi); 4091 4092 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4093 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 4094 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4095 } 4096 return SV; 4097 } 4098 case NEON::BI__builtin_neon_vzip_v: 4099 case NEON::BI__builtin_neon_vzipq_v: { 4100 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4101 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4102 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4103 Value *SV = nullptr; 4104 4105 for (unsigned vi = 0; vi != 2; ++vi) { 4106 SmallVector<uint32_t, 16> Indices; 4107 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4108 Indices.push_back((i + vi*e) >> 1); 4109 Indices.push_back(((i + vi*e) >> 1)+e); 4110 } 4111 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4112 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 4113 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4114 } 4115 return SV; 4116 } 4117 } 4118 4119 assert(Int && "Expected valid intrinsic number"); 4120 4121 // Determine the type(s) of this overloaded AArch64 intrinsic. 4122 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E); 4123 4124 Value *Result = EmitNeonCall(F, Ops, NameHint); 4125 llvm::Type *ResultType = ConvertType(E->getType()); 4126 // AArch64 intrinsic one-element vector type cast to 4127 // scalar type expected by the builtin 4128 return Builder.CreateBitCast(Result, ResultType, NameHint); 4129 } 4130 4131 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( 4132 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, 4133 const CmpInst::Predicate Ip, const Twine &Name) { 4134 llvm::Type *OTy = Op->getType(); 4135 4136 // FIXME: this is utterly horrific. We should not be looking at previous 4137 // codegen context to find out what needs doing. Unfortunately TableGen 4138 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32 4139 // (etc). 4140 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op)) 4141 OTy = BI->getOperand(0)->getType(); 4142 4143 Op = Builder.CreateBitCast(Op, OTy); 4144 if (OTy->getScalarType()->isFloatingPointTy()) { 4145 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy)); 4146 } else { 4147 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy)); 4148 } 4149 return Builder.CreateSExt(Op, Ty, Name); 4150 } 4151 4152 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, 4153 Value *ExtOp, Value *IndexOp, 4154 llvm::Type *ResTy, unsigned IntID, 4155 const char *Name) { 4156 SmallVector<Value *, 2> TblOps; 4157 if (ExtOp) 4158 TblOps.push_back(ExtOp); 4159 4160 // Build a vector containing sequential number like (0, 1, 2, ..., 15) 4161 SmallVector<uint32_t, 16> Indices; 4162 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); 4163 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { 4164 Indices.push_back(2*i); 4165 Indices.push_back(2*i+1); 4166 } 4167 4168 int PairPos = 0, End = Ops.size() - 1; 4169 while (PairPos < End) { 4170 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4171 Ops[PairPos+1], Indices, 4172 Name)); 4173 PairPos += 2; 4174 } 4175 4176 // If there's an odd number of 64-bit lookup table, fill the high 64-bit 4177 // of the 128-bit lookup table with zero. 4178 if (PairPos == End) { 4179 Value *ZeroTbl = ConstantAggregateZero::get(TblTy); 4180 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4181 ZeroTbl, Indices, Name)); 4182 } 4183 4184 Function *TblF; 4185 TblOps.push_back(IndexOp); 4186 TblF = CGF.CGM.getIntrinsic(IntID, ResTy); 4187 4188 return CGF.EmitNeonCall(TblF, TblOps, Name); 4189 } 4190 4191 Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) { 4192 unsigned Value; 4193 switch (BuiltinID) { 4194 default: 4195 return nullptr; 4196 case ARM::BI__builtin_arm_nop: 4197 Value = 0; 4198 break; 4199 case ARM::BI__builtin_arm_yield: 4200 case ARM::BI__yield: 4201 Value = 1; 4202 break; 4203 case ARM::BI__builtin_arm_wfe: 4204 case ARM::BI__wfe: 4205 Value = 2; 4206 break; 4207 case ARM::BI__builtin_arm_wfi: 4208 case ARM::BI__wfi: 4209 Value = 3; 4210 break; 4211 case ARM::BI__builtin_arm_sev: 4212 case ARM::BI__sev: 4213 Value = 4; 4214 break; 4215 case ARM::BI__builtin_arm_sevl: 4216 case ARM::BI__sevl: 4217 Value = 5; 4218 break; 4219 } 4220 4221 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint), 4222 llvm::ConstantInt::get(Int32Ty, Value)); 4223 } 4224 4225 // Generates the IR for the read/write special register builtin, 4226 // ValueType is the type of the value that is to be written or read, 4227 // RegisterType is the type of the register being written to or read from. 4228 static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF, 4229 const CallExpr *E, 4230 llvm::Type *RegisterType, 4231 llvm::Type *ValueType, 4232 bool IsRead, 4233 StringRef SysReg = "") { 4234 // write and register intrinsics only support 32 and 64 bit operations. 4235 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64)) 4236 && "Unsupported size for register."); 4237 4238 CodeGen::CGBuilderTy &Builder = CGF.Builder; 4239 CodeGen::CodeGenModule &CGM = CGF.CGM; 4240 LLVMContext &Context = CGM.getLLVMContext(); 4241 4242 if (SysReg.empty()) { 4243 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts(); 4244 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString(); 4245 } 4246 4247 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) }; 4248 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops); 4249 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName); 4250 4251 llvm::Type *Types[] = { RegisterType }; 4252 4253 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32); 4254 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64)) 4255 && "Can't fit 64-bit value in 32-bit register"); 4256 4257 if (IsRead) { 4258 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types); 4259 llvm::Value *Call = Builder.CreateCall(F, Metadata); 4260 4261 if (MixedTypes) 4262 // Read into 64 bit register and then truncate result to 32 bit. 4263 return Builder.CreateTrunc(Call, ValueType); 4264 4265 if (ValueType->isPointerTy()) 4266 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*). 4267 return Builder.CreateIntToPtr(Call, ValueType); 4268 4269 return Call; 4270 } 4271 4272 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types); 4273 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1)); 4274 if (MixedTypes) { 4275 // Extend 32 bit write value to 64 bit to pass to write. 4276 ArgValue = Builder.CreateZExt(ArgValue, RegisterType); 4277 return Builder.CreateCall(F, { Metadata, ArgValue }); 4278 } 4279 4280 if (ValueType->isPointerTy()) { 4281 // Have VoidPtrTy ArgValue but want to return an i32/i64. 4282 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType); 4283 return Builder.CreateCall(F, { Metadata, ArgValue }); 4284 } 4285 4286 return Builder.CreateCall(F, { Metadata, ArgValue }); 4287 } 4288 4289 /// Return true if BuiltinID is an overloaded Neon intrinsic with an extra 4290 /// argument that specifies the vector type. 4291 static bool HasExtraNeonArgument(unsigned BuiltinID) { 4292 switch (BuiltinID) { 4293 default: break; 4294 case NEON::BI__builtin_neon_vget_lane_i8: 4295 case NEON::BI__builtin_neon_vget_lane_i16: 4296 case NEON::BI__builtin_neon_vget_lane_i32: 4297 case NEON::BI__builtin_neon_vget_lane_i64: 4298 case NEON::BI__builtin_neon_vget_lane_f32: 4299 case NEON::BI__builtin_neon_vgetq_lane_i8: 4300 case NEON::BI__builtin_neon_vgetq_lane_i16: 4301 case NEON::BI__builtin_neon_vgetq_lane_i32: 4302 case NEON::BI__builtin_neon_vgetq_lane_i64: 4303 case NEON::BI__builtin_neon_vgetq_lane_f32: 4304 case NEON::BI__builtin_neon_vset_lane_i8: 4305 case NEON::BI__builtin_neon_vset_lane_i16: 4306 case NEON::BI__builtin_neon_vset_lane_i32: 4307 case NEON::BI__builtin_neon_vset_lane_i64: 4308 case NEON::BI__builtin_neon_vset_lane_f32: 4309 case NEON::BI__builtin_neon_vsetq_lane_i8: 4310 case NEON::BI__builtin_neon_vsetq_lane_i16: 4311 case NEON::BI__builtin_neon_vsetq_lane_i32: 4312 case NEON::BI__builtin_neon_vsetq_lane_i64: 4313 case NEON::BI__builtin_neon_vsetq_lane_f32: 4314 case NEON::BI__builtin_neon_vsha1h_u32: 4315 case NEON::BI__builtin_neon_vsha1cq_u32: 4316 case NEON::BI__builtin_neon_vsha1pq_u32: 4317 case NEON::BI__builtin_neon_vsha1mq_u32: 4318 case ARM::BI_MoveToCoprocessor: 4319 case ARM::BI_MoveToCoprocessor2: 4320 return false; 4321 } 4322 return true; 4323 } 4324 4325 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 4326 const CallExpr *E) { 4327 if (auto Hint = GetValueForARMHint(BuiltinID)) 4328 return Hint; 4329 4330 if (BuiltinID == ARM::BI__emit) { 4331 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb; 4332 llvm::FunctionType *FTy = 4333 llvm::FunctionType::get(VoidTy, /*Variadic=*/false); 4334 4335 APSInt Value; 4336 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext())) 4337 llvm_unreachable("Sema will ensure that the parameter is constant"); 4338 4339 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue(); 4340 4341 llvm::InlineAsm *Emit = 4342 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "", 4343 /*SideEffects=*/true) 4344 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "", 4345 /*SideEffects=*/true); 4346 4347 return Builder.CreateCall(Emit); 4348 } 4349 4350 if (BuiltinID == ARM::BI__builtin_arm_dbg) { 4351 Value *Option = EmitScalarExpr(E->getArg(0)); 4352 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option); 4353 } 4354 4355 if (BuiltinID == ARM::BI__builtin_arm_prefetch) { 4356 Value *Address = EmitScalarExpr(E->getArg(0)); 4357 Value *RW = EmitScalarExpr(E->getArg(1)); 4358 Value *IsData = EmitScalarExpr(E->getArg(2)); 4359 4360 // Locality is not supported on ARM target 4361 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3); 4362 4363 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4364 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 4365 } 4366 4367 if (BuiltinID == ARM::BI__builtin_arm_rbit) { 4368 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 4369 return Builder.CreateCall( 4370 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 4371 } 4372 4373 if (BuiltinID == ARM::BI__clear_cache) { 4374 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 4375 const FunctionDecl *FD = E->getDirectCallee(); 4376 Value *Ops[2]; 4377 for (unsigned i = 0; i < 2; i++) 4378 Ops[i] = EmitScalarExpr(E->getArg(i)); 4379 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 4380 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 4381 StringRef Name = FD->getName(); 4382 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 4383 } 4384 4385 if (BuiltinID == ARM::BI__builtin_arm_mcrr || 4386 BuiltinID == ARM::BI__builtin_arm_mcrr2) { 4387 Function *F; 4388 4389 switch (BuiltinID) { 4390 default: llvm_unreachable("unexpected builtin"); 4391 case ARM::BI__builtin_arm_mcrr: 4392 F = CGM.getIntrinsic(Intrinsic::arm_mcrr); 4393 break; 4394 case ARM::BI__builtin_arm_mcrr2: 4395 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2); 4396 break; 4397 } 4398 4399 // MCRR{2} instruction has 5 operands but 4400 // the intrinsic has 4 because Rt and Rt2 4401 // are represented as a single unsigned 64 4402 // bit integer in the intrinsic definition 4403 // but internally it's represented as 2 32 4404 // bit integers. 4405 4406 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4407 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4408 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2)); 4409 Value *CRm = EmitScalarExpr(E->getArg(3)); 4410 4411 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4412 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty); 4413 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1); 4414 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty); 4415 4416 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm}); 4417 } 4418 4419 if (BuiltinID == ARM::BI__builtin_arm_mrrc || 4420 BuiltinID == ARM::BI__builtin_arm_mrrc2) { 4421 Function *F; 4422 4423 switch (BuiltinID) { 4424 default: llvm_unreachable("unexpected builtin"); 4425 case ARM::BI__builtin_arm_mrrc: 4426 F = CGM.getIntrinsic(Intrinsic::arm_mrrc); 4427 break; 4428 case ARM::BI__builtin_arm_mrrc2: 4429 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2); 4430 break; 4431 } 4432 4433 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4434 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4435 Value *CRm = EmitScalarExpr(E->getArg(2)); 4436 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm}); 4437 4438 // Returns an unsigned 64 bit integer, represented 4439 // as two 32 bit integers. 4440 4441 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1); 4442 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0); 4443 Rt = Builder.CreateZExt(Rt, Int64Ty); 4444 Rt1 = Builder.CreateZExt(Rt1, Int64Ty); 4445 4446 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32); 4447 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true); 4448 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1); 4449 4450 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType())); 4451 } 4452 4453 if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 4454 ((BuiltinID == ARM::BI__builtin_arm_ldrex || 4455 BuiltinID == ARM::BI__builtin_arm_ldaex) && 4456 getContext().getTypeSize(E->getType()) == 64) || 4457 BuiltinID == ARM::BI__ldrexd) { 4458 Function *F; 4459 4460 switch (BuiltinID) { 4461 default: llvm_unreachable("unexpected builtin"); 4462 case ARM::BI__builtin_arm_ldaex: 4463 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd); 4464 break; 4465 case ARM::BI__builtin_arm_ldrexd: 4466 case ARM::BI__builtin_arm_ldrex: 4467 case ARM::BI__ldrexd: 4468 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 4469 break; 4470 } 4471 4472 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 4473 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 4474 "ldrexd"); 4475 4476 Value *Val0 = Builder.CreateExtractValue(Val, 1); 4477 Value *Val1 = Builder.CreateExtractValue(Val, 0); 4478 Val0 = Builder.CreateZExt(Val0, Int64Ty); 4479 Val1 = Builder.CreateZExt(Val1, Int64Ty); 4480 4481 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 4482 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 4483 Val = Builder.CreateOr(Val, Val1); 4484 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 4485 } 4486 4487 if (BuiltinID == ARM::BI__builtin_arm_ldrex || 4488 BuiltinID == ARM::BI__builtin_arm_ldaex) { 4489 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 4490 4491 QualType Ty = E->getType(); 4492 llvm::Type *RealResTy = ConvertType(Ty); 4493 llvm::Type *PtrTy = llvm::IntegerType::get( 4494 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 4495 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 4496 4497 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex 4498 ? Intrinsic::arm_ldaex 4499 : Intrinsic::arm_ldrex, 4500 PtrTy); 4501 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 4502 4503 if (RealResTy->isPointerTy()) 4504 return Builder.CreateIntToPtr(Val, RealResTy); 4505 else { 4506 llvm::Type *IntResTy = llvm::IntegerType::get( 4507 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 4508 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 4509 return Builder.CreateBitCast(Val, RealResTy); 4510 } 4511 } 4512 4513 if (BuiltinID == ARM::BI__builtin_arm_strexd || 4514 ((BuiltinID == ARM::BI__builtin_arm_stlex || 4515 BuiltinID == ARM::BI__builtin_arm_strex) && 4516 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 4517 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4518 ? Intrinsic::arm_stlexd 4519 : Intrinsic::arm_strexd); 4520 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, nullptr); 4521 4522 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 4523 Value *Val = EmitScalarExpr(E->getArg(0)); 4524 Builder.CreateStore(Val, Tmp); 4525 4526 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 4527 Val = Builder.CreateLoad(LdPtr); 4528 4529 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 4530 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 4531 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 4532 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd"); 4533 } 4534 4535 if (BuiltinID == ARM::BI__builtin_arm_strex || 4536 BuiltinID == ARM::BI__builtin_arm_stlex) { 4537 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 4538 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 4539 4540 QualType Ty = E->getArg(0)->getType(); 4541 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 4542 getContext().getTypeSize(Ty)); 4543 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 4544 4545 if (StoreVal->getType()->isPointerTy()) 4546 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 4547 else { 4548 llvm::Type *IntTy = llvm::IntegerType::get( 4549 getLLVMContext(), 4550 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 4551 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 4552 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 4553 } 4554 4555 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4556 ? Intrinsic::arm_stlex 4557 : Intrinsic::arm_strex, 4558 StoreAddr->getType()); 4559 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex"); 4560 } 4561 4562 switch (BuiltinID) { 4563 case ARM::BI__iso_volatile_load8: 4564 case ARM::BI__iso_volatile_load16: 4565 case ARM::BI__iso_volatile_load32: 4566 case ARM::BI__iso_volatile_load64: { 4567 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4568 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4569 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); 4570 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4571 LoadSize.getQuantity() * 8); 4572 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4573 llvm::LoadInst *Load = 4574 Builder.CreateAlignedLoad(Ptr, LoadSize); 4575 Load->setVolatile(true); 4576 return Load; 4577 } 4578 case ARM::BI__iso_volatile_store8: 4579 case ARM::BI__iso_volatile_store16: 4580 case ARM::BI__iso_volatile_store32: 4581 case ARM::BI__iso_volatile_store64: { 4582 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4583 Value *Value = EmitScalarExpr(E->getArg(1)); 4584 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4585 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 4586 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4587 StoreSize.getQuantity() * 8); 4588 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4589 llvm::StoreInst *Store = 4590 Builder.CreateAlignedStore(Value, Ptr, 4591 StoreSize); 4592 Store->setVolatile(true); 4593 return Store; 4594 } 4595 } 4596 4597 if (BuiltinID == ARM::BI__builtin_arm_clrex) { 4598 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 4599 return Builder.CreateCall(F); 4600 } 4601 4602 // CRC32 4603 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 4604 switch (BuiltinID) { 4605 case ARM::BI__builtin_arm_crc32b: 4606 CRCIntrinsicID = Intrinsic::arm_crc32b; break; 4607 case ARM::BI__builtin_arm_crc32cb: 4608 CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 4609 case ARM::BI__builtin_arm_crc32h: 4610 CRCIntrinsicID = Intrinsic::arm_crc32h; break; 4611 case ARM::BI__builtin_arm_crc32ch: 4612 CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 4613 case ARM::BI__builtin_arm_crc32w: 4614 case ARM::BI__builtin_arm_crc32d: 4615 CRCIntrinsicID = Intrinsic::arm_crc32w; break; 4616 case ARM::BI__builtin_arm_crc32cw: 4617 case ARM::BI__builtin_arm_crc32cd: 4618 CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 4619 } 4620 4621 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 4622 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 4623 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 4624 4625 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 4626 // intrinsics, hence we need different codegen for these cases. 4627 if (BuiltinID == ARM::BI__builtin_arm_crc32d || 4628 BuiltinID == ARM::BI__builtin_arm_crc32cd) { 4629 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4630 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 4631 Value *Arg1b = Builder.CreateLShr(Arg1, C1); 4632 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 4633 4634 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4635 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a}); 4636 return Builder.CreateCall(F, {Res, Arg1b}); 4637 } else { 4638 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 4639 4640 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4641 return Builder.CreateCall(F, {Arg0, Arg1}); 4642 } 4643 } 4644 4645 if (BuiltinID == ARM::BI__builtin_arm_rsr || 4646 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4647 BuiltinID == ARM::BI__builtin_arm_rsrp || 4648 BuiltinID == ARM::BI__builtin_arm_wsr || 4649 BuiltinID == ARM::BI__builtin_arm_wsr64 || 4650 BuiltinID == ARM::BI__builtin_arm_wsrp) { 4651 4652 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr || 4653 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4654 BuiltinID == ARM::BI__builtin_arm_rsrp; 4655 4656 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp || 4657 BuiltinID == ARM::BI__builtin_arm_wsrp; 4658 4659 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 || 4660 BuiltinID == ARM::BI__builtin_arm_wsr64; 4661 4662 llvm::Type *ValueType; 4663 llvm::Type *RegisterType; 4664 if (IsPointerBuiltin) { 4665 ValueType = VoidPtrTy; 4666 RegisterType = Int32Ty; 4667 } else if (Is64Bit) { 4668 ValueType = RegisterType = Int64Ty; 4669 } else { 4670 ValueType = RegisterType = Int32Ty; 4671 } 4672 4673 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 4674 } 4675 4676 // Find out if any arguments are required to be integer constant 4677 // expressions. 4678 unsigned ICEArguments = 0; 4679 ASTContext::GetBuiltinTypeError Error; 4680 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 4681 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 4682 4683 auto getAlignmentValue32 = [&](Address addr) -> Value* { 4684 return Builder.getInt32(addr.getAlignment().getQuantity()); 4685 }; 4686 4687 Address PtrOp0 = Address::invalid(); 4688 Address PtrOp1 = Address::invalid(); 4689 SmallVector<Value*, 4> Ops; 4690 bool HasExtraArg = HasExtraNeonArgument(BuiltinID); 4691 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0); 4692 for (unsigned i = 0, e = NumArgs; i != e; i++) { 4693 if (i == 0) { 4694 switch (BuiltinID) { 4695 case NEON::BI__builtin_neon_vld1_v: 4696 case NEON::BI__builtin_neon_vld1q_v: 4697 case NEON::BI__builtin_neon_vld1q_lane_v: 4698 case NEON::BI__builtin_neon_vld1_lane_v: 4699 case NEON::BI__builtin_neon_vld1_dup_v: 4700 case NEON::BI__builtin_neon_vld1q_dup_v: 4701 case NEON::BI__builtin_neon_vst1_v: 4702 case NEON::BI__builtin_neon_vst1q_v: 4703 case NEON::BI__builtin_neon_vst1q_lane_v: 4704 case NEON::BI__builtin_neon_vst1_lane_v: 4705 case NEON::BI__builtin_neon_vst2_v: 4706 case NEON::BI__builtin_neon_vst2q_v: 4707 case NEON::BI__builtin_neon_vst2_lane_v: 4708 case NEON::BI__builtin_neon_vst2q_lane_v: 4709 case NEON::BI__builtin_neon_vst3_v: 4710 case NEON::BI__builtin_neon_vst3q_v: 4711 case NEON::BI__builtin_neon_vst3_lane_v: 4712 case NEON::BI__builtin_neon_vst3q_lane_v: 4713 case NEON::BI__builtin_neon_vst4_v: 4714 case NEON::BI__builtin_neon_vst4q_v: 4715 case NEON::BI__builtin_neon_vst4_lane_v: 4716 case NEON::BI__builtin_neon_vst4q_lane_v: 4717 // Get the alignment for the argument in addition to the value; 4718 // we'll use it later. 4719 PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); 4720 Ops.push_back(PtrOp0.getPointer()); 4721 continue; 4722 } 4723 } 4724 if (i == 1) { 4725 switch (BuiltinID) { 4726 case NEON::BI__builtin_neon_vld2_v: 4727 case NEON::BI__builtin_neon_vld2q_v: 4728 case NEON::BI__builtin_neon_vld3_v: 4729 case NEON::BI__builtin_neon_vld3q_v: 4730 case NEON::BI__builtin_neon_vld4_v: 4731 case NEON::BI__builtin_neon_vld4q_v: 4732 case NEON::BI__builtin_neon_vld2_lane_v: 4733 case NEON::BI__builtin_neon_vld2q_lane_v: 4734 case NEON::BI__builtin_neon_vld3_lane_v: 4735 case NEON::BI__builtin_neon_vld3q_lane_v: 4736 case NEON::BI__builtin_neon_vld4_lane_v: 4737 case NEON::BI__builtin_neon_vld4q_lane_v: 4738 case NEON::BI__builtin_neon_vld2_dup_v: 4739 case NEON::BI__builtin_neon_vld3_dup_v: 4740 case NEON::BI__builtin_neon_vld4_dup_v: 4741 // Get the alignment for the argument in addition to the value; 4742 // we'll use it later. 4743 PtrOp1 = EmitPointerWithAlignment(E->getArg(1)); 4744 Ops.push_back(PtrOp1.getPointer()); 4745 continue; 4746 } 4747 } 4748 4749 if ((ICEArguments & (1 << i)) == 0) { 4750 Ops.push_back(EmitScalarExpr(E->getArg(i))); 4751 } else { 4752 // If this is required to be a constant, constant fold it so that we know 4753 // that the generated intrinsic gets a ConstantInt. 4754 llvm::APSInt Result; 4755 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 4756 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 4757 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 4758 } 4759 } 4760 4761 switch (BuiltinID) { 4762 default: break; 4763 4764 case NEON::BI__builtin_neon_vget_lane_i8: 4765 case NEON::BI__builtin_neon_vget_lane_i16: 4766 case NEON::BI__builtin_neon_vget_lane_i32: 4767 case NEON::BI__builtin_neon_vget_lane_i64: 4768 case NEON::BI__builtin_neon_vget_lane_f32: 4769 case NEON::BI__builtin_neon_vgetq_lane_i8: 4770 case NEON::BI__builtin_neon_vgetq_lane_i16: 4771 case NEON::BI__builtin_neon_vgetq_lane_i32: 4772 case NEON::BI__builtin_neon_vgetq_lane_i64: 4773 case NEON::BI__builtin_neon_vgetq_lane_f32: 4774 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); 4775 4776 case NEON::BI__builtin_neon_vset_lane_i8: 4777 case NEON::BI__builtin_neon_vset_lane_i16: 4778 case NEON::BI__builtin_neon_vset_lane_i32: 4779 case NEON::BI__builtin_neon_vset_lane_i64: 4780 case NEON::BI__builtin_neon_vset_lane_f32: 4781 case NEON::BI__builtin_neon_vsetq_lane_i8: 4782 case NEON::BI__builtin_neon_vsetq_lane_i16: 4783 case NEON::BI__builtin_neon_vsetq_lane_i32: 4784 case NEON::BI__builtin_neon_vsetq_lane_i64: 4785 case NEON::BI__builtin_neon_vsetq_lane_f32: 4786 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 4787 4788 case NEON::BI__builtin_neon_vsha1h_u32: 4789 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, 4790 "vsha1h"); 4791 case NEON::BI__builtin_neon_vsha1cq_u32: 4792 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, 4793 "vsha1h"); 4794 case NEON::BI__builtin_neon_vsha1pq_u32: 4795 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, 4796 "vsha1h"); 4797 case NEON::BI__builtin_neon_vsha1mq_u32: 4798 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, 4799 "vsha1h"); 4800 4801 // The ARM _MoveToCoprocessor builtins put the input register value as 4802 // the first argument, but the LLVM intrinsic expects it as the third one. 4803 case ARM::BI_MoveToCoprocessor: 4804 case ARM::BI_MoveToCoprocessor2: { 4805 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ? 4806 Intrinsic::arm_mcr : Intrinsic::arm_mcr2); 4807 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], 4808 Ops[3], Ops[4], Ops[5]}); 4809 } 4810 case ARM::BI_BitScanForward: 4811 case ARM::BI_BitScanForward64: 4812 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 4813 case ARM::BI_BitScanReverse: 4814 case ARM::BI_BitScanReverse64: 4815 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 4816 4817 case ARM::BI_InterlockedAnd64: 4818 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 4819 case ARM::BI_InterlockedExchange64: 4820 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 4821 case ARM::BI_InterlockedExchangeAdd64: 4822 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 4823 case ARM::BI_InterlockedExchangeSub64: 4824 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 4825 case ARM::BI_InterlockedOr64: 4826 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 4827 case ARM::BI_InterlockedXor64: 4828 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 4829 case ARM::BI_InterlockedDecrement64: 4830 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 4831 case ARM::BI_InterlockedIncrement64: 4832 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 4833 } 4834 4835 // Get the last argument, which specifies the vector type. 4836 assert(HasExtraArg); 4837 llvm::APSInt Result; 4838 const Expr *Arg = E->getArg(E->getNumArgs()-1); 4839 if (!Arg->isIntegerConstantExpr(Result, getContext())) 4840 return nullptr; 4841 4842 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 4843 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 4844 // Determine the overloaded type of this builtin. 4845 llvm::Type *Ty; 4846 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 4847 Ty = FloatTy; 4848 else 4849 Ty = DoubleTy; 4850 4851 // Determine whether this is an unsigned conversion or not. 4852 bool usgn = Result.getZExtValue() == 1; 4853 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 4854 4855 // Call the appropriate intrinsic. 4856 Function *F = CGM.getIntrinsic(Int, Ty); 4857 return Builder.CreateCall(F, Ops, "vcvtr"); 4858 } 4859 4860 // Determine the type of this overloaded NEON intrinsic. 4861 NeonTypeFlags Type(Result.getZExtValue()); 4862 bool usgn = Type.isUnsigned(); 4863 bool rightShift = false; 4864 4865 llvm::VectorType *VTy = GetNeonType(this, Type); 4866 llvm::Type *Ty = VTy; 4867 if (!Ty) 4868 return nullptr; 4869 4870 // Many NEON builtins have identical semantics and uses in ARM and 4871 // AArch64. Emit these in a single function. 4872 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap); 4873 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 4874 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); 4875 if (Builtin) 4876 return EmitCommonNeonBuiltinExpr( 4877 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 4878 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1); 4879 4880 unsigned Int; 4881 switch (BuiltinID) { 4882 default: return nullptr; 4883 case NEON::BI__builtin_neon_vld1q_lane_v: 4884 // Handle 64-bit integer elements as a special case. Use shuffles of 4885 // one-element vectors to avoid poor code for i64 in the backend. 4886 if (VTy->getElementType()->isIntegerTy(64)) { 4887 // Extract the other lane. 4888 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4889 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 4890 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 4891 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 4892 // Load the value as a one-element vector. 4893 Ty = llvm::VectorType::get(VTy->getElementType(), 1); 4894 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4895 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys); 4896 Value *Align = getAlignmentValue32(PtrOp0); 4897 Value *Ld = Builder.CreateCall(F, {Ops[0], Align}); 4898 // Combine them. 4899 uint32_t Indices[] = {1 - Lane, Lane}; 4900 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices); 4901 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 4902 } 4903 // fall through 4904 case NEON::BI__builtin_neon_vld1_lane_v: { 4905 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4906 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType()); 4907 Value *Ld = Builder.CreateLoad(PtrOp0); 4908 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 4909 } 4910 case NEON::BI__builtin_neon_vld2_dup_v: 4911 case NEON::BI__builtin_neon_vld3_dup_v: 4912 case NEON::BI__builtin_neon_vld4_dup_v: { 4913 // Handle 64-bit elements as a special-case. There is no "dup" needed. 4914 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 4915 switch (BuiltinID) { 4916 case NEON::BI__builtin_neon_vld2_dup_v: 4917 Int = Intrinsic::arm_neon_vld2; 4918 break; 4919 case NEON::BI__builtin_neon_vld3_dup_v: 4920 Int = Intrinsic::arm_neon_vld3; 4921 break; 4922 case NEON::BI__builtin_neon_vld4_dup_v: 4923 Int = Intrinsic::arm_neon_vld4; 4924 break; 4925 default: llvm_unreachable("unknown vld_dup intrinsic?"); 4926 } 4927 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4928 Function *F = CGM.getIntrinsic(Int, Tys); 4929 llvm::Value *Align = getAlignmentValue32(PtrOp1); 4930 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup"); 4931 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4932 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4933 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4934 } 4935 switch (BuiltinID) { 4936 case NEON::BI__builtin_neon_vld2_dup_v: 4937 Int = Intrinsic::arm_neon_vld2lane; 4938 break; 4939 case NEON::BI__builtin_neon_vld3_dup_v: 4940 Int = Intrinsic::arm_neon_vld3lane; 4941 break; 4942 case NEON::BI__builtin_neon_vld4_dup_v: 4943 Int = Intrinsic::arm_neon_vld4lane; 4944 break; 4945 default: llvm_unreachable("unknown vld_dup intrinsic?"); 4946 } 4947 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4948 Function *F = CGM.getIntrinsic(Int, Tys); 4949 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 4950 4951 SmallVector<Value*, 6> Args; 4952 Args.push_back(Ops[1]); 4953 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 4954 4955 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 4956 Args.push_back(CI); 4957 Args.push_back(getAlignmentValue32(PtrOp1)); 4958 4959 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 4960 // splat lane 0 to all elts in each vector of the result. 4961 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 4962 Value *Val = Builder.CreateExtractValue(Ops[1], i); 4963 Value *Elt = Builder.CreateBitCast(Val, Ty); 4964 Elt = EmitNeonSplat(Elt, CI); 4965 Elt = Builder.CreateBitCast(Elt, Val->getType()); 4966 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 4967 } 4968 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4969 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4970 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4971 } 4972 case NEON::BI__builtin_neon_vqrshrn_n_v: 4973 Int = 4974 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 4975 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 4976 1, true); 4977 case NEON::BI__builtin_neon_vqrshrun_n_v: 4978 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 4979 Ops, "vqrshrun_n", 1, true); 4980 case NEON::BI__builtin_neon_vqshrn_n_v: 4981 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 4982 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 4983 1, true); 4984 case NEON::BI__builtin_neon_vqshrun_n_v: 4985 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 4986 Ops, "vqshrun_n", 1, true); 4987 case NEON::BI__builtin_neon_vrecpe_v: 4988 case NEON::BI__builtin_neon_vrecpeq_v: 4989 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 4990 Ops, "vrecpe"); 4991 case NEON::BI__builtin_neon_vrshrn_n_v: 4992 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 4993 Ops, "vrshrn_n", 1, true); 4994 case NEON::BI__builtin_neon_vrsra_n_v: 4995 case NEON::BI__builtin_neon_vrsraq_n_v: 4996 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4997 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4998 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 4999 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 5000 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]}); 5001 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 5002 case NEON::BI__builtin_neon_vsri_n_v: 5003 case NEON::BI__builtin_neon_vsriq_n_v: 5004 rightShift = true; 5005 case NEON::BI__builtin_neon_vsli_n_v: 5006 case NEON::BI__builtin_neon_vsliq_n_v: 5007 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 5008 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 5009 Ops, "vsli_n"); 5010 case NEON::BI__builtin_neon_vsra_n_v: 5011 case NEON::BI__builtin_neon_vsraq_n_v: 5012 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5013 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 5014 return Builder.CreateAdd(Ops[0], Ops[1]); 5015 case NEON::BI__builtin_neon_vst1q_lane_v: 5016 // Handle 64-bit integer elements as a special case. Use a shuffle to get 5017 // a one-element vector and avoid poor code for i64 in the backend. 5018 if (VTy->getElementType()->isIntegerTy(64)) { 5019 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5020 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 5021 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5022 Ops[2] = getAlignmentValue32(PtrOp0); 5023 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()}; 5024 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 5025 Tys), Ops); 5026 } 5027 // fall through 5028 case NEON::BI__builtin_neon_vst1_lane_v: { 5029 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5030 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 5031 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5032 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty)); 5033 return St; 5034 } 5035 case NEON::BI__builtin_neon_vtbl1_v: 5036 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 5037 Ops, "vtbl1"); 5038 case NEON::BI__builtin_neon_vtbl2_v: 5039 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 5040 Ops, "vtbl2"); 5041 case NEON::BI__builtin_neon_vtbl3_v: 5042 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 5043 Ops, "vtbl3"); 5044 case NEON::BI__builtin_neon_vtbl4_v: 5045 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 5046 Ops, "vtbl4"); 5047 case NEON::BI__builtin_neon_vtbx1_v: 5048 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 5049 Ops, "vtbx1"); 5050 case NEON::BI__builtin_neon_vtbx2_v: 5051 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 5052 Ops, "vtbx2"); 5053 case NEON::BI__builtin_neon_vtbx3_v: 5054 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 5055 Ops, "vtbx3"); 5056 case NEON::BI__builtin_neon_vtbx4_v: 5057 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 5058 Ops, "vtbx4"); 5059 } 5060 } 5061 5062 static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID, 5063 const CallExpr *E, 5064 SmallVectorImpl<Value *> &Ops) { 5065 unsigned int Int = 0; 5066 const char *s = nullptr; 5067 5068 switch (BuiltinID) { 5069 default: 5070 return nullptr; 5071 case NEON::BI__builtin_neon_vtbl1_v: 5072 case NEON::BI__builtin_neon_vqtbl1_v: 5073 case NEON::BI__builtin_neon_vqtbl1q_v: 5074 case NEON::BI__builtin_neon_vtbl2_v: 5075 case NEON::BI__builtin_neon_vqtbl2_v: 5076 case NEON::BI__builtin_neon_vqtbl2q_v: 5077 case NEON::BI__builtin_neon_vtbl3_v: 5078 case NEON::BI__builtin_neon_vqtbl3_v: 5079 case NEON::BI__builtin_neon_vqtbl3q_v: 5080 case NEON::BI__builtin_neon_vtbl4_v: 5081 case NEON::BI__builtin_neon_vqtbl4_v: 5082 case NEON::BI__builtin_neon_vqtbl4q_v: 5083 break; 5084 case NEON::BI__builtin_neon_vtbx1_v: 5085 case NEON::BI__builtin_neon_vqtbx1_v: 5086 case NEON::BI__builtin_neon_vqtbx1q_v: 5087 case NEON::BI__builtin_neon_vtbx2_v: 5088 case NEON::BI__builtin_neon_vqtbx2_v: 5089 case NEON::BI__builtin_neon_vqtbx2q_v: 5090 case NEON::BI__builtin_neon_vtbx3_v: 5091 case NEON::BI__builtin_neon_vqtbx3_v: 5092 case NEON::BI__builtin_neon_vqtbx3q_v: 5093 case NEON::BI__builtin_neon_vtbx4_v: 5094 case NEON::BI__builtin_neon_vqtbx4_v: 5095 case NEON::BI__builtin_neon_vqtbx4q_v: 5096 break; 5097 } 5098 5099 assert(E->getNumArgs() >= 3); 5100 5101 // Get the last argument, which specifies the vector type. 5102 llvm::APSInt Result; 5103 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 5104 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) 5105 return nullptr; 5106 5107 // Determine the type of this overloaded NEON intrinsic. 5108 NeonTypeFlags Type(Result.getZExtValue()); 5109 llvm::VectorType *Ty = GetNeonType(&CGF, Type); 5110 if (!Ty) 5111 return nullptr; 5112 5113 CodeGen::CGBuilderTy &Builder = CGF.Builder; 5114 5115 // AArch64 scalar builtins are not overloaded, they do not have an extra 5116 // argument that specifies the vector type, need to handle each case. 5117 switch (BuiltinID) { 5118 case NEON::BI__builtin_neon_vtbl1_v: { 5119 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr, 5120 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1, 5121 "vtbl1"); 5122 } 5123 case NEON::BI__builtin_neon_vtbl2_v: { 5124 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr, 5125 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1, 5126 "vtbl1"); 5127 } 5128 case NEON::BI__builtin_neon_vtbl3_v: { 5129 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr, 5130 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2, 5131 "vtbl2"); 5132 } 5133 case NEON::BI__builtin_neon_vtbl4_v: { 5134 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr, 5135 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2, 5136 "vtbl2"); 5137 } 5138 case NEON::BI__builtin_neon_vtbx1_v: { 5139 Value *TblRes = 5140 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2], 5141 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1"); 5142 5143 llvm::Constant *EightV = ConstantInt::get(Ty, 8); 5144 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); 5145 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5146 5147 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5148 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5149 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5150 } 5151 case NEON::BI__builtin_neon_vtbx2_v: { 5152 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0], 5153 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1, 5154 "vtbx1"); 5155 } 5156 case NEON::BI__builtin_neon_vtbx3_v: { 5157 Value *TblRes = 5158 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4], 5159 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2"); 5160 5161 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24); 5162 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], 5163 TwentyFourV); 5164 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5165 5166 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5167 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5168 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5169 } 5170 case NEON::BI__builtin_neon_vtbx4_v: { 5171 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0], 5172 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2, 5173 "vtbx2"); 5174 } 5175 case NEON::BI__builtin_neon_vqtbl1_v: 5176 case NEON::BI__builtin_neon_vqtbl1q_v: 5177 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break; 5178 case NEON::BI__builtin_neon_vqtbl2_v: 5179 case NEON::BI__builtin_neon_vqtbl2q_v: { 5180 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break; 5181 case NEON::BI__builtin_neon_vqtbl3_v: 5182 case NEON::BI__builtin_neon_vqtbl3q_v: 5183 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break; 5184 case NEON::BI__builtin_neon_vqtbl4_v: 5185 case NEON::BI__builtin_neon_vqtbl4q_v: 5186 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break; 5187 case NEON::BI__builtin_neon_vqtbx1_v: 5188 case NEON::BI__builtin_neon_vqtbx1q_v: 5189 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break; 5190 case NEON::BI__builtin_neon_vqtbx2_v: 5191 case NEON::BI__builtin_neon_vqtbx2q_v: 5192 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break; 5193 case NEON::BI__builtin_neon_vqtbx3_v: 5194 case NEON::BI__builtin_neon_vqtbx3q_v: 5195 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break; 5196 case NEON::BI__builtin_neon_vqtbx4_v: 5197 case NEON::BI__builtin_neon_vqtbx4q_v: 5198 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break; 5199 } 5200 } 5201 5202 if (!Int) 5203 return nullptr; 5204 5205 Function *F = CGF.CGM.getIntrinsic(Int, Ty); 5206 return CGF.EmitNeonCall(F, Ops, s); 5207 } 5208 5209 Value *CodeGenFunction::vectorWrapScalar16(Value *Op) { 5210 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4); 5211 Op = Builder.CreateBitCast(Op, Int16Ty); 5212 Value *V = UndefValue::get(VTy); 5213 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 5214 Op = Builder.CreateInsertElement(V, Op, CI); 5215 return Op; 5216 } 5217 5218 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 5219 const CallExpr *E) { 5220 unsigned HintID = static_cast<unsigned>(-1); 5221 switch (BuiltinID) { 5222 default: break; 5223 case AArch64::BI__builtin_arm_nop: 5224 HintID = 0; 5225 break; 5226 case AArch64::BI__builtin_arm_yield: 5227 HintID = 1; 5228 break; 5229 case AArch64::BI__builtin_arm_wfe: 5230 HintID = 2; 5231 break; 5232 case AArch64::BI__builtin_arm_wfi: 5233 HintID = 3; 5234 break; 5235 case AArch64::BI__builtin_arm_sev: 5236 HintID = 4; 5237 break; 5238 case AArch64::BI__builtin_arm_sevl: 5239 HintID = 5; 5240 break; 5241 } 5242 5243 if (HintID != static_cast<unsigned>(-1)) { 5244 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint); 5245 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); 5246 } 5247 5248 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { 5249 Value *Address = EmitScalarExpr(E->getArg(0)); 5250 Value *RW = EmitScalarExpr(E->getArg(1)); 5251 Value *CacheLevel = EmitScalarExpr(E->getArg(2)); 5252 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3)); 5253 Value *IsData = EmitScalarExpr(E->getArg(4)); 5254 5255 Value *Locality = nullptr; 5256 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) { 5257 // Temporal fetch, needs to convert cache level to locality. 5258 Locality = llvm::ConstantInt::get(Int32Ty, 5259 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3); 5260 } else { 5261 // Streaming fetch. 5262 Locality = llvm::ConstantInt::get(Int32Ty, 0); 5263 } 5264 5265 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify 5266 // PLDL3STRM or PLDL2STRM. 5267 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 5268 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 5269 } 5270 5271 if (BuiltinID == AArch64::BI__builtin_arm_rbit) { 5272 assert((getContext().getTypeSize(E->getType()) == 32) && 5273 "rbit of unusual size!"); 5274 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5275 return Builder.CreateCall( 5276 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5277 } 5278 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) { 5279 assert((getContext().getTypeSize(E->getType()) == 64) && 5280 "rbit of unusual size!"); 5281 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5282 return Builder.CreateCall( 5283 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5284 } 5285 5286 if (BuiltinID == AArch64::BI__clear_cache) { 5287 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 5288 const FunctionDecl *FD = E->getDirectCallee(); 5289 Value *Ops[2]; 5290 for (unsigned i = 0; i < 2; i++) 5291 Ops[i] = EmitScalarExpr(E->getArg(i)); 5292 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 5293 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 5294 StringRef Name = FD->getName(); 5295 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 5296 } 5297 5298 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex || 5299 BuiltinID == AArch64::BI__builtin_arm_ldaex) && 5300 getContext().getTypeSize(E->getType()) == 128) { 5301 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5302 ? Intrinsic::aarch64_ldaxp 5303 : Intrinsic::aarch64_ldxp); 5304 5305 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 5306 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 5307 "ldxp"); 5308 5309 Value *Val0 = Builder.CreateExtractValue(Val, 1); 5310 Value *Val1 = Builder.CreateExtractValue(Val, 0); 5311 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 5312 Val0 = Builder.CreateZExt(Val0, Int128Ty); 5313 Val1 = Builder.CreateZExt(Val1, Int128Ty); 5314 5315 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64); 5316 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 5317 Val = Builder.CreateOr(Val, Val1); 5318 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 5319 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex || 5320 BuiltinID == AArch64::BI__builtin_arm_ldaex) { 5321 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 5322 5323 QualType Ty = E->getType(); 5324 llvm::Type *RealResTy = ConvertType(Ty); 5325 llvm::Type *PtrTy = llvm::IntegerType::get( 5326 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 5327 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 5328 5329 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5330 ? Intrinsic::aarch64_ldaxr 5331 : Intrinsic::aarch64_ldxr, 5332 PtrTy); 5333 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr"); 5334 5335 if (RealResTy->isPointerTy()) 5336 return Builder.CreateIntToPtr(Val, RealResTy); 5337 5338 llvm::Type *IntResTy = llvm::IntegerType::get( 5339 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 5340 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 5341 return Builder.CreateBitCast(Val, RealResTy); 5342 } 5343 5344 if ((BuiltinID == AArch64::BI__builtin_arm_strex || 5345 BuiltinID == AArch64::BI__builtin_arm_stlex) && 5346 getContext().getTypeSize(E->getArg(0)->getType()) == 128) { 5347 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5348 ? Intrinsic::aarch64_stlxp 5349 : Intrinsic::aarch64_stxp); 5350 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty, nullptr); 5351 5352 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 5353 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true); 5354 5355 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy)); 5356 llvm::Value *Val = Builder.CreateLoad(Tmp); 5357 5358 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 5359 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 5360 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), 5361 Int8PtrTy); 5362 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp"); 5363 } 5364 5365 if (BuiltinID == AArch64::BI__builtin_arm_strex || 5366 BuiltinID == AArch64::BI__builtin_arm_stlex) { 5367 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 5368 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 5369 5370 QualType Ty = E->getArg(0)->getType(); 5371 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 5372 getContext().getTypeSize(Ty)); 5373 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 5374 5375 if (StoreVal->getType()->isPointerTy()) 5376 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty); 5377 else { 5378 llvm::Type *IntTy = llvm::IntegerType::get( 5379 getLLVMContext(), 5380 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 5381 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 5382 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty); 5383 } 5384 5385 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5386 ? Intrinsic::aarch64_stlxr 5387 : Intrinsic::aarch64_stxr, 5388 StoreAddr->getType()); 5389 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr"); 5390 } 5391 5392 if (BuiltinID == AArch64::BI__builtin_arm_clrex) { 5393 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex); 5394 return Builder.CreateCall(F); 5395 } 5396 5397 // CRC32 5398 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 5399 switch (BuiltinID) { 5400 case AArch64::BI__builtin_arm_crc32b: 5401 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break; 5402 case AArch64::BI__builtin_arm_crc32cb: 5403 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break; 5404 case AArch64::BI__builtin_arm_crc32h: 5405 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break; 5406 case AArch64::BI__builtin_arm_crc32ch: 5407 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break; 5408 case AArch64::BI__builtin_arm_crc32w: 5409 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break; 5410 case AArch64::BI__builtin_arm_crc32cw: 5411 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break; 5412 case AArch64::BI__builtin_arm_crc32d: 5413 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break; 5414 case AArch64::BI__builtin_arm_crc32cd: 5415 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break; 5416 } 5417 5418 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 5419 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 5420 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 5421 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 5422 5423 llvm::Type *DataTy = F->getFunctionType()->getParamType(1); 5424 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy); 5425 5426 return Builder.CreateCall(F, {Arg0, Arg1}); 5427 } 5428 5429 if (BuiltinID == AArch64::BI__builtin_arm_rsr || 5430 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5431 BuiltinID == AArch64::BI__builtin_arm_rsrp || 5432 BuiltinID == AArch64::BI__builtin_arm_wsr || 5433 BuiltinID == AArch64::BI__builtin_arm_wsr64 || 5434 BuiltinID == AArch64::BI__builtin_arm_wsrp) { 5435 5436 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr || 5437 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5438 BuiltinID == AArch64::BI__builtin_arm_rsrp; 5439 5440 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp || 5441 BuiltinID == AArch64::BI__builtin_arm_wsrp; 5442 5443 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr && 5444 BuiltinID != AArch64::BI__builtin_arm_wsr; 5445 5446 llvm::Type *ValueType; 5447 llvm::Type *RegisterType = Int64Ty; 5448 if (IsPointerBuiltin) { 5449 ValueType = VoidPtrTy; 5450 } else if (Is64Bit) { 5451 ValueType = Int64Ty; 5452 } else { 5453 ValueType = Int32Ty; 5454 } 5455 5456 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 5457 } 5458 5459 // Find out if any arguments are required to be integer constant 5460 // expressions. 5461 unsigned ICEArguments = 0; 5462 ASTContext::GetBuiltinTypeError Error; 5463 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 5464 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 5465 5466 llvm::SmallVector<Value*, 4> Ops; 5467 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 5468 if ((ICEArguments & (1 << i)) == 0) { 5469 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5470 } else { 5471 // If this is required to be a constant, constant fold it so that we know 5472 // that the generated intrinsic gets a ConstantInt. 5473 llvm::APSInt Result; 5474 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5475 assert(IsConst && "Constant arg isn't actually constant?"); 5476 (void)IsConst; 5477 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5478 } 5479 } 5480 5481 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap); 5482 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5483 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted); 5484 5485 if (Builtin) { 5486 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1))); 5487 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E); 5488 assert(Result && "SISD intrinsic should have been handled"); 5489 return Result; 5490 } 5491 5492 llvm::APSInt Result; 5493 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5494 NeonTypeFlags Type(0); 5495 if (Arg->isIntegerConstantExpr(Result, getContext())) 5496 // Determine the type of this overloaded NEON intrinsic. 5497 Type = NeonTypeFlags(Result.getZExtValue()); 5498 5499 bool usgn = Type.isUnsigned(); 5500 bool quad = Type.isQuad(); 5501 5502 // Handle non-overloaded intrinsics first. 5503 switch (BuiltinID) { 5504 default: break; 5505 case NEON::BI__builtin_neon_vldrq_p128: { 5506 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128); 5507 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0); 5508 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy); 5509 return Builder.CreateAlignedLoad(Int128Ty, Ptr, 5510 CharUnits::fromQuantity(16)); 5511 } 5512 case NEON::BI__builtin_neon_vstrq_p128: { 5513 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128); 5514 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy); 5515 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr); 5516 } 5517 case NEON::BI__builtin_neon_vcvts_u32_f32: 5518 case NEON::BI__builtin_neon_vcvtd_u64_f64: 5519 usgn = true; 5520 // FALL THROUGH 5521 case NEON::BI__builtin_neon_vcvts_s32_f32: 5522 case NEON::BI__builtin_neon_vcvtd_s64_f64: { 5523 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5524 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5525 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5526 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5527 Ops[0] = Builder.CreateBitCast(Ops[0], FTy); 5528 if (usgn) 5529 return Builder.CreateFPToUI(Ops[0], InTy); 5530 return Builder.CreateFPToSI(Ops[0], InTy); 5531 } 5532 case NEON::BI__builtin_neon_vcvts_f32_u32: 5533 case NEON::BI__builtin_neon_vcvtd_f64_u64: 5534 usgn = true; 5535 // FALL THROUGH 5536 case NEON::BI__builtin_neon_vcvts_f32_s32: 5537 case NEON::BI__builtin_neon_vcvtd_f64_s64: { 5538 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5539 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5540 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5541 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5542 Ops[0] = Builder.CreateBitCast(Ops[0], InTy); 5543 if (usgn) 5544 return Builder.CreateUIToFP(Ops[0], FTy); 5545 return Builder.CreateSIToFP(Ops[0], FTy); 5546 } 5547 case NEON::BI__builtin_neon_vpaddd_s64: { 5548 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2); 5549 Value *Vec = EmitScalarExpr(E->getArg(0)); 5550 // The vector is v2f64, so make sure it's bitcast to that. 5551 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64"); 5552 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5553 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5554 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5555 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5556 // Pairwise addition of a v2f64 into a scalar f64. 5557 return Builder.CreateAdd(Op0, Op1, "vpaddd"); 5558 } 5559 case NEON::BI__builtin_neon_vpaddd_f64: { 5560 llvm::Type *Ty = 5561 llvm::VectorType::get(DoubleTy, 2); 5562 Value *Vec = EmitScalarExpr(E->getArg(0)); 5563 // The vector is v2f64, so make sure it's bitcast to that. 5564 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64"); 5565 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5566 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5567 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5568 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5569 // Pairwise addition of a v2f64 into a scalar f64. 5570 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5571 } 5572 case NEON::BI__builtin_neon_vpadds_f32: { 5573 llvm::Type *Ty = 5574 llvm::VectorType::get(FloatTy, 2); 5575 Value *Vec = EmitScalarExpr(E->getArg(0)); 5576 // The vector is v2f32, so make sure it's bitcast to that. 5577 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32"); 5578 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5579 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5580 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5581 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5582 // Pairwise addition of a v2f32 into a scalar f32. 5583 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5584 } 5585 case NEON::BI__builtin_neon_vceqzd_s64: 5586 case NEON::BI__builtin_neon_vceqzd_f64: 5587 case NEON::BI__builtin_neon_vceqzs_f32: 5588 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5589 return EmitAArch64CompareBuiltinExpr( 5590 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5591 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz"); 5592 case NEON::BI__builtin_neon_vcgezd_s64: 5593 case NEON::BI__builtin_neon_vcgezd_f64: 5594 case NEON::BI__builtin_neon_vcgezs_f32: 5595 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5596 return EmitAArch64CompareBuiltinExpr( 5597 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5598 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez"); 5599 case NEON::BI__builtin_neon_vclezd_s64: 5600 case NEON::BI__builtin_neon_vclezd_f64: 5601 case NEON::BI__builtin_neon_vclezs_f32: 5602 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5603 return EmitAArch64CompareBuiltinExpr( 5604 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5605 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez"); 5606 case NEON::BI__builtin_neon_vcgtzd_s64: 5607 case NEON::BI__builtin_neon_vcgtzd_f64: 5608 case NEON::BI__builtin_neon_vcgtzs_f32: 5609 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5610 return EmitAArch64CompareBuiltinExpr( 5611 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5612 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz"); 5613 case NEON::BI__builtin_neon_vcltzd_s64: 5614 case NEON::BI__builtin_neon_vcltzd_f64: 5615 case NEON::BI__builtin_neon_vcltzs_f32: 5616 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5617 return EmitAArch64CompareBuiltinExpr( 5618 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5619 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz"); 5620 5621 case NEON::BI__builtin_neon_vceqzd_u64: { 5622 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5623 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 5624 Ops[0] = 5625 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty)); 5626 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd"); 5627 } 5628 case NEON::BI__builtin_neon_vceqd_f64: 5629 case NEON::BI__builtin_neon_vcled_f64: 5630 case NEON::BI__builtin_neon_vcltd_f64: 5631 case NEON::BI__builtin_neon_vcged_f64: 5632 case NEON::BI__builtin_neon_vcgtd_f64: { 5633 llvm::CmpInst::Predicate P; 5634 switch (BuiltinID) { 5635 default: llvm_unreachable("missing builtin ID in switch!"); 5636 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break; 5637 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break; 5638 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break; 5639 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break; 5640 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break; 5641 } 5642 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5643 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 5644 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 5645 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5646 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd"); 5647 } 5648 case NEON::BI__builtin_neon_vceqs_f32: 5649 case NEON::BI__builtin_neon_vcles_f32: 5650 case NEON::BI__builtin_neon_vclts_f32: 5651 case NEON::BI__builtin_neon_vcges_f32: 5652 case NEON::BI__builtin_neon_vcgts_f32: { 5653 llvm::CmpInst::Predicate P; 5654 switch (BuiltinID) { 5655 default: llvm_unreachable("missing builtin ID in switch!"); 5656 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break; 5657 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break; 5658 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break; 5659 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break; 5660 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break; 5661 } 5662 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5663 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 5664 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy); 5665 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5666 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd"); 5667 } 5668 case NEON::BI__builtin_neon_vceqd_s64: 5669 case NEON::BI__builtin_neon_vceqd_u64: 5670 case NEON::BI__builtin_neon_vcgtd_s64: 5671 case NEON::BI__builtin_neon_vcgtd_u64: 5672 case NEON::BI__builtin_neon_vcltd_s64: 5673 case NEON::BI__builtin_neon_vcltd_u64: 5674 case NEON::BI__builtin_neon_vcged_u64: 5675 case NEON::BI__builtin_neon_vcged_s64: 5676 case NEON::BI__builtin_neon_vcled_u64: 5677 case NEON::BI__builtin_neon_vcled_s64: { 5678 llvm::CmpInst::Predicate P; 5679 switch (BuiltinID) { 5680 default: llvm_unreachable("missing builtin ID in switch!"); 5681 case NEON::BI__builtin_neon_vceqd_s64: 5682 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break; 5683 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break; 5684 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break; 5685 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break; 5686 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break; 5687 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break; 5688 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break; 5689 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break; 5690 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break; 5691 } 5692 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5693 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 5694 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 5695 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]); 5696 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd"); 5697 } 5698 case NEON::BI__builtin_neon_vtstd_s64: 5699 case NEON::BI__builtin_neon_vtstd_u64: { 5700 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5701 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 5702 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 5703 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 5704 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 5705 llvm::Constant::getNullValue(Int64Ty)); 5706 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd"); 5707 } 5708 case NEON::BI__builtin_neon_vset_lane_i8: 5709 case NEON::BI__builtin_neon_vset_lane_i16: 5710 case NEON::BI__builtin_neon_vset_lane_i32: 5711 case NEON::BI__builtin_neon_vset_lane_i64: 5712 case NEON::BI__builtin_neon_vset_lane_f32: 5713 case NEON::BI__builtin_neon_vsetq_lane_i8: 5714 case NEON::BI__builtin_neon_vsetq_lane_i16: 5715 case NEON::BI__builtin_neon_vsetq_lane_i32: 5716 case NEON::BI__builtin_neon_vsetq_lane_i64: 5717 case NEON::BI__builtin_neon_vsetq_lane_f32: 5718 Ops.push_back(EmitScalarExpr(E->getArg(2))); 5719 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 5720 case NEON::BI__builtin_neon_vset_lane_f64: 5721 // The vector type needs a cast for the v1f64 variant. 5722 Ops[1] = Builder.CreateBitCast(Ops[1], 5723 llvm::VectorType::get(DoubleTy, 1)); 5724 Ops.push_back(EmitScalarExpr(E->getArg(2))); 5725 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 5726 case NEON::BI__builtin_neon_vsetq_lane_f64: 5727 // The vector type needs a cast for the v2f64 variant. 5728 Ops[1] = Builder.CreateBitCast(Ops[1], 5729 llvm::VectorType::get(DoubleTy, 2)); 5730 Ops.push_back(EmitScalarExpr(E->getArg(2))); 5731 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 5732 5733 case NEON::BI__builtin_neon_vget_lane_i8: 5734 case NEON::BI__builtin_neon_vdupb_lane_i8: 5735 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8)); 5736 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5737 "vget_lane"); 5738 case NEON::BI__builtin_neon_vgetq_lane_i8: 5739 case NEON::BI__builtin_neon_vdupb_laneq_i8: 5740 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16)); 5741 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5742 "vgetq_lane"); 5743 case NEON::BI__builtin_neon_vget_lane_i16: 5744 case NEON::BI__builtin_neon_vduph_lane_i16: 5745 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4)); 5746 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5747 "vget_lane"); 5748 case NEON::BI__builtin_neon_vgetq_lane_i16: 5749 case NEON::BI__builtin_neon_vduph_laneq_i16: 5750 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8)); 5751 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5752 "vgetq_lane"); 5753 case NEON::BI__builtin_neon_vget_lane_i32: 5754 case NEON::BI__builtin_neon_vdups_lane_i32: 5755 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2)); 5756 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5757 "vget_lane"); 5758 case NEON::BI__builtin_neon_vdups_lane_f32: 5759 Ops[0] = Builder.CreateBitCast(Ops[0], 5760 llvm::VectorType::get(FloatTy, 2)); 5761 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5762 "vdups_lane"); 5763 case NEON::BI__builtin_neon_vgetq_lane_i32: 5764 case NEON::BI__builtin_neon_vdups_laneq_i32: 5765 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 5766 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5767 "vgetq_lane"); 5768 case NEON::BI__builtin_neon_vget_lane_i64: 5769 case NEON::BI__builtin_neon_vdupd_lane_i64: 5770 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1)); 5771 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5772 "vget_lane"); 5773 case NEON::BI__builtin_neon_vdupd_lane_f64: 5774 Ops[0] = Builder.CreateBitCast(Ops[0], 5775 llvm::VectorType::get(DoubleTy, 1)); 5776 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5777 "vdupd_lane"); 5778 case NEON::BI__builtin_neon_vgetq_lane_i64: 5779 case NEON::BI__builtin_neon_vdupd_laneq_i64: 5780 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 5781 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5782 "vgetq_lane"); 5783 case NEON::BI__builtin_neon_vget_lane_f32: 5784 Ops[0] = Builder.CreateBitCast(Ops[0], 5785 llvm::VectorType::get(FloatTy, 2)); 5786 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5787 "vget_lane"); 5788 case NEON::BI__builtin_neon_vget_lane_f64: 5789 Ops[0] = Builder.CreateBitCast(Ops[0], 5790 llvm::VectorType::get(DoubleTy, 1)); 5791 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5792 "vget_lane"); 5793 case NEON::BI__builtin_neon_vgetq_lane_f32: 5794 case NEON::BI__builtin_neon_vdups_laneq_f32: 5795 Ops[0] = Builder.CreateBitCast(Ops[0], 5796 llvm::VectorType::get(FloatTy, 4)); 5797 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5798 "vgetq_lane"); 5799 case NEON::BI__builtin_neon_vgetq_lane_f64: 5800 case NEON::BI__builtin_neon_vdupd_laneq_f64: 5801 Ops[0] = Builder.CreateBitCast(Ops[0], 5802 llvm::VectorType::get(DoubleTy, 2)); 5803 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 5804 "vgetq_lane"); 5805 case NEON::BI__builtin_neon_vaddd_s64: 5806 case NEON::BI__builtin_neon_vaddd_u64: 5807 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd"); 5808 case NEON::BI__builtin_neon_vsubd_s64: 5809 case NEON::BI__builtin_neon_vsubd_u64: 5810 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd"); 5811 case NEON::BI__builtin_neon_vqdmlalh_s16: 5812 case NEON::BI__builtin_neon_vqdmlslh_s16: { 5813 SmallVector<Value *, 2> ProductOps; 5814 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 5815 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2)))); 5816 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 5817 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 5818 ProductOps, "vqdmlXl"); 5819 Constant *CI = ConstantInt::get(SizeTy, 0); 5820 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 5821 5822 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16 5823 ? Intrinsic::aarch64_neon_sqadd 5824 : Intrinsic::aarch64_neon_sqsub; 5825 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl"); 5826 } 5827 case NEON::BI__builtin_neon_vqshlud_n_s64: { 5828 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5829 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 5830 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty), 5831 Ops, "vqshlu_n"); 5832 } 5833 case NEON::BI__builtin_neon_vqshld_n_u64: 5834 case NEON::BI__builtin_neon_vqshld_n_s64: { 5835 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64 5836 ? Intrinsic::aarch64_neon_uqshl 5837 : Intrinsic::aarch64_neon_sqshl; 5838 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5839 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 5840 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n"); 5841 } 5842 case NEON::BI__builtin_neon_vrshrd_n_u64: 5843 case NEON::BI__builtin_neon_vrshrd_n_s64: { 5844 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64 5845 ? Intrinsic::aarch64_neon_urshl 5846 : Intrinsic::aarch64_neon_srshl; 5847 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5848 int SV = cast<ConstantInt>(Ops[1])->getSExtValue(); 5849 Ops[1] = ConstantInt::get(Int64Ty, -SV); 5850 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n"); 5851 } 5852 case NEON::BI__builtin_neon_vrsrad_n_u64: 5853 case NEON::BI__builtin_neon_vrsrad_n_s64: { 5854 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64 5855 ? Intrinsic::aarch64_neon_urshl 5856 : Intrinsic::aarch64_neon_srshl; 5857 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 5858 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2)))); 5859 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty), 5860 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)}); 5861 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty)); 5862 } 5863 case NEON::BI__builtin_neon_vshld_n_s64: 5864 case NEON::BI__builtin_neon_vshld_n_u64: { 5865 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 5866 return Builder.CreateShl( 5867 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n"); 5868 } 5869 case NEON::BI__builtin_neon_vshrd_n_s64: { 5870 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 5871 return Builder.CreateAShr( 5872 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 5873 Amt->getZExtValue())), 5874 "shrd_n"); 5875 } 5876 case NEON::BI__builtin_neon_vshrd_n_u64: { 5877 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 5878 uint64_t ShiftAmt = Amt->getZExtValue(); 5879 // Right-shifting an unsigned value by its size yields 0. 5880 if (ShiftAmt == 64) 5881 return ConstantInt::get(Int64Ty, 0); 5882 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt), 5883 "shrd_n"); 5884 } 5885 case NEON::BI__builtin_neon_vsrad_n_s64: { 5886 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 5887 Ops[1] = Builder.CreateAShr( 5888 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 5889 Amt->getZExtValue())), 5890 "shrd_n"); 5891 return Builder.CreateAdd(Ops[0], Ops[1]); 5892 } 5893 case NEON::BI__builtin_neon_vsrad_n_u64: { 5894 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 5895 uint64_t ShiftAmt = Amt->getZExtValue(); 5896 // Right-shifting an unsigned value by its size yields 0. 5897 // As Op + 0 = Op, return Ops[0] directly. 5898 if (ShiftAmt == 64) 5899 return Ops[0]; 5900 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt), 5901 "shrd_n"); 5902 return Builder.CreateAdd(Ops[0], Ops[1]); 5903 } 5904 case NEON::BI__builtin_neon_vqdmlalh_lane_s16: 5905 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16: 5906 case NEON::BI__builtin_neon_vqdmlslh_lane_s16: 5907 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: { 5908 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 5909 "lane"); 5910 SmallVector<Value *, 2> ProductOps; 5911 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 5912 ProductOps.push_back(vectorWrapScalar16(Ops[2])); 5913 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 5914 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 5915 ProductOps, "vqdmlXl"); 5916 Constant *CI = ConstantInt::get(SizeTy, 0); 5917 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 5918 Ops.pop_back(); 5919 5920 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 || 5921 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16) 5922 ? Intrinsic::aarch64_neon_sqadd 5923 : Intrinsic::aarch64_neon_sqsub; 5924 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl"); 5925 } 5926 case NEON::BI__builtin_neon_vqdmlals_s32: 5927 case NEON::BI__builtin_neon_vqdmlsls_s32: { 5928 SmallVector<Value *, 2> ProductOps; 5929 ProductOps.push_back(Ops[1]); 5930 ProductOps.push_back(EmitScalarExpr(E->getArg(2))); 5931 Ops[1] = 5932 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 5933 ProductOps, "vqdmlXl"); 5934 5935 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32 5936 ? Intrinsic::aarch64_neon_sqadd 5937 : Intrinsic::aarch64_neon_sqsub; 5938 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl"); 5939 } 5940 case NEON::BI__builtin_neon_vqdmlals_lane_s32: 5941 case NEON::BI__builtin_neon_vqdmlals_laneq_s32: 5942 case NEON::BI__builtin_neon_vqdmlsls_lane_s32: 5943 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: { 5944 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 5945 "lane"); 5946 SmallVector<Value *, 2> ProductOps; 5947 ProductOps.push_back(Ops[1]); 5948 ProductOps.push_back(Ops[2]); 5949 Ops[1] = 5950 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 5951 ProductOps, "vqdmlXl"); 5952 Ops.pop_back(); 5953 5954 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 || 5955 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32) 5956 ? Intrinsic::aarch64_neon_sqadd 5957 : Intrinsic::aarch64_neon_sqsub; 5958 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl"); 5959 } 5960 } 5961 5962 llvm::VectorType *VTy = GetNeonType(this, Type); 5963 llvm::Type *Ty = VTy; 5964 if (!Ty) 5965 return nullptr; 5966 5967 // Not all intrinsics handled by the common case work for AArch64 yet, so only 5968 // defer to common code if it's been added to our special map. 5969 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID, 5970 AArch64SIMDIntrinsicsProvenSorted); 5971 5972 if (Builtin) 5973 return EmitCommonNeonBuiltinExpr( 5974 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 5975 Builtin->NameHint, Builtin->TypeModifier, E, Ops, 5976 /*never use addresses*/ Address::invalid(), Address::invalid()); 5977 5978 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops)) 5979 return V; 5980 5981 unsigned Int; 5982 switch (BuiltinID) { 5983 default: return nullptr; 5984 case NEON::BI__builtin_neon_vbsl_v: 5985 case NEON::BI__builtin_neon_vbslq_v: { 5986 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy); 5987 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl"); 5988 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl"); 5989 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl"); 5990 5991 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl"); 5992 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl"); 5993 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl"); 5994 return Builder.CreateBitCast(Ops[0], Ty); 5995 } 5996 case NEON::BI__builtin_neon_vfma_lane_v: 5997 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types 5998 // The ARM builtins (and instructions) have the addend as the first 5999 // operand, but the 'fma' intrinsics have it last. Swap it around here. 6000 Value *Addend = Ops[0]; 6001 Value *Multiplicand = Ops[1]; 6002 Value *LaneSource = Ops[2]; 6003 Ops[0] = Multiplicand; 6004 Ops[1] = LaneSource; 6005 Ops[2] = Addend; 6006 6007 // Now adjust things to handle the lane access. 6008 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ? 6009 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) : 6010 VTy; 6011 llvm::Constant *cst = cast<Constant>(Ops[3]); 6012 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst); 6013 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy); 6014 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane"); 6015 6016 Ops.pop_back(); 6017 Int = Intrinsic::fma; 6018 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla"); 6019 } 6020 case NEON::BI__builtin_neon_vfma_laneq_v: { 6021 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 6022 // v1f64 fma should be mapped to Neon scalar f64 fma 6023 if (VTy && VTy->getElementType() == DoubleTy) { 6024 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6025 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 6026 llvm::Type *VTy = GetNeonType(this, 6027 NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 6028 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 6029 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6030 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 6031 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6032 return Builder.CreateBitCast(Result, Ty); 6033 } 6034 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6035 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6036 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6037 6038 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 6039 VTy->getNumElements() * 2); 6040 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 6041 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 6042 cast<ConstantInt>(Ops[3])); 6043 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 6044 6045 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6046 } 6047 case NEON::BI__builtin_neon_vfmaq_laneq_v: { 6048 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6049 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6050 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6051 6052 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6053 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 6054 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6055 } 6056 case NEON::BI__builtin_neon_vfmas_lane_f32: 6057 case NEON::BI__builtin_neon_vfmas_laneq_f32: 6058 case NEON::BI__builtin_neon_vfmad_lane_f64: 6059 case NEON::BI__builtin_neon_vfmad_laneq_f64: { 6060 Ops.push_back(EmitScalarExpr(E->getArg(3))); 6061 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 6062 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6063 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6064 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6065 } 6066 case NEON::BI__builtin_neon_vmull_v: 6067 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6068 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull; 6069 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull; 6070 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 6071 case NEON::BI__builtin_neon_vmax_v: 6072 case NEON::BI__builtin_neon_vmaxq_v: 6073 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6074 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax; 6075 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax; 6076 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 6077 case NEON::BI__builtin_neon_vmin_v: 6078 case NEON::BI__builtin_neon_vminq_v: 6079 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6080 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin; 6081 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin; 6082 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 6083 case NEON::BI__builtin_neon_vabd_v: 6084 case NEON::BI__builtin_neon_vabdq_v: 6085 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6086 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd; 6087 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd; 6088 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 6089 case NEON::BI__builtin_neon_vpadal_v: 6090 case NEON::BI__builtin_neon_vpadalq_v: { 6091 unsigned ArgElts = VTy->getNumElements(); 6092 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType()); 6093 unsigned BitWidth = EltTy->getBitWidth(); 6094 llvm::Type *ArgTy = llvm::VectorType::get( 6095 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts); 6096 llvm::Type* Tys[2] = { VTy, ArgTy }; 6097 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp; 6098 SmallVector<llvm::Value*, 1> TmpOps; 6099 TmpOps.push_back(Ops[1]); 6100 Function *F = CGM.getIntrinsic(Int, Tys); 6101 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal"); 6102 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType()); 6103 return Builder.CreateAdd(tmp, addend); 6104 } 6105 case NEON::BI__builtin_neon_vpmin_v: 6106 case NEON::BI__builtin_neon_vpminq_v: 6107 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6108 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp; 6109 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp; 6110 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 6111 case NEON::BI__builtin_neon_vpmax_v: 6112 case NEON::BI__builtin_neon_vpmaxq_v: 6113 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6114 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp; 6115 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp; 6116 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 6117 case NEON::BI__builtin_neon_vminnm_v: 6118 case NEON::BI__builtin_neon_vminnmq_v: 6119 Int = Intrinsic::aarch64_neon_fminnm; 6120 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 6121 case NEON::BI__builtin_neon_vmaxnm_v: 6122 case NEON::BI__builtin_neon_vmaxnmq_v: 6123 Int = Intrinsic::aarch64_neon_fmaxnm; 6124 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 6125 case NEON::BI__builtin_neon_vrecpss_f32: { 6126 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6127 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy), 6128 Ops, "vrecps"); 6129 } 6130 case NEON::BI__builtin_neon_vrecpsd_f64: { 6131 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6132 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy), 6133 Ops, "vrecps"); 6134 } 6135 case NEON::BI__builtin_neon_vqshrun_n_v: 6136 Int = Intrinsic::aarch64_neon_sqshrun; 6137 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 6138 case NEON::BI__builtin_neon_vqrshrun_n_v: 6139 Int = Intrinsic::aarch64_neon_sqrshrun; 6140 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 6141 case NEON::BI__builtin_neon_vqshrn_n_v: 6142 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn; 6143 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 6144 case NEON::BI__builtin_neon_vrshrn_n_v: 6145 Int = Intrinsic::aarch64_neon_rshrn; 6146 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 6147 case NEON::BI__builtin_neon_vqrshrn_n_v: 6148 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn; 6149 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 6150 case NEON::BI__builtin_neon_vrnda_v: 6151 case NEON::BI__builtin_neon_vrndaq_v: { 6152 Int = Intrinsic::round; 6153 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); 6154 } 6155 case NEON::BI__builtin_neon_vrndi_v: 6156 case NEON::BI__builtin_neon_vrndiq_v: { 6157 Int = Intrinsic::nearbyint; 6158 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); 6159 } 6160 case NEON::BI__builtin_neon_vrndm_v: 6161 case NEON::BI__builtin_neon_vrndmq_v: { 6162 Int = Intrinsic::floor; 6163 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); 6164 } 6165 case NEON::BI__builtin_neon_vrndn_v: 6166 case NEON::BI__builtin_neon_vrndnq_v: { 6167 Int = Intrinsic::aarch64_neon_frintn; 6168 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); 6169 } 6170 case NEON::BI__builtin_neon_vrndp_v: 6171 case NEON::BI__builtin_neon_vrndpq_v: { 6172 Int = Intrinsic::ceil; 6173 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); 6174 } 6175 case NEON::BI__builtin_neon_vrndx_v: 6176 case NEON::BI__builtin_neon_vrndxq_v: { 6177 Int = Intrinsic::rint; 6178 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); 6179 } 6180 case NEON::BI__builtin_neon_vrnd_v: 6181 case NEON::BI__builtin_neon_vrndq_v: { 6182 Int = Intrinsic::trunc; 6183 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz"); 6184 } 6185 case NEON::BI__builtin_neon_vceqz_v: 6186 case NEON::BI__builtin_neon_vceqzq_v: 6187 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, 6188 ICmpInst::ICMP_EQ, "vceqz"); 6189 case NEON::BI__builtin_neon_vcgez_v: 6190 case NEON::BI__builtin_neon_vcgezq_v: 6191 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, 6192 ICmpInst::ICMP_SGE, "vcgez"); 6193 case NEON::BI__builtin_neon_vclez_v: 6194 case NEON::BI__builtin_neon_vclezq_v: 6195 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, 6196 ICmpInst::ICMP_SLE, "vclez"); 6197 case NEON::BI__builtin_neon_vcgtz_v: 6198 case NEON::BI__builtin_neon_vcgtzq_v: 6199 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, 6200 ICmpInst::ICMP_SGT, "vcgtz"); 6201 case NEON::BI__builtin_neon_vcltz_v: 6202 case NEON::BI__builtin_neon_vcltzq_v: 6203 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, 6204 ICmpInst::ICMP_SLT, "vcltz"); 6205 case NEON::BI__builtin_neon_vcvt_f64_v: 6206 case NEON::BI__builtin_neon_vcvtq_f64_v: 6207 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6208 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 6209 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 6210 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 6211 case NEON::BI__builtin_neon_vcvt_f64_f32: { 6212 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad && 6213 "unexpected vcvt_f64_f32 builtin"); 6214 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false); 6215 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6216 6217 return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); 6218 } 6219 case NEON::BI__builtin_neon_vcvt_f32_f64: { 6220 assert(Type.getEltType() == NeonTypeFlags::Float32 && 6221 "unexpected vcvt_f32_f64 builtin"); 6222 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); 6223 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6224 6225 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); 6226 } 6227 case NEON::BI__builtin_neon_vcvt_s32_v: 6228 case NEON::BI__builtin_neon_vcvt_u32_v: 6229 case NEON::BI__builtin_neon_vcvt_s64_v: 6230 case NEON::BI__builtin_neon_vcvt_u64_v: 6231 case NEON::BI__builtin_neon_vcvtq_s32_v: 6232 case NEON::BI__builtin_neon_vcvtq_u32_v: 6233 case NEON::BI__builtin_neon_vcvtq_s64_v: 6234 case NEON::BI__builtin_neon_vcvtq_u64_v: { 6235 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 6236 if (usgn) 6237 return Builder.CreateFPToUI(Ops[0], Ty); 6238 return Builder.CreateFPToSI(Ops[0], Ty); 6239 } 6240 case NEON::BI__builtin_neon_vcvta_s32_v: 6241 case NEON::BI__builtin_neon_vcvtaq_s32_v: 6242 case NEON::BI__builtin_neon_vcvta_u32_v: 6243 case NEON::BI__builtin_neon_vcvtaq_u32_v: 6244 case NEON::BI__builtin_neon_vcvta_s64_v: 6245 case NEON::BI__builtin_neon_vcvtaq_s64_v: 6246 case NEON::BI__builtin_neon_vcvta_u64_v: 6247 case NEON::BI__builtin_neon_vcvtaq_u64_v: { 6248 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas; 6249 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6250 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta"); 6251 } 6252 case NEON::BI__builtin_neon_vcvtm_s32_v: 6253 case NEON::BI__builtin_neon_vcvtmq_s32_v: 6254 case NEON::BI__builtin_neon_vcvtm_u32_v: 6255 case NEON::BI__builtin_neon_vcvtmq_u32_v: 6256 case NEON::BI__builtin_neon_vcvtm_s64_v: 6257 case NEON::BI__builtin_neon_vcvtmq_s64_v: 6258 case NEON::BI__builtin_neon_vcvtm_u64_v: 6259 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 6260 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms; 6261 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6262 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm"); 6263 } 6264 case NEON::BI__builtin_neon_vcvtn_s32_v: 6265 case NEON::BI__builtin_neon_vcvtnq_s32_v: 6266 case NEON::BI__builtin_neon_vcvtn_u32_v: 6267 case NEON::BI__builtin_neon_vcvtnq_u32_v: 6268 case NEON::BI__builtin_neon_vcvtn_s64_v: 6269 case NEON::BI__builtin_neon_vcvtnq_s64_v: 6270 case NEON::BI__builtin_neon_vcvtn_u64_v: 6271 case NEON::BI__builtin_neon_vcvtnq_u64_v: { 6272 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns; 6273 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6274 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn"); 6275 } 6276 case NEON::BI__builtin_neon_vcvtp_s32_v: 6277 case NEON::BI__builtin_neon_vcvtpq_s32_v: 6278 case NEON::BI__builtin_neon_vcvtp_u32_v: 6279 case NEON::BI__builtin_neon_vcvtpq_u32_v: 6280 case NEON::BI__builtin_neon_vcvtp_s64_v: 6281 case NEON::BI__builtin_neon_vcvtpq_s64_v: 6282 case NEON::BI__builtin_neon_vcvtp_u64_v: 6283 case NEON::BI__builtin_neon_vcvtpq_u64_v: { 6284 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps; 6285 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6286 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp"); 6287 } 6288 case NEON::BI__builtin_neon_vmulx_v: 6289 case NEON::BI__builtin_neon_vmulxq_v: { 6290 Int = Intrinsic::aarch64_neon_fmulx; 6291 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 6292 } 6293 case NEON::BI__builtin_neon_vmul_lane_v: 6294 case NEON::BI__builtin_neon_vmul_laneq_v: { 6295 // v1f64 vmul_lane should be mapped to Neon scalar mul lane 6296 bool Quad = false; 6297 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v) 6298 Quad = true; 6299 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6300 llvm::Type *VTy = GetNeonType(this, 6301 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); 6302 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 6303 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); 6304 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); 6305 return Builder.CreateBitCast(Result, Ty); 6306 } 6307 case NEON::BI__builtin_neon_vnegd_s64: 6308 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd"); 6309 case NEON::BI__builtin_neon_vpmaxnm_v: 6310 case NEON::BI__builtin_neon_vpmaxnmq_v: { 6311 Int = Intrinsic::aarch64_neon_fmaxnmp; 6312 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 6313 } 6314 case NEON::BI__builtin_neon_vpminnm_v: 6315 case NEON::BI__builtin_neon_vpminnmq_v: { 6316 Int = Intrinsic::aarch64_neon_fminnmp; 6317 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 6318 } 6319 case NEON::BI__builtin_neon_vsqrt_v: 6320 case NEON::BI__builtin_neon_vsqrtq_v: { 6321 Int = Intrinsic::sqrt; 6322 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6323 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); 6324 } 6325 case NEON::BI__builtin_neon_vrbit_v: 6326 case NEON::BI__builtin_neon_vrbitq_v: { 6327 Int = Intrinsic::aarch64_neon_rbit; 6328 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); 6329 } 6330 case NEON::BI__builtin_neon_vaddv_u8: 6331 // FIXME: These are handled by the AArch64 scalar code. 6332 usgn = true; 6333 // FALLTHROUGH 6334 case NEON::BI__builtin_neon_vaddv_s8: { 6335 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6336 Ty = Int32Ty; 6337 VTy = llvm::VectorType::get(Int8Ty, 8); 6338 llvm::Type *Tys[2] = { Ty, VTy }; 6339 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6340 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6341 return Builder.CreateTrunc(Ops[0], Int8Ty); 6342 } 6343 case NEON::BI__builtin_neon_vaddv_u16: 6344 usgn = true; 6345 // FALLTHROUGH 6346 case NEON::BI__builtin_neon_vaddv_s16: { 6347 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6348 Ty = Int32Ty; 6349 VTy = llvm::VectorType::get(Int16Ty, 4); 6350 llvm::Type *Tys[2] = { Ty, VTy }; 6351 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6352 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6353 return Builder.CreateTrunc(Ops[0], Int16Ty); 6354 } 6355 case NEON::BI__builtin_neon_vaddvq_u8: 6356 usgn = true; 6357 // FALLTHROUGH 6358 case NEON::BI__builtin_neon_vaddvq_s8: { 6359 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6360 Ty = Int32Ty; 6361 VTy = llvm::VectorType::get(Int8Ty, 16); 6362 llvm::Type *Tys[2] = { Ty, VTy }; 6363 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6364 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6365 return Builder.CreateTrunc(Ops[0], Int8Ty); 6366 } 6367 case NEON::BI__builtin_neon_vaddvq_u16: 6368 usgn = true; 6369 // FALLTHROUGH 6370 case NEON::BI__builtin_neon_vaddvq_s16: { 6371 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6372 Ty = Int32Ty; 6373 VTy = llvm::VectorType::get(Int16Ty, 8); 6374 llvm::Type *Tys[2] = { Ty, VTy }; 6375 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6376 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6377 return Builder.CreateTrunc(Ops[0], Int16Ty); 6378 } 6379 case NEON::BI__builtin_neon_vmaxv_u8: { 6380 Int = Intrinsic::aarch64_neon_umaxv; 6381 Ty = Int32Ty; 6382 VTy = llvm::VectorType::get(Int8Ty, 8); 6383 llvm::Type *Tys[2] = { Ty, VTy }; 6384 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6385 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6386 return Builder.CreateTrunc(Ops[0], Int8Ty); 6387 } 6388 case NEON::BI__builtin_neon_vmaxv_u16: { 6389 Int = Intrinsic::aarch64_neon_umaxv; 6390 Ty = Int32Ty; 6391 VTy = llvm::VectorType::get(Int16Ty, 4); 6392 llvm::Type *Tys[2] = { Ty, VTy }; 6393 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6394 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6395 return Builder.CreateTrunc(Ops[0], Int16Ty); 6396 } 6397 case NEON::BI__builtin_neon_vmaxvq_u8: { 6398 Int = Intrinsic::aarch64_neon_umaxv; 6399 Ty = Int32Ty; 6400 VTy = llvm::VectorType::get(Int8Ty, 16); 6401 llvm::Type *Tys[2] = { Ty, VTy }; 6402 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6403 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6404 return Builder.CreateTrunc(Ops[0], Int8Ty); 6405 } 6406 case NEON::BI__builtin_neon_vmaxvq_u16: { 6407 Int = Intrinsic::aarch64_neon_umaxv; 6408 Ty = Int32Ty; 6409 VTy = llvm::VectorType::get(Int16Ty, 8); 6410 llvm::Type *Tys[2] = { Ty, VTy }; 6411 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6412 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6413 return Builder.CreateTrunc(Ops[0], Int16Ty); 6414 } 6415 case NEON::BI__builtin_neon_vmaxv_s8: { 6416 Int = Intrinsic::aarch64_neon_smaxv; 6417 Ty = Int32Ty; 6418 VTy = llvm::VectorType::get(Int8Ty, 8); 6419 llvm::Type *Tys[2] = { Ty, VTy }; 6420 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6421 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6422 return Builder.CreateTrunc(Ops[0], Int8Ty); 6423 } 6424 case NEON::BI__builtin_neon_vmaxv_s16: { 6425 Int = Intrinsic::aarch64_neon_smaxv; 6426 Ty = Int32Ty; 6427 VTy = llvm::VectorType::get(Int16Ty, 4); 6428 llvm::Type *Tys[2] = { Ty, VTy }; 6429 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6430 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6431 return Builder.CreateTrunc(Ops[0], Int16Ty); 6432 } 6433 case NEON::BI__builtin_neon_vmaxvq_s8: { 6434 Int = Intrinsic::aarch64_neon_smaxv; 6435 Ty = Int32Ty; 6436 VTy = llvm::VectorType::get(Int8Ty, 16); 6437 llvm::Type *Tys[2] = { Ty, VTy }; 6438 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6439 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6440 return Builder.CreateTrunc(Ops[0], Int8Ty); 6441 } 6442 case NEON::BI__builtin_neon_vmaxvq_s16: { 6443 Int = Intrinsic::aarch64_neon_smaxv; 6444 Ty = Int32Ty; 6445 VTy = llvm::VectorType::get(Int16Ty, 8); 6446 llvm::Type *Tys[2] = { Ty, VTy }; 6447 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6448 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6449 return Builder.CreateTrunc(Ops[0], Int16Ty); 6450 } 6451 case NEON::BI__builtin_neon_vminv_u8: { 6452 Int = Intrinsic::aarch64_neon_uminv; 6453 Ty = Int32Ty; 6454 VTy = llvm::VectorType::get(Int8Ty, 8); 6455 llvm::Type *Tys[2] = { Ty, VTy }; 6456 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6457 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6458 return Builder.CreateTrunc(Ops[0], Int8Ty); 6459 } 6460 case NEON::BI__builtin_neon_vminv_u16: { 6461 Int = Intrinsic::aarch64_neon_uminv; 6462 Ty = Int32Ty; 6463 VTy = llvm::VectorType::get(Int16Ty, 4); 6464 llvm::Type *Tys[2] = { Ty, VTy }; 6465 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6466 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6467 return Builder.CreateTrunc(Ops[0], Int16Ty); 6468 } 6469 case NEON::BI__builtin_neon_vminvq_u8: { 6470 Int = Intrinsic::aarch64_neon_uminv; 6471 Ty = Int32Ty; 6472 VTy = llvm::VectorType::get(Int8Ty, 16); 6473 llvm::Type *Tys[2] = { Ty, VTy }; 6474 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6475 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6476 return Builder.CreateTrunc(Ops[0], Int8Ty); 6477 } 6478 case NEON::BI__builtin_neon_vminvq_u16: { 6479 Int = Intrinsic::aarch64_neon_uminv; 6480 Ty = Int32Ty; 6481 VTy = llvm::VectorType::get(Int16Ty, 8); 6482 llvm::Type *Tys[2] = { Ty, VTy }; 6483 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6484 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6485 return Builder.CreateTrunc(Ops[0], Int16Ty); 6486 } 6487 case NEON::BI__builtin_neon_vminv_s8: { 6488 Int = Intrinsic::aarch64_neon_sminv; 6489 Ty = Int32Ty; 6490 VTy = llvm::VectorType::get(Int8Ty, 8); 6491 llvm::Type *Tys[2] = { Ty, VTy }; 6492 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6493 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6494 return Builder.CreateTrunc(Ops[0], Int8Ty); 6495 } 6496 case NEON::BI__builtin_neon_vminv_s16: { 6497 Int = Intrinsic::aarch64_neon_sminv; 6498 Ty = Int32Ty; 6499 VTy = llvm::VectorType::get(Int16Ty, 4); 6500 llvm::Type *Tys[2] = { Ty, VTy }; 6501 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6502 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6503 return Builder.CreateTrunc(Ops[0], Int16Ty); 6504 } 6505 case NEON::BI__builtin_neon_vminvq_s8: { 6506 Int = Intrinsic::aarch64_neon_sminv; 6507 Ty = Int32Ty; 6508 VTy = llvm::VectorType::get(Int8Ty, 16); 6509 llvm::Type *Tys[2] = { Ty, VTy }; 6510 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6511 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6512 return Builder.CreateTrunc(Ops[0], Int8Ty); 6513 } 6514 case NEON::BI__builtin_neon_vminvq_s16: { 6515 Int = Intrinsic::aarch64_neon_sminv; 6516 Ty = Int32Ty; 6517 VTy = llvm::VectorType::get(Int16Ty, 8); 6518 llvm::Type *Tys[2] = { Ty, VTy }; 6519 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6520 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6521 return Builder.CreateTrunc(Ops[0], Int16Ty); 6522 } 6523 case NEON::BI__builtin_neon_vmul_n_f64: { 6524 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6525 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy); 6526 return Builder.CreateFMul(Ops[0], RHS); 6527 } 6528 case NEON::BI__builtin_neon_vaddlv_u8: { 6529 Int = Intrinsic::aarch64_neon_uaddlv; 6530 Ty = Int32Ty; 6531 VTy = llvm::VectorType::get(Int8Ty, 8); 6532 llvm::Type *Tys[2] = { Ty, VTy }; 6533 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6534 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6535 return Builder.CreateTrunc(Ops[0], Int16Ty); 6536 } 6537 case NEON::BI__builtin_neon_vaddlv_u16: { 6538 Int = Intrinsic::aarch64_neon_uaddlv; 6539 Ty = Int32Ty; 6540 VTy = llvm::VectorType::get(Int16Ty, 4); 6541 llvm::Type *Tys[2] = { Ty, VTy }; 6542 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6543 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6544 } 6545 case NEON::BI__builtin_neon_vaddlvq_u8: { 6546 Int = Intrinsic::aarch64_neon_uaddlv; 6547 Ty = Int32Ty; 6548 VTy = llvm::VectorType::get(Int8Ty, 16); 6549 llvm::Type *Tys[2] = { Ty, VTy }; 6550 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6551 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6552 return Builder.CreateTrunc(Ops[0], Int16Ty); 6553 } 6554 case NEON::BI__builtin_neon_vaddlvq_u16: { 6555 Int = Intrinsic::aarch64_neon_uaddlv; 6556 Ty = Int32Ty; 6557 VTy = llvm::VectorType::get(Int16Ty, 8); 6558 llvm::Type *Tys[2] = { Ty, VTy }; 6559 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6560 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6561 } 6562 case NEON::BI__builtin_neon_vaddlv_s8: { 6563 Int = Intrinsic::aarch64_neon_saddlv; 6564 Ty = Int32Ty; 6565 VTy = llvm::VectorType::get(Int8Ty, 8); 6566 llvm::Type *Tys[2] = { Ty, VTy }; 6567 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6568 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6569 return Builder.CreateTrunc(Ops[0], Int16Ty); 6570 } 6571 case NEON::BI__builtin_neon_vaddlv_s16: { 6572 Int = Intrinsic::aarch64_neon_saddlv; 6573 Ty = Int32Ty; 6574 VTy = llvm::VectorType::get(Int16Ty, 4); 6575 llvm::Type *Tys[2] = { Ty, VTy }; 6576 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6577 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6578 } 6579 case NEON::BI__builtin_neon_vaddlvq_s8: { 6580 Int = Intrinsic::aarch64_neon_saddlv; 6581 Ty = Int32Ty; 6582 VTy = llvm::VectorType::get(Int8Ty, 16); 6583 llvm::Type *Tys[2] = { Ty, VTy }; 6584 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6585 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6586 return Builder.CreateTrunc(Ops[0], Int16Ty); 6587 } 6588 case NEON::BI__builtin_neon_vaddlvq_s16: { 6589 Int = Intrinsic::aarch64_neon_saddlv; 6590 Ty = Int32Ty; 6591 VTy = llvm::VectorType::get(Int16Ty, 8); 6592 llvm::Type *Tys[2] = { Ty, VTy }; 6593 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6594 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6595 } 6596 case NEON::BI__builtin_neon_vsri_n_v: 6597 case NEON::BI__builtin_neon_vsriq_n_v: { 6598 Int = Intrinsic::aarch64_neon_vsri; 6599 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6600 return EmitNeonCall(Intrin, Ops, "vsri_n"); 6601 } 6602 case NEON::BI__builtin_neon_vsli_n_v: 6603 case NEON::BI__builtin_neon_vsliq_n_v: { 6604 Int = Intrinsic::aarch64_neon_vsli; 6605 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6606 return EmitNeonCall(Intrin, Ops, "vsli_n"); 6607 } 6608 case NEON::BI__builtin_neon_vsra_n_v: 6609 case NEON::BI__builtin_neon_vsraq_n_v: 6610 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6611 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 6612 return Builder.CreateAdd(Ops[0], Ops[1]); 6613 case NEON::BI__builtin_neon_vrsra_n_v: 6614 case NEON::BI__builtin_neon_vrsraq_n_v: { 6615 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl; 6616 SmallVector<llvm::Value*,2> TmpOps; 6617 TmpOps.push_back(Ops[1]); 6618 TmpOps.push_back(Ops[2]); 6619 Function* F = CGM.getIntrinsic(Int, Ty); 6620 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true); 6621 Ops[0] = Builder.CreateBitCast(Ops[0], VTy); 6622 return Builder.CreateAdd(Ops[0], tmp); 6623 } 6624 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence 6625 // of an Align parameter here. 6626 case NEON::BI__builtin_neon_vld1_x2_v: 6627 case NEON::BI__builtin_neon_vld1q_x2_v: 6628 case NEON::BI__builtin_neon_vld1_x3_v: 6629 case NEON::BI__builtin_neon_vld1q_x3_v: 6630 case NEON::BI__builtin_neon_vld1_x4_v: 6631 case NEON::BI__builtin_neon_vld1q_x4_v: { 6632 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6633 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6634 llvm::Type *Tys[2] = { VTy, PTy }; 6635 unsigned Int; 6636 switch (BuiltinID) { 6637 case NEON::BI__builtin_neon_vld1_x2_v: 6638 case NEON::BI__builtin_neon_vld1q_x2_v: 6639 Int = Intrinsic::aarch64_neon_ld1x2; 6640 break; 6641 case NEON::BI__builtin_neon_vld1_x3_v: 6642 case NEON::BI__builtin_neon_vld1q_x3_v: 6643 Int = Intrinsic::aarch64_neon_ld1x3; 6644 break; 6645 case NEON::BI__builtin_neon_vld1_x4_v: 6646 case NEON::BI__builtin_neon_vld1q_x4_v: 6647 Int = Intrinsic::aarch64_neon_ld1x4; 6648 break; 6649 } 6650 Function *F = CGM.getIntrinsic(Int, Tys); 6651 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN"); 6652 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6653 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6654 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6655 } 6656 case NEON::BI__builtin_neon_vst1_x2_v: 6657 case NEON::BI__builtin_neon_vst1q_x2_v: 6658 case NEON::BI__builtin_neon_vst1_x3_v: 6659 case NEON::BI__builtin_neon_vst1q_x3_v: 6660 case NEON::BI__builtin_neon_vst1_x4_v: 6661 case NEON::BI__builtin_neon_vst1q_x4_v: { 6662 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6663 llvm::Type *Tys[2] = { VTy, PTy }; 6664 unsigned Int; 6665 switch (BuiltinID) { 6666 case NEON::BI__builtin_neon_vst1_x2_v: 6667 case NEON::BI__builtin_neon_vst1q_x2_v: 6668 Int = Intrinsic::aarch64_neon_st1x2; 6669 break; 6670 case NEON::BI__builtin_neon_vst1_x3_v: 6671 case NEON::BI__builtin_neon_vst1q_x3_v: 6672 Int = Intrinsic::aarch64_neon_st1x3; 6673 break; 6674 case NEON::BI__builtin_neon_vst1_x4_v: 6675 case NEON::BI__builtin_neon_vst1q_x4_v: 6676 Int = Intrinsic::aarch64_neon_st1x4; 6677 break; 6678 } 6679 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end()); 6680 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 6681 } 6682 case NEON::BI__builtin_neon_vld1_v: 6683 case NEON::BI__builtin_neon_vld1q_v: { 6684 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 6685 auto Alignment = CharUnits::fromQuantity( 6686 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16); 6687 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment); 6688 } 6689 case NEON::BI__builtin_neon_vst1_v: 6690 case NEON::BI__builtin_neon_vst1q_v: 6691 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 6692 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 6693 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6694 case NEON::BI__builtin_neon_vld1_lane_v: 6695 case NEON::BI__builtin_neon_vld1q_lane_v: { 6696 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6697 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 6698 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6699 auto Alignment = CharUnits::fromQuantity( 6700 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16); 6701 Ops[0] = 6702 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 6703 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane"); 6704 } 6705 case NEON::BI__builtin_neon_vld1_dup_v: 6706 case NEON::BI__builtin_neon_vld1q_dup_v: { 6707 Value *V = UndefValue::get(Ty); 6708 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 6709 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6710 auto Alignment = CharUnits::fromQuantity( 6711 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16); 6712 Ops[0] = 6713 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 6714 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 6715 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI); 6716 return EmitNeonSplat(Ops[0], CI); 6717 } 6718 case NEON::BI__builtin_neon_vst1_lane_v: 6719 case NEON::BI__builtin_neon_vst1q_lane_v: 6720 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6721 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 6722 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6723 return Builder.CreateDefaultAlignedStore(Ops[1], 6724 Builder.CreateBitCast(Ops[0], Ty)); 6725 case NEON::BI__builtin_neon_vld2_v: 6726 case NEON::BI__builtin_neon_vld2q_v: { 6727 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 6728 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6729 llvm::Type *Tys[2] = { VTy, PTy }; 6730 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys); 6731 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 6732 Ops[0] = Builder.CreateBitCast(Ops[0], 6733 llvm::PointerType::getUnqual(Ops[1]->getType())); 6734 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6735 } 6736 case NEON::BI__builtin_neon_vld3_v: 6737 case NEON::BI__builtin_neon_vld3q_v: { 6738 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 6739 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6740 llvm::Type *Tys[2] = { VTy, PTy }; 6741 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys); 6742 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 6743 Ops[0] = Builder.CreateBitCast(Ops[0], 6744 llvm::PointerType::getUnqual(Ops[1]->getType())); 6745 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6746 } 6747 case NEON::BI__builtin_neon_vld4_v: 6748 case NEON::BI__builtin_neon_vld4q_v: { 6749 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 6750 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6751 llvm::Type *Tys[2] = { VTy, PTy }; 6752 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys); 6753 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 6754 Ops[0] = Builder.CreateBitCast(Ops[0], 6755 llvm::PointerType::getUnqual(Ops[1]->getType())); 6756 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6757 } 6758 case NEON::BI__builtin_neon_vld2_dup_v: 6759 case NEON::BI__builtin_neon_vld2q_dup_v: { 6760 llvm::Type *PTy = 6761 llvm::PointerType::getUnqual(VTy->getElementType()); 6762 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6763 llvm::Type *Tys[2] = { VTy, PTy }; 6764 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys); 6765 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 6766 Ops[0] = Builder.CreateBitCast(Ops[0], 6767 llvm::PointerType::getUnqual(Ops[1]->getType())); 6768 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6769 } 6770 case NEON::BI__builtin_neon_vld3_dup_v: 6771 case NEON::BI__builtin_neon_vld3q_dup_v: { 6772 llvm::Type *PTy = 6773 llvm::PointerType::getUnqual(VTy->getElementType()); 6774 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6775 llvm::Type *Tys[2] = { VTy, PTy }; 6776 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys); 6777 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 6778 Ops[0] = Builder.CreateBitCast(Ops[0], 6779 llvm::PointerType::getUnqual(Ops[1]->getType())); 6780 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6781 } 6782 case NEON::BI__builtin_neon_vld4_dup_v: 6783 case NEON::BI__builtin_neon_vld4q_dup_v: { 6784 llvm::Type *PTy = 6785 llvm::PointerType::getUnqual(VTy->getElementType()); 6786 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6787 llvm::Type *Tys[2] = { VTy, PTy }; 6788 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys); 6789 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 6790 Ops[0] = Builder.CreateBitCast(Ops[0], 6791 llvm::PointerType::getUnqual(Ops[1]->getType())); 6792 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6793 } 6794 case NEON::BI__builtin_neon_vld2_lane_v: 6795 case NEON::BI__builtin_neon_vld2q_lane_v: { 6796 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 6797 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys); 6798 Ops.push_back(Ops[1]); 6799 Ops.erase(Ops.begin()+1); 6800 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6801 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6802 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 6803 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 6804 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6805 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6806 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6807 } 6808 case NEON::BI__builtin_neon_vld3_lane_v: 6809 case NEON::BI__builtin_neon_vld3q_lane_v: { 6810 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 6811 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys); 6812 Ops.push_back(Ops[1]); 6813 Ops.erase(Ops.begin()+1); 6814 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6815 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6816 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 6817 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 6818 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 6819 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6820 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6821 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6822 } 6823 case NEON::BI__builtin_neon_vld4_lane_v: 6824 case NEON::BI__builtin_neon_vld4q_lane_v: { 6825 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 6826 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys); 6827 Ops.push_back(Ops[1]); 6828 Ops.erase(Ops.begin()+1); 6829 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6830 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6831 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 6832 Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 6833 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty); 6834 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane"); 6835 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6836 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6837 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6838 } 6839 case NEON::BI__builtin_neon_vst2_v: 6840 case NEON::BI__builtin_neon_vst2q_v: { 6841 Ops.push_back(Ops[0]); 6842 Ops.erase(Ops.begin()); 6843 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() }; 6844 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys), 6845 Ops, ""); 6846 } 6847 case NEON::BI__builtin_neon_vst2_lane_v: 6848 case NEON::BI__builtin_neon_vst2q_lane_v: { 6849 Ops.push_back(Ops[0]); 6850 Ops.erase(Ops.begin()); 6851 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty); 6852 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 6853 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys), 6854 Ops, ""); 6855 } 6856 case NEON::BI__builtin_neon_vst3_v: 6857 case NEON::BI__builtin_neon_vst3q_v: { 6858 Ops.push_back(Ops[0]); 6859 Ops.erase(Ops.begin()); 6860 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 6861 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys), 6862 Ops, ""); 6863 } 6864 case NEON::BI__builtin_neon_vst3_lane_v: 6865 case NEON::BI__builtin_neon_vst3q_lane_v: { 6866 Ops.push_back(Ops[0]); 6867 Ops.erase(Ops.begin()); 6868 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 6869 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 6870 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys), 6871 Ops, ""); 6872 } 6873 case NEON::BI__builtin_neon_vst4_v: 6874 case NEON::BI__builtin_neon_vst4q_v: { 6875 Ops.push_back(Ops[0]); 6876 Ops.erase(Ops.begin()); 6877 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 6878 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys), 6879 Ops, ""); 6880 } 6881 case NEON::BI__builtin_neon_vst4_lane_v: 6882 case NEON::BI__builtin_neon_vst4q_lane_v: { 6883 Ops.push_back(Ops[0]); 6884 Ops.erase(Ops.begin()); 6885 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 6886 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() }; 6887 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys), 6888 Ops, ""); 6889 } 6890 case NEON::BI__builtin_neon_vtrn_v: 6891 case NEON::BI__builtin_neon_vtrnq_v: { 6892 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 6893 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6894 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6895 Value *SV = nullptr; 6896 6897 for (unsigned vi = 0; vi != 2; ++vi) { 6898 SmallVector<uint32_t, 16> Indices; 6899 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 6900 Indices.push_back(i+vi); 6901 Indices.push_back(i+e+vi); 6902 } 6903 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 6904 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 6905 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 6906 } 6907 return SV; 6908 } 6909 case NEON::BI__builtin_neon_vuzp_v: 6910 case NEON::BI__builtin_neon_vuzpq_v: { 6911 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 6912 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6913 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6914 Value *SV = nullptr; 6915 6916 for (unsigned vi = 0; vi != 2; ++vi) { 6917 SmallVector<uint32_t, 16> Indices; 6918 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 6919 Indices.push_back(2*i+vi); 6920 6921 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 6922 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 6923 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 6924 } 6925 return SV; 6926 } 6927 case NEON::BI__builtin_neon_vzip_v: 6928 case NEON::BI__builtin_neon_vzipq_v: { 6929 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 6930 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6931 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6932 Value *SV = nullptr; 6933 6934 for (unsigned vi = 0; vi != 2; ++vi) { 6935 SmallVector<uint32_t, 16> Indices; 6936 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 6937 Indices.push_back((i + vi*e) >> 1); 6938 Indices.push_back(((i + vi*e) >> 1)+e); 6939 } 6940 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 6941 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 6942 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 6943 } 6944 return SV; 6945 } 6946 case NEON::BI__builtin_neon_vqtbl1q_v: { 6947 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty), 6948 Ops, "vtbl1"); 6949 } 6950 case NEON::BI__builtin_neon_vqtbl2q_v: { 6951 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty), 6952 Ops, "vtbl2"); 6953 } 6954 case NEON::BI__builtin_neon_vqtbl3q_v: { 6955 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty), 6956 Ops, "vtbl3"); 6957 } 6958 case NEON::BI__builtin_neon_vqtbl4q_v: { 6959 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty), 6960 Ops, "vtbl4"); 6961 } 6962 case NEON::BI__builtin_neon_vqtbx1q_v: { 6963 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty), 6964 Ops, "vtbx1"); 6965 } 6966 case NEON::BI__builtin_neon_vqtbx2q_v: { 6967 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty), 6968 Ops, "vtbx2"); 6969 } 6970 case NEON::BI__builtin_neon_vqtbx3q_v: { 6971 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty), 6972 Ops, "vtbx3"); 6973 } 6974 case NEON::BI__builtin_neon_vqtbx4q_v: { 6975 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty), 6976 Ops, "vtbx4"); 6977 } 6978 case NEON::BI__builtin_neon_vsqadd_v: 6979 case NEON::BI__builtin_neon_vsqaddq_v: { 6980 Int = Intrinsic::aarch64_neon_usqadd; 6981 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); 6982 } 6983 case NEON::BI__builtin_neon_vuqadd_v: 6984 case NEON::BI__builtin_neon_vuqaddq_v: { 6985 Int = Intrinsic::aarch64_neon_suqadd; 6986 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); 6987 } 6988 } 6989 } 6990 6991 llvm::Value *CodeGenFunction:: 6992 BuildVector(ArrayRef<llvm::Value*> Ops) { 6993 assert((Ops.size() & (Ops.size() - 1)) == 0 && 6994 "Not a power-of-two sized vector!"); 6995 bool AllConstants = true; 6996 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 6997 AllConstants &= isa<Constant>(Ops[i]); 6998 6999 // If this is a constant vector, create a ConstantVector. 7000 if (AllConstants) { 7001 SmallVector<llvm::Constant*, 16> CstOps; 7002 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7003 CstOps.push_back(cast<Constant>(Ops[i])); 7004 return llvm::ConstantVector::get(CstOps); 7005 } 7006 7007 // Otherwise, insertelement the values to build the vector. 7008 Value *Result = 7009 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 7010 7011 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7012 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 7013 7014 return Result; 7015 } 7016 7017 // Convert the mask from an integer type to a vector of i1. 7018 static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask, 7019 unsigned NumElts) { 7020 7021 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(), 7022 cast<IntegerType>(Mask->getType())->getBitWidth()); 7023 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy); 7024 7025 // If we have less than 8 elements, then the starting mask was an i8 and 7026 // we need to extract down to the right number of elements. 7027 if (NumElts < 8) { 7028 uint32_t Indices[4]; 7029 for (unsigned i = 0; i != NumElts; ++i) 7030 Indices[i] = i; 7031 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec, 7032 makeArrayRef(Indices, NumElts), 7033 "extract"); 7034 } 7035 return MaskVec; 7036 } 7037 7038 static Value *EmitX86MaskedStore(CodeGenFunction &CGF, 7039 SmallVectorImpl<Value *> &Ops, 7040 unsigned Align) { 7041 // Cast the pointer to right type. 7042 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7043 llvm::PointerType::getUnqual(Ops[1]->getType())); 7044 7045 // If the mask is all ones just emit a regular store. 7046 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7047 if (C->isAllOnesValue()) 7048 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align); 7049 7050 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7051 Ops[1]->getType()->getVectorNumElements()); 7052 7053 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec); 7054 } 7055 7056 static Value *EmitX86MaskedLoad(CodeGenFunction &CGF, 7057 SmallVectorImpl<Value *> &Ops, unsigned Align) { 7058 // Cast the pointer to right type. 7059 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7060 llvm::PointerType::getUnqual(Ops[1]->getType())); 7061 7062 // If the mask is all ones just emit a regular store. 7063 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7064 if (C->isAllOnesValue()) 7065 return CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7066 7067 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7068 Ops[1]->getType()->getVectorNumElements()); 7069 7070 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]); 7071 } 7072 7073 static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF, 7074 SmallVectorImpl<Value *> &Ops, 7075 llvm::Type *DstTy, 7076 unsigned SrcSizeInBits, 7077 unsigned Align) { 7078 // Load the subvector. 7079 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7080 7081 // Create broadcast mask. 7082 unsigned NumDstElts = DstTy->getVectorNumElements(); 7083 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits(); 7084 7085 SmallVector<uint32_t, 8> Mask; 7086 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts) 7087 for (unsigned j = 0; j != NumSrcElts; ++j) 7088 Mask.push_back(j); 7089 7090 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst"); 7091 } 7092 7093 static Value *EmitX86Select(CodeGenFunction &CGF, 7094 Value *Mask, Value *Op0, Value *Op1) { 7095 7096 // If the mask is all ones just return first argument. 7097 if (const auto *C = dyn_cast<Constant>(Mask)) 7098 if (C->isAllOnesValue()) 7099 return Op0; 7100 7101 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements()); 7102 7103 return CGF.Builder.CreateSelect(Mask, Op0, Op1); 7104 } 7105 7106 static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC, 7107 bool Signed, SmallVectorImpl<Value *> &Ops) { 7108 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 7109 Value *Cmp; 7110 7111 if (CC == 3) { 7112 Cmp = Constant::getNullValue( 7113 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7114 } else if (CC == 7) { 7115 Cmp = Constant::getAllOnesValue( 7116 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7117 } else { 7118 ICmpInst::Predicate Pred; 7119 switch (CC) { 7120 default: llvm_unreachable("Unknown condition code"); 7121 case 0: Pred = ICmpInst::ICMP_EQ; break; 7122 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; 7123 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; 7124 case 4: Pred = ICmpInst::ICMP_NE; break; 7125 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; 7126 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; 7127 } 7128 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7129 } 7130 7131 const auto *C = dyn_cast<Constant>(Ops.back()); 7132 if (!C || !C->isAllOnesValue()) 7133 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts)); 7134 7135 if (NumElts < 8) { 7136 uint32_t Indices[8]; 7137 for (unsigned i = 0; i != NumElts; ++i) 7138 Indices[i] = i; 7139 for (unsigned i = NumElts; i != 8; ++i) 7140 Indices[i] = i % NumElts + NumElts; 7141 Cmp = CGF.Builder.CreateShuffleVector( 7142 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices); 7143 } 7144 return CGF.Builder.CreateBitCast(Cmp, 7145 IntegerType::get(CGF.getLLVMContext(), 7146 std::max(NumElts, 8U))); 7147 } 7148 7149 static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred, 7150 ArrayRef<Value *> Ops) { 7151 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7152 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]); 7153 7154 if (Ops.size() == 2) 7155 return Res; 7156 7157 assert(Ops.size() == 4); 7158 return EmitX86Select(CGF, Ops[3], Res, Ops[2]); 7159 } 7160 7161 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 7162 const CallExpr *E) { 7163 if (BuiltinID == X86::BI__builtin_ms_va_start || 7164 BuiltinID == X86::BI__builtin_ms_va_end) 7165 return EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(), 7166 BuiltinID == X86::BI__builtin_ms_va_start); 7167 if (BuiltinID == X86::BI__builtin_ms_va_copy) { 7168 // Lower this manually. We can't reliably determine whether or not any 7169 // given va_copy() is for a Win64 va_list from the calling convention 7170 // alone, because it's legal to do this from a System V ABI function. 7171 // With opaque pointer types, we won't have enough information in LLVM 7172 // IR to determine this from the argument types, either. Best to do it 7173 // now, while we have enough information. 7174 Address DestAddr = EmitMSVAListRef(E->getArg(0)); 7175 Address SrcAddr = EmitMSVAListRef(E->getArg(1)); 7176 7177 llvm::Type *BPP = Int8PtrPtrTy; 7178 7179 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"), 7180 DestAddr.getAlignment()); 7181 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"), 7182 SrcAddr.getAlignment()); 7183 7184 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); 7185 return Builder.CreateStore(ArgPtr, DestAddr); 7186 } 7187 7188 SmallVector<Value*, 4> Ops; 7189 7190 // Find out if any arguments are required to be integer constant expressions. 7191 unsigned ICEArguments = 0; 7192 ASTContext::GetBuiltinTypeError Error; 7193 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 7194 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 7195 7196 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 7197 // If this is a normal argument, just emit it as a scalar. 7198 if ((ICEArguments & (1 << i)) == 0) { 7199 Ops.push_back(EmitScalarExpr(E->getArg(i))); 7200 continue; 7201 } 7202 7203 // If this is required to be a constant, constant fold it so that we know 7204 // that the generated intrinsic gets a ConstantInt. 7205 llvm::APSInt Result; 7206 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 7207 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 7208 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 7209 } 7210 7211 // These exist so that the builtin that takes an immediate can be bounds 7212 // checked by clang to avoid passing bad immediates to the backend. Since 7213 // AVX has a larger immediate than SSE we would need separate builtins to 7214 // do the different bounds checking. Rather than create a clang specific 7215 // SSE only builtin, this implements eight separate builtins to match gcc 7216 // implementation. 7217 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) { 7218 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm)); 7219 llvm::Function *F = CGM.getIntrinsic(ID); 7220 return Builder.CreateCall(F, Ops); 7221 }; 7222 7223 // For the vector forms of FP comparisons, translate the builtins directly to 7224 // IR. 7225 // TODO: The builtins could be removed if the SSE header files used vector 7226 // extension comparisons directly (vector ordered/unordered may need 7227 // additional support via __builtin_isnan()). 7228 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) { 7229 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]); 7230 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType()); 7231 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy); 7232 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy); 7233 return Builder.CreateBitCast(Sext, FPVecTy); 7234 }; 7235 7236 switch (BuiltinID) { 7237 default: return nullptr; 7238 case X86::BI__builtin_cpu_supports: { 7239 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); 7240 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString(); 7241 7242 // TODO: When/if this becomes more than x86 specific then use a TargetInfo 7243 // based mapping. 7244 // Processor features and mapping to processor feature value. 7245 enum X86Features { 7246 CMOV = 0, 7247 MMX, 7248 POPCNT, 7249 SSE, 7250 SSE2, 7251 SSE3, 7252 SSSE3, 7253 SSE4_1, 7254 SSE4_2, 7255 AVX, 7256 AVX2, 7257 SSE4_A, 7258 FMA4, 7259 XOP, 7260 FMA, 7261 AVX512F, 7262 BMI, 7263 BMI2, 7264 AES, 7265 PCLMUL, 7266 AVX512VL, 7267 AVX512BW, 7268 AVX512DQ, 7269 AVX512CD, 7270 AVX512ER, 7271 AVX512PF, 7272 AVX512VBMI, 7273 AVX512IFMA, 7274 MAX 7275 }; 7276 7277 X86Features Feature = StringSwitch<X86Features>(FeatureStr) 7278 .Case("cmov", X86Features::CMOV) 7279 .Case("mmx", X86Features::MMX) 7280 .Case("popcnt", X86Features::POPCNT) 7281 .Case("sse", X86Features::SSE) 7282 .Case("sse2", X86Features::SSE2) 7283 .Case("sse3", X86Features::SSE3) 7284 .Case("ssse3", X86Features::SSSE3) 7285 .Case("sse4.1", X86Features::SSE4_1) 7286 .Case("sse4.2", X86Features::SSE4_2) 7287 .Case("avx", X86Features::AVX) 7288 .Case("avx2", X86Features::AVX2) 7289 .Case("sse4a", X86Features::SSE4_A) 7290 .Case("fma4", X86Features::FMA4) 7291 .Case("xop", X86Features::XOP) 7292 .Case("fma", X86Features::FMA) 7293 .Case("avx512f", X86Features::AVX512F) 7294 .Case("bmi", X86Features::BMI) 7295 .Case("bmi2", X86Features::BMI2) 7296 .Case("aes", X86Features::AES) 7297 .Case("pclmul", X86Features::PCLMUL) 7298 .Case("avx512vl", X86Features::AVX512VL) 7299 .Case("avx512bw", X86Features::AVX512BW) 7300 .Case("avx512dq", X86Features::AVX512DQ) 7301 .Case("avx512cd", X86Features::AVX512CD) 7302 .Case("avx512er", X86Features::AVX512ER) 7303 .Case("avx512pf", X86Features::AVX512PF) 7304 .Case("avx512vbmi", X86Features::AVX512VBMI) 7305 .Case("avx512ifma", X86Features::AVX512IFMA) 7306 .Default(X86Features::MAX); 7307 assert(Feature != X86Features::MAX && "Invalid feature!"); 7308 7309 // Matching the struct layout from the compiler-rt/libgcc structure that is 7310 // filled in: 7311 // unsigned int __cpu_vendor; 7312 // unsigned int __cpu_type; 7313 // unsigned int __cpu_subtype; 7314 // unsigned int __cpu_features[1]; 7315 llvm::Type *STy = llvm::StructType::get( 7316 Int32Ty, Int32Ty, Int32Ty, llvm::ArrayType::get(Int32Ty, 1), nullptr); 7317 7318 // Grab the global __cpu_model. 7319 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7320 7321 // Grab the first (0th) element from the field __cpu_features off of the 7322 // global in the struct STy. 7323 Value *Idxs[] = { 7324 ConstantInt::get(Int32Ty, 0), 7325 ConstantInt::get(Int32Ty, 3), 7326 ConstantInt::get(Int32Ty, 0) 7327 }; 7328 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs); 7329 Value *Features = Builder.CreateAlignedLoad(CpuFeatures, 7330 CharUnits::fromQuantity(4)); 7331 7332 // Check the value of the bit corresponding to the feature requested. 7333 Value *Bitset = Builder.CreateAnd( 7334 Features, llvm::ConstantInt::get(Int32Ty, 1ULL << Feature)); 7335 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0)); 7336 } 7337 case X86::BI_mm_prefetch: { 7338 Value *Address = Ops[0]; 7339 Value *RW = ConstantInt::get(Int32Ty, 0); 7340 Value *Locality = Ops[1]; 7341 Value *Data = ConstantInt::get(Int32Ty, 1); 7342 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 7343 return Builder.CreateCall(F, {Address, RW, Locality, Data}); 7344 } 7345 case X86::BI_mm_clflush: { 7346 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush), 7347 Ops[0]); 7348 } 7349 case X86::BI_mm_lfence: { 7350 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence)); 7351 } 7352 case X86::BI_mm_mfence: { 7353 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence)); 7354 } 7355 case X86::BI_mm_sfence: { 7356 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence)); 7357 } 7358 case X86::BI_mm_pause: { 7359 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause)); 7360 } 7361 case X86::BI__rdtsc: { 7362 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc)); 7363 } 7364 case X86::BI__builtin_ia32_undef128: 7365 case X86::BI__builtin_ia32_undef256: 7366 case X86::BI__builtin_ia32_undef512: 7367 return UndefValue::get(ConvertType(E->getType())); 7368 case X86::BI__builtin_ia32_vec_init_v8qi: 7369 case X86::BI__builtin_ia32_vec_init_v4hi: 7370 case X86::BI__builtin_ia32_vec_init_v2si: 7371 return Builder.CreateBitCast(BuildVector(Ops), 7372 llvm::Type::getX86_MMXTy(getLLVMContext())); 7373 case X86::BI__builtin_ia32_vec_ext_v2si: 7374 return Builder.CreateExtractElement(Ops[0], 7375 llvm::ConstantInt::get(Ops[1]->getType(), 0)); 7376 case X86::BI_mm_setcsr: 7377 case X86::BI__builtin_ia32_ldmxcsr: { 7378 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 7379 Builder.CreateStore(Ops[0], Tmp); 7380 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 7381 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7382 } 7383 case X86::BI_mm_getcsr: 7384 case X86::BI__builtin_ia32_stmxcsr: { 7385 Address Tmp = CreateMemTemp(E->getType()); 7386 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 7387 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7388 return Builder.CreateLoad(Tmp, "stmxcsr"); 7389 } 7390 case X86::BI__builtin_ia32_xsave: 7391 case X86::BI__builtin_ia32_xsave64: 7392 case X86::BI__builtin_ia32_xrstor: 7393 case X86::BI__builtin_ia32_xrstor64: 7394 case X86::BI__builtin_ia32_xsaveopt: 7395 case X86::BI__builtin_ia32_xsaveopt64: 7396 case X86::BI__builtin_ia32_xrstors: 7397 case X86::BI__builtin_ia32_xrstors64: 7398 case X86::BI__builtin_ia32_xsavec: 7399 case X86::BI__builtin_ia32_xsavec64: 7400 case X86::BI__builtin_ia32_xsaves: 7401 case X86::BI__builtin_ia32_xsaves64: { 7402 Intrinsic::ID ID; 7403 #define INTRINSIC_X86_XSAVE_ID(NAME) \ 7404 case X86::BI__builtin_ia32_##NAME: \ 7405 ID = Intrinsic::x86_##NAME; \ 7406 break 7407 switch (BuiltinID) { 7408 default: llvm_unreachable("Unsupported intrinsic!"); 7409 INTRINSIC_X86_XSAVE_ID(xsave); 7410 INTRINSIC_X86_XSAVE_ID(xsave64); 7411 INTRINSIC_X86_XSAVE_ID(xrstor); 7412 INTRINSIC_X86_XSAVE_ID(xrstor64); 7413 INTRINSIC_X86_XSAVE_ID(xsaveopt); 7414 INTRINSIC_X86_XSAVE_ID(xsaveopt64); 7415 INTRINSIC_X86_XSAVE_ID(xrstors); 7416 INTRINSIC_X86_XSAVE_ID(xrstors64); 7417 INTRINSIC_X86_XSAVE_ID(xsavec); 7418 INTRINSIC_X86_XSAVE_ID(xsavec64); 7419 INTRINSIC_X86_XSAVE_ID(xsaves); 7420 INTRINSIC_X86_XSAVE_ID(xsaves64); 7421 } 7422 #undef INTRINSIC_X86_XSAVE_ID 7423 Value *Mhi = Builder.CreateTrunc( 7424 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty); 7425 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty); 7426 Ops[1] = Mhi; 7427 Ops.push_back(Mlo); 7428 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 7429 } 7430 case X86::BI__builtin_ia32_storedqudi128_mask: 7431 case X86::BI__builtin_ia32_storedqusi128_mask: 7432 case X86::BI__builtin_ia32_storedquhi128_mask: 7433 case X86::BI__builtin_ia32_storedquqi128_mask: 7434 case X86::BI__builtin_ia32_storeupd128_mask: 7435 case X86::BI__builtin_ia32_storeups128_mask: 7436 case X86::BI__builtin_ia32_storedqudi256_mask: 7437 case X86::BI__builtin_ia32_storedqusi256_mask: 7438 case X86::BI__builtin_ia32_storedquhi256_mask: 7439 case X86::BI__builtin_ia32_storedquqi256_mask: 7440 case X86::BI__builtin_ia32_storeupd256_mask: 7441 case X86::BI__builtin_ia32_storeups256_mask: 7442 case X86::BI__builtin_ia32_storedqudi512_mask: 7443 case X86::BI__builtin_ia32_storedqusi512_mask: 7444 case X86::BI__builtin_ia32_storedquhi512_mask: 7445 case X86::BI__builtin_ia32_storedquqi512_mask: 7446 case X86::BI__builtin_ia32_storeupd512_mask: 7447 case X86::BI__builtin_ia32_storeups512_mask: 7448 return EmitX86MaskedStore(*this, Ops, 1); 7449 7450 case X86::BI__builtin_ia32_storess128_mask: 7451 case X86::BI__builtin_ia32_storesd128_mask: { 7452 return EmitX86MaskedStore(*this, Ops, 16); 7453 } 7454 case X86::BI__builtin_ia32_movdqa32store128_mask: 7455 case X86::BI__builtin_ia32_movdqa64store128_mask: 7456 case X86::BI__builtin_ia32_storeaps128_mask: 7457 case X86::BI__builtin_ia32_storeapd128_mask: 7458 case X86::BI__builtin_ia32_movdqa32store256_mask: 7459 case X86::BI__builtin_ia32_movdqa64store256_mask: 7460 case X86::BI__builtin_ia32_storeaps256_mask: 7461 case X86::BI__builtin_ia32_storeapd256_mask: 7462 case X86::BI__builtin_ia32_movdqa32store512_mask: 7463 case X86::BI__builtin_ia32_movdqa64store512_mask: 7464 case X86::BI__builtin_ia32_storeaps512_mask: 7465 case X86::BI__builtin_ia32_storeapd512_mask: { 7466 unsigned Align = 7467 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7468 return EmitX86MaskedStore(*this, Ops, Align); 7469 } 7470 case X86::BI__builtin_ia32_loadups128_mask: 7471 case X86::BI__builtin_ia32_loadups256_mask: 7472 case X86::BI__builtin_ia32_loadups512_mask: 7473 case X86::BI__builtin_ia32_loadupd128_mask: 7474 case X86::BI__builtin_ia32_loadupd256_mask: 7475 case X86::BI__builtin_ia32_loadupd512_mask: 7476 case X86::BI__builtin_ia32_loaddquqi128_mask: 7477 case X86::BI__builtin_ia32_loaddquqi256_mask: 7478 case X86::BI__builtin_ia32_loaddquqi512_mask: 7479 case X86::BI__builtin_ia32_loaddquhi128_mask: 7480 case X86::BI__builtin_ia32_loaddquhi256_mask: 7481 case X86::BI__builtin_ia32_loaddquhi512_mask: 7482 case X86::BI__builtin_ia32_loaddqusi128_mask: 7483 case X86::BI__builtin_ia32_loaddqusi256_mask: 7484 case X86::BI__builtin_ia32_loaddqusi512_mask: 7485 case X86::BI__builtin_ia32_loaddqudi128_mask: 7486 case X86::BI__builtin_ia32_loaddqudi256_mask: 7487 case X86::BI__builtin_ia32_loaddqudi512_mask: 7488 return EmitX86MaskedLoad(*this, Ops, 1); 7489 7490 case X86::BI__builtin_ia32_loadss128_mask: 7491 case X86::BI__builtin_ia32_loadsd128_mask: 7492 return EmitX86MaskedLoad(*this, Ops, 16); 7493 7494 case X86::BI__builtin_ia32_loadaps128_mask: 7495 case X86::BI__builtin_ia32_loadaps256_mask: 7496 case X86::BI__builtin_ia32_loadaps512_mask: 7497 case X86::BI__builtin_ia32_loadapd128_mask: 7498 case X86::BI__builtin_ia32_loadapd256_mask: 7499 case X86::BI__builtin_ia32_loadapd512_mask: 7500 case X86::BI__builtin_ia32_movdqa32load128_mask: 7501 case X86::BI__builtin_ia32_movdqa32load256_mask: 7502 case X86::BI__builtin_ia32_movdqa32load512_mask: 7503 case X86::BI__builtin_ia32_movdqa64load128_mask: 7504 case X86::BI__builtin_ia32_movdqa64load256_mask: 7505 case X86::BI__builtin_ia32_movdqa64load512_mask: { 7506 unsigned Align = 7507 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7508 return EmitX86MaskedLoad(*this, Ops, Align); 7509 } 7510 7511 case X86::BI__builtin_ia32_vbroadcastf128_pd256: 7512 case X86::BI__builtin_ia32_vbroadcastf128_ps256: { 7513 llvm::Type *DstTy = ConvertType(E->getType()); 7514 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1); 7515 } 7516 7517 case X86::BI__builtin_ia32_storehps: 7518 case X86::BI__builtin_ia32_storelps: { 7519 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 7520 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 7521 7522 // cast val v2i64 7523 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 7524 7525 // extract (0, 1) 7526 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 7527 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index); 7528 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 7529 7530 // cast pointer to i64 & store 7531 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 7532 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7533 } 7534 case X86::BI__builtin_ia32_palignr128: 7535 case X86::BI__builtin_ia32_palignr256: 7536 case X86::BI__builtin_ia32_palignr512_mask: { 7537 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 7538 7539 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 7540 assert(NumElts % 16 == 0); 7541 7542 // If palignr is shifting the pair of vectors more than the size of two 7543 // lanes, emit zero. 7544 if (ShiftVal >= 32) 7545 return llvm::Constant::getNullValue(ConvertType(E->getType())); 7546 7547 // If palignr is shifting the pair of input vectors more than one lane, 7548 // but less than two lanes, convert to shifting in zeroes. 7549 if (ShiftVal > 16) { 7550 ShiftVal -= 16; 7551 Ops[1] = Ops[0]; 7552 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType()); 7553 } 7554 7555 uint32_t Indices[64]; 7556 // 256-bit palignr operates on 128-bit lanes so we need to handle that 7557 for (unsigned l = 0; l != NumElts; l += 16) { 7558 for (unsigned i = 0; i != 16; ++i) { 7559 unsigned Idx = ShiftVal + i; 7560 if (Idx >= 16) 7561 Idx += NumElts - 16; // End of lane, switch operand. 7562 Indices[l + i] = Idx + l; 7563 } 7564 } 7565 7566 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0], 7567 makeArrayRef(Indices, NumElts), 7568 "palignr"); 7569 7570 // If this isn't a masked builtin, just return the align operation. 7571 if (Ops.size() == 3) 7572 return Align; 7573 7574 return EmitX86Select(*this, Ops[4], Align, Ops[3]); 7575 } 7576 7577 case X86::BI__builtin_ia32_movnti: 7578 case X86::BI__builtin_ia32_movnti64: 7579 case X86::BI__builtin_ia32_movntsd: 7580 case X86::BI__builtin_ia32_movntss: { 7581 llvm::MDNode *Node = llvm::MDNode::get( 7582 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); 7583 7584 Value *Ptr = Ops[0]; 7585 Value *Src = Ops[1]; 7586 7587 // Extract the 0'th element of the source vector. 7588 if (BuiltinID == X86::BI__builtin_ia32_movntsd || 7589 BuiltinID == X86::BI__builtin_ia32_movntss) 7590 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract"); 7591 7592 // Convert the type of the pointer to a pointer to the stored type. 7593 Value *BC = Builder.CreateBitCast( 7594 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast"); 7595 7596 // Unaligned nontemporal store of the scalar value. 7597 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC); 7598 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 7599 SI->setAlignment(1); 7600 return SI; 7601 } 7602 7603 case X86::BI__builtin_ia32_selectb_128: 7604 case X86::BI__builtin_ia32_selectb_256: 7605 case X86::BI__builtin_ia32_selectb_512: 7606 case X86::BI__builtin_ia32_selectw_128: 7607 case X86::BI__builtin_ia32_selectw_256: 7608 case X86::BI__builtin_ia32_selectw_512: 7609 case X86::BI__builtin_ia32_selectd_128: 7610 case X86::BI__builtin_ia32_selectd_256: 7611 case X86::BI__builtin_ia32_selectd_512: 7612 case X86::BI__builtin_ia32_selectq_128: 7613 case X86::BI__builtin_ia32_selectq_256: 7614 case X86::BI__builtin_ia32_selectq_512: 7615 case X86::BI__builtin_ia32_selectps_128: 7616 case X86::BI__builtin_ia32_selectps_256: 7617 case X86::BI__builtin_ia32_selectps_512: 7618 case X86::BI__builtin_ia32_selectpd_128: 7619 case X86::BI__builtin_ia32_selectpd_256: 7620 case X86::BI__builtin_ia32_selectpd_512: 7621 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]); 7622 case X86::BI__builtin_ia32_pcmpeqb128_mask: 7623 case X86::BI__builtin_ia32_pcmpeqb256_mask: 7624 case X86::BI__builtin_ia32_pcmpeqb512_mask: 7625 case X86::BI__builtin_ia32_pcmpeqw128_mask: 7626 case X86::BI__builtin_ia32_pcmpeqw256_mask: 7627 case X86::BI__builtin_ia32_pcmpeqw512_mask: 7628 case X86::BI__builtin_ia32_pcmpeqd128_mask: 7629 case X86::BI__builtin_ia32_pcmpeqd256_mask: 7630 case X86::BI__builtin_ia32_pcmpeqd512_mask: 7631 case X86::BI__builtin_ia32_pcmpeqq128_mask: 7632 case X86::BI__builtin_ia32_pcmpeqq256_mask: 7633 case X86::BI__builtin_ia32_pcmpeqq512_mask: 7634 return EmitX86MaskedCompare(*this, 0, false, Ops); 7635 case X86::BI__builtin_ia32_pcmpgtb128_mask: 7636 case X86::BI__builtin_ia32_pcmpgtb256_mask: 7637 case X86::BI__builtin_ia32_pcmpgtb512_mask: 7638 case X86::BI__builtin_ia32_pcmpgtw128_mask: 7639 case X86::BI__builtin_ia32_pcmpgtw256_mask: 7640 case X86::BI__builtin_ia32_pcmpgtw512_mask: 7641 case X86::BI__builtin_ia32_pcmpgtd128_mask: 7642 case X86::BI__builtin_ia32_pcmpgtd256_mask: 7643 case X86::BI__builtin_ia32_pcmpgtd512_mask: 7644 case X86::BI__builtin_ia32_pcmpgtq128_mask: 7645 case X86::BI__builtin_ia32_pcmpgtq256_mask: 7646 case X86::BI__builtin_ia32_pcmpgtq512_mask: 7647 return EmitX86MaskedCompare(*this, 6, true, Ops); 7648 case X86::BI__builtin_ia32_cmpb128_mask: 7649 case X86::BI__builtin_ia32_cmpb256_mask: 7650 case X86::BI__builtin_ia32_cmpb512_mask: 7651 case X86::BI__builtin_ia32_cmpw128_mask: 7652 case X86::BI__builtin_ia32_cmpw256_mask: 7653 case X86::BI__builtin_ia32_cmpw512_mask: 7654 case X86::BI__builtin_ia32_cmpd128_mask: 7655 case X86::BI__builtin_ia32_cmpd256_mask: 7656 case X86::BI__builtin_ia32_cmpd512_mask: 7657 case X86::BI__builtin_ia32_cmpq128_mask: 7658 case X86::BI__builtin_ia32_cmpq256_mask: 7659 case X86::BI__builtin_ia32_cmpq512_mask: { 7660 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 7661 return EmitX86MaskedCompare(*this, CC, true, Ops); 7662 } 7663 case X86::BI__builtin_ia32_ucmpb128_mask: 7664 case X86::BI__builtin_ia32_ucmpb256_mask: 7665 case X86::BI__builtin_ia32_ucmpb512_mask: 7666 case X86::BI__builtin_ia32_ucmpw128_mask: 7667 case X86::BI__builtin_ia32_ucmpw256_mask: 7668 case X86::BI__builtin_ia32_ucmpw512_mask: 7669 case X86::BI__builtin_ia32_ucmpd128_mask: 7670 case X86::BI__builtin_ia32_ucmpd256_mask: 7671 case X86::BI__builtin_ia32_ucmpd512_mask: 7672 case X86::BI__builtin_ia32_ucmpq128_mask: 7673 case X86::BI__builtin_ia32_ucmpq256_mask: 7674 case X86::BI__builtin_ia32_ucmpq512_mask: { 7675 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 7676 return EmitX86MaskedCompare(*this, CC, false, Ops); 7677 } 7678 7679 case X86::BI__builtin_ia32_vplzcntd_128_mask: 7680 case X86::BI__builtin_ia32_vplzcntd_256_mask: 7681 case X86::BI__builtin_ia32_vplzcntd_512_mask: 7682 case X86::BI__builtin_ia32_vplzcntq_128_mask: 7683 case X86::BI__builtin_ia32_vplzcntq_256_mask: 7684 case X86::BI__builtin_ia32_vplzcntq_512_mask: { 7685 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType()); 7686 return EmitX86Select(*this, Ops[2], 7687 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}), 7688 Ops[1]); 7689 } 7690 7691 case X86::BI__builtin_ia32_pmaxsb128: 7692 case X86::BI__builtin_ia32_pmaxsw128: 7693 case X86::BI__builtin_ia32_pmaxsd128: 7694 case X86::BI__builtin_ia32_pmaxsq128_mask: 7695 case X86::BI__builtin_ia32_pmaxsb256: 7696 case X86::BI__builtin_ia32_pmaxsw256: 7697 case X86::BI__builtin_ia32_pmaxsd256: 7698 case X86::BI__builtin_ia32_pmaxsq256_mask: 7699 case X86::BI__builtin_ia32_pmaxsb512_mask: 7700 case X86::BI__builtin_ia32_pmaxsw512_mask: 7701 case X86::BI__builtin_ia32_pmaxsd512_mask: 7702 case X86::BI__builtin_ia32_pmaxsq512_mask: 7703 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops); 7704 case X86::BI__builtin_ia32_pmaxub128: 7705 case X86::BI__builtin_ia32_pmaxuw128: 7706 case X86::BI__builtin_ia32_pmaxud128: 7707 case X86::BI__builtin_ia32_pmaxuq128_mask: 7708 case X86::BI__builtin_ia32_pmaxub256: 7709 case X86::BI__builtin_ia32_pmaxuw256: 7710 case X86::BI__builtin_ia32_pmaxud256: 7711 case X86::BI__builtin_ia32_pmaxuq256_mask: 7712 case X86::BI__builtin_ia32_pmaxub512_mask: 7713 case X86::BI__builtin_ia32_pmaxuw512_mask: 7714 case X86::BI__builtin_ia32_pmaxud512_mask: 7715 case X86::BI__builtin_ia32_pmaxuq512_mask: 7716 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops); 7717 case X86::BI__builtin_ia32_pminsb128: 7718 case X86::BI__builtin_ia32_pminsw128: 7719 case X86::BI__builtin_ia32_pminsd128: 7720 case X86::BI__builtin_ia32_pminsq128_mask: 7721 case X86::BI__builtin_ia32_pminsb256: 7722 case X86::BI__builtin_ia32_pminsw256: 7723 case X86::BI__builtin_ia32_pminsd256: 7724 case X86::BI__builtin_ia32_pminsq256_mask: 7725 case X86::BI__builtin_ia32_pminsb512_mask: 7726 case X86::BI__builtin_ia32_pminsw512_mask: 7727 case X86::BI__builtin_ia32_pminsd512_mask: 7728 case X86::BI__builtin_ia32_pminsq512_mask: 7729 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops); 7730 case X86::BI__builtin_ia32_pminub128: 7731 case X86::BI__builtin_ia32_pminuw128: 7732 case X86::BI__builtin_ia32_pminud128: 7733 case X86::BI__builtin_ia32_pminuq128_mask: 7734 case X86::BI__builtin_ia32_pminub256: 7735 case X86::BI__builtin_ia32_pminuw256: 7736 case X86::BI__builtin_ia32_pminud256: 7737 case X86::BI__builtin_ia32_pminuq256_mask: 7738 case X86::BI__builtin_ia32_pminub512_mask: 7739 case X86::BI__builtin_ia32_pminuw512_mask: 7740 case X86::BI__builtin_ia32_pminud512_mask: 7741 case X86::BI__builtin_ia32_pminuq512_mask: 7742 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops); 7743 7744 // 3DNow! 7745 case X86::BI__builtin_ia32_pswapdsf: 7746 case X86::BI__builtin_ia32_pswapdsi: { 7747 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 7748 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 7749 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd); 7750 return Builder.CreateCall(F, Ops, "pswapd"); 7751 } 7752 case X86::BI__builtin_ia32_rdrand16_step: 7753 case X86::BI__builtin_ia32_rdrand32_step: 7754 case X86::BI__builtin_ia32_rdrand64_step: 7755 case X86::BI__builtin_ia32_rdseed16_step: 7756 case X86::BI__builtin_ia32_rdseed32_step: 7757 case X86::BI__builtin_ia32_rdseed64_step: { 7758 Intrinsic::ID ID; 7759 switch (BuiltinID) { 7760 default: llvm_unreachable("Unsupported intrinsic!"); 7761 case X86::BI__builtin_ia32_rdrand16_step: 7762 ID = Intrinsic::x86_rdrand_16; 7763 break; 7764 case X86::BI__builtin_ia32_rdrand32_step: 7765 ID = Intrinsic::x86_rdrand_32; 7766 break; 7767 case X86::BI__builtin_ia32_rdrand64_step: 7768 ID = Intrinsic::x86_rdrand_64; 7769 break; 7770 case X86::BI__builtin_ia32_rdseed16_step: 7771 ID = Intrinsic::x86_rdseed_16; 7772 break; 7773 case X86::BI__builtin_ia32_rdseed32_step: 7774 ID = Intrinsic::x86_rdseed_32; 7775 break; 7776 case X86::BI__builtin_ia32_rdseed64_step: 7777 ID = Intrinsic::x86_rdseed_64; 7778 break; 7779 } 7780 7781 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 7782 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0), 7783 Ops[0]); 7784 return Builder.CreateExtractValue(Call, 1); 7785 } 7786 7787 // SSE packed comparison intrinsics 7788 case X86::BI__builtin_ia32_cmpeqps: 7789 case X86::BI__builtin_ia32_cmpeqpd: 7790 return getVectorFCmpIR(CmpInst::FCMP_OEQ); 7791 case X86::BI__builtin_ia32_cmpltps: 7792 case X86::BI__builtin_ia32_cmpltpd: 7793 return getVectorFCmpIR(CmpInst::FCMP_OLT); 7794 case X86::BI__builtin_ia32_cmpleps: 7795 case X86::BI__builtin_ia32_cmplepd: 7796 return getVectorFCmpIR(CmpInst::FCMP_OLE); 7797 case X86::BI__builtin_ia32_cmpunordps: 7798 case X86::BI__builtin_ia32_cmpunordpd: 7799 return getVectorFCmpIR(CmpInst::FCMP_UNO); 7800 case X86::BI__builtin_ia32_cmpneqps: 7801 case X86::BI__builtin_ia32_cmpneqpd: 7802 return getVectorFCmpIR(CmpInst::FCMP_UNE); 7803 case X86::BI__builtin_ia32_cmpnltps: 7804 case X86::BI__builtin_ia32_cmpnltpd: 7805 return getVectorFCmpIR(CmpInst::FCMP_UGE); 7806 case X86::BI__builtin_ia32_cmpnleps: 7807 case X86::BI__builtin_ia32_cmpnlepd: 7808 return getVectorFCmpIR(CmpInst::FCMP_UGT); 7809 case X86::BI__builtin_ia32_cmpordps: 7810 case X86::BI__builtin_ia32_cmpordpd: 7811 return getVectorFCmpIR(CmpInst::FCMP_ORD); 7812 case X86::BI__builtin_ia32_cmpps: 7813 case X86::BI__builtin_ia32_cmpps256: 7814 case X86::BI__builtin_ia32_cmppd: 7815 case X86::BI__builtin_ia32_cmppd256: { 7816 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 7817 // If this one of the SSE immediates, we can use native IR. 7818 if (CC < 8) { 7819 FCmpInst::Predicate Pred; 7820 switch (CC) { 7821 case 0: Pred = FCmpInst::FCMP_OEQ; break; 7822 case 1: Pred = FCmpInst::FCMP_OLT; break; 7823 case 2: Pred = FCmpInst::FCMP_OLE; break; 7824 case 3: Pred = FCmpInst::FCMP_UNO; break; 7825 case 4: Pred = FCmpInst::FCMP_UNE; break; 7826 case 5: Pred = FCmpInst::FCMP_UGE; break; 7827 case 6: Pred = FCmpInst::FCMP_UGT; break; 7828 case 7: Pred = FCmpInst::FCMP_ORD; break; 7829 } 7830 return getVectorFCmpIR(Pred); 7831 } 7832 7833 // We can't handle 8-31 immediates with native IR, use the intrinsic. 7834 Intrinsic::ID ID; 7835 switch (BuiltinID) { 7836 default: llvm_unreachable("Unsupported intrinsic!"); 7837 case X86::BI__builtin_ia32_cmpps: 7838 ID = Intrinsic::x86_sse_cmp_ps; 7839 break; 7840 case X86::BI__builtin_ia32_cmpps256: 7841 ID = Intrinsic::x86_avx_cmp_ps_256; 7842 break; 7843 case X86::BI__builtin_ia32_cmppd: 7844 ID = Intrinsic::x86_sse2_cmp_pd; 7845 break; 7846 case X86::BI__builtin_ia32_cmppd256: 7847 ID = Intrinsic::x86_avx_cmp_pd_256; 7848 break; 7849 } 7850 7851 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 7852 } 7853 7854 // SSE scalar comparison intrinsics 7855 case X86::BI__builtin_ia32_cmpeqss: 7856 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0); 7857 case X86::BI__builtin_ia32_cmpltss: 7858 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1); 7859 case X86::BI__builtin_ia32_cmpless: 7860 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2); 7861 case X86::BI__builtin_ia32_cmpunordss: 7862 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3); 7863 case X86::BI__builtin_ia32_cmpneqss: 7864 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4); 7865 case X86::BI__builtin_ia32_cmpnltss: 7866 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5); 7867 case X86::BI__builtin_ia32_cmpnless: 7868 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6); 7869 case X86::BI__builtin_ia32_cmpordss: 7870 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7); 7871 case X86::BI__builtin_ia32_cmpeqsd: 7872 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0); 7873 case X86::BI__builtin_ia32_cmpltsd: 7874 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1); 7875 case X86::BI__builtin_ia32_cmplesd: 7876 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2); 7877 case X86::BI__builtin_ia32_cmpunordsd: 7878 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3); 7879 case X86::BI__builtin_ia32_cmpneqsd: 7880 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4); 7881 case X86::BI__builtin_ia32_cmpnltsd: 7882 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5); 7883 case X86::BI__builtin_ia32_cmpnlesd: 7884 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); 7885 case X86::BI__builtin_ia32_cmpordsd: 7886 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); 7887 7888 case X86::BI__emul: 7889 case X86::BI__emulu: { 7890 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64); 7891 bool isSigned = (BuiltinID == X86::BI__emul); 7892 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned); 7893 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned); 7894 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned); 7895 } 7896 case X86::BI__mulh: 7897 case X86::BI__umulh: 7898 case X86::BI_mul128: 7899 case X86::BI_umul128: { 7900 llvm::Type *ResType = ConvertType(E->getType()); 7901 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 7902 7903 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128); 7904 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned); 7905 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned); 7906 7907 Value *MulResult, *HigherBits; 7908 if (IsSigned) { 7909 MulResult = Builder.CreateNSWMul(LHS, RHS); 7910 HigherBits = Builder.CreateAShr(MulResult, 64); 7911 } else { 7912 MulResult = Builder.CreateNUWMul(LHS, RHS); 7913 HigherBits = Builder.CreateLShr(MulResult, 64); 7914 } 7915 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); 7916 7917 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh) 7918 return HigherBits; 7919 7920 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2)); 7921 Builder.CreateStore(HigherBits, HighBitsAddress); 7922 return Builder.CreateIntCast(MulResult, ResType, IsSigned); 7923 } 7924 7925 case X86::BI__faststorefence: { 7926 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 7927 llvm::CrossThread); 7928 } 7929 case X86::BI_ReadWriteBarrier: 7930 case X86::BI_ReadBarrier: 7931 case X86::BI_WriteBarrier: { 7932 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 7933 llvm::SingleThread); 7934 } 7935 case X86::BI_BitScanForward: 7936 case X86::BI_BitScanForward64: 7937 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 7938 case X86::BI_BitScanReverse: 7939 case X86::BI_BitScanReverse64: 7940 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 7941 7942 case X86::BI_InterlockedAnd64: 7943 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 7944 case X86::BI_InterlockedExchange64: 7945 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 7946 case X86::BI_InterlockedExchangeAdd64: 7947 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 7948 case X86::BI_InterlockedExchangeSub64: 7949 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 7950 case X86::BI_InterlockedOr64: 7951 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 7952 case X86::BI_InterlockedXor64: 7953 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 7954 case X86::BI_InterlockedDecrement64: 7955 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 7956 case X86::BI_InterlockedIncrement64: 7957 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 7958 7959 case X86::BI_AddressOfReturnAddress: { 7960 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); 7961 return Builder.CreateCall(F); 7962 } 7963 case X86::BI__stosb: { 7964 // We treat __stosb as a volatile memset - it may not generate "rep stosb" 7965 // instruction, but it will create a memset that won't be optimized away. 7966 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); 7967 } 7968 } 7969 } 7970 7971 7972 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 7973 const CallExpr *E) { 7974 SmallVector<Value*, 4> Ops; 7975 7976 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 7977 Ops.push_back(EmitScalarExpr(E->getArg(i))); 7978 7979 Intrinsic::ID ID = Intrinsic::not_intrinsic; 7980 7981 switch (BuiltinID) { 7982 default: return nullptr; 7983 7984 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we 7985 // call __builtin_readcyclecounter. 7986 case PPC::BI__builtin_ppc_get_timebase: 7987 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter)); 7988 7989 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr 7990 case PPC::BI__builtin_altivec_lvx: 7991 case PPC::BI__builtin_altivec_lvxl: 7992 case PPC::BI__builtin_altivec_lvebx: 7993 case PPC::BI__builtin_altivec_lvehx: 7994 case PPC::BI__builtin_altivec_lvewx: 7995 case PPC::BI__builtin_altivec_lvsl: 7996 case PPC::BI__builtin_altivec_lvsr: 7997 case PPC::BI__builtin_vsx_lxvd2x: 7998 case PPC::BI__builtin_vsx_lxvw4x: 7999 case PPC::BI__builtin_vsx_lxvd2x_be: 8000 case PPC::BI__builtin_vsx_lxvw4x_be: 8001 case PPC::BI__builtin_vsx_lxvl: 8002 case PPC::BI__builtin_vsx_lxvll: 8003 { 8004 if(BuiltinID == PPC::BI__builtin_vsx_lxvl || 8005 BuiltinID == PPC::BI__builtin_vsx_lxvll){ 8006 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy); 8007 }else { 8008 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8009 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 8010 Ops.pop_back(); 8011 } 8012 8013 switch (BuiltinID) { 8014 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 8015 case PPC::BI__builtin_altivec_lvx: 8016 ID = Intrinsic::ppc_altivec_lvx; 8017 break; 8018 case PPC::BI__builtin_altivec_lvxl: 8019 ID = Intrinsic::ppc_altivec_lvxl; 8020 break; 8021 case PPC::BI__builtin_altivec_lvebx: 8022 ID = Intrinsic::ppc_altivec_lvebx; 8023 break; 8024 case PPC::BI__builtin_altivec_lvehx: 8025 ID = Intrinsic::ppc_altivec_lvehx; 8026 break; 8027 case PPC::BI__builtin_altivec_lvewx: 8028 ID = Intrinsic::ppc_altivec_lvewx; 8029 break; 8030 case PPC::BI__builtin_altivec_lvsl: 8031 ID = Intrinsic::ppc_altivec_lvsl; 8032 break; 8033 case PPC::BI__builtin_altivec_lvsr: 8034 ID = Intrinsic::ppc_altivec_lvsr; 8035 break; 8036 case PPC::BI__builtin_vsx_lxvd2x: 8037 ID = Intrinsic::ppc_vsx_lxvd2x; 8038 break; 8039 case PPC::BI__builtin_vsx_lxvw4x: 8040 ID = Intrinsic::ppc_vsx_lxvw4x; 8041 break; 8042 case PPC::BI__builtin_vsx_lxvd2x_be: 8043 ID = Intrinsic::ppc_vsx_lxvd2x_be; 8044 break; 8045 case PPC::BI__builtin_vsx_lxvw4x_be: 8046 ID = Intrinsic::ppc_vsx_lxvw4x_be; 8047 break; 8048 case PPC::BI__builtin_vsx_lxvl: 8049 ID = Intrinsic::ppc_vsx_lxvl; 8050 break; 8051 case PPC::BI__builtin_vsx_lxvll: 8052 ID = Intrinsic::ppc_vsx_lxvll; 8053 break; 8054 } 8055 llvm::Function *F = CGM.getIntrinsic(ID); 8056 return Builder.CreateCall(F, Ops, ""); 8057 } 8058 8059 // vec_st, vec_xst_be 8060 case PPC::BI__builtin_altivec_stvx: 8061 case PPC::BI__builtin_altivec_stvxl: 8062 case PPC::BI__builtin_altivec_stvebx: 8063 case PPC::BI__builtin_altivec_stvehx: 8064 case PPC::BI__builtin_altivec_stvewx: 8065 case PPC::BI__builtin_vsx_stxvd2x: 8066 case PPC::BI__builtin_vsx_stxvw4x: 8067 case PPC::BI__builtin_vsx_stxvd2x_be: 8068 case PPC::BI__builtin_vsx_stxvw4x_be: 8069 case PPC::BI__builtin_vsx_stxvl: 8070 case PPC::BI__builtin_vsx_stxvll: 8071 { 8072 if(BuiltinID == PPC::BI__builtin_vsx_stxvl || 8073 BuiltinID == PPC::BI__builtin_vsx_stxvll ){ 8074 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8075 }else { 8076 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 8077 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 8078 Ops.pop_back(); 8079 } 8080 8081 switch (BuiltinID) { 8082 default: llvm_unreachable("Unsupported st intrinsic!"); 8083 case PPC::BI__builtin_altivec_stvx: 8084 ID = Intrinsic::ppc_altivec_stvx; 8085 break; 8086 case PPC::BI__builtin_altivec_stvxl: 8087 ID = Intrinsic::ppc_altivec_stvxl; 8088 break; 8089 case PPC::BI__builtin_altivec_stvebx: 8090 ID = Intrinsic::ppc_altivec_stvebx; 8091 break; 8092 case PPC::BI__builtin_altivec_stvehx: 8093 ID = Intrinsic::ppc_altivec_stvehx; 8094 break; 8095 case PPC::BI__builtin_altivec_stvewx: 8096 ID = Intrinsic::ppc_altivec_stvewx; 8097 break; 8098 case PPC::BI__builtin_vsx_stxvd2x: 8099 ID = Intrinsic::ppc_vsx_stxvd2x; 8100 break; 8101 case PPC::BI__builtin_vsx_stxvw4x: 8102 ID = Intrinsic::ppc_vsx_stxvw4x; 8103 break; 8104 case PPC::BI__builtin_vsx_stxvd2x_be: 8105 ID = Intrinsic::ppc_vsx_stxvd2x_be; 8106 break; 8107 case PPC::BI__builtin_vsx_stxvw4x_be: 8108 ID = Intrinsic::ppc_vsx_stxvw4x_be; 8109 break; 8110 case PPC::BI__builtin_vsx_stxvl: 8111 ID = Intrinsic::ppc_vsx_stxvl; 8112 break; 8113 case PPC::BI__builtin_vsx_stxvll: 8114 ID = Intrinsic::ppc_vsx_stxvll; 8115 break; 8116 } 8117 llvm::Function *F = CGM.getIntrinsic(ID); 8118 return Builder.CreateCall(F, Ops, ""); 8119 } 8120 // Square root 8121 case PPC::BI__builtin_vsx_xvsqrtsp: 8122 case PPC::BI__builtin_vsx_xvsqrtdp: { 8123 llvm::Type *ResultType = ConvertType(E->getType()); 8124 Value *X = EmitScalarExpr(E->getArg(0)); 8125 ID = Intrinsic::sqrt; 8126 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8127 return Builder.CreateCall(F, X); 8128 } 8129 // Count leading zeros 8130 case PPC::BI__builtin_altivec_vclzb: 8131 case PPC::BI__builtin_altivec_vclzh: 8132 case PPC::BI__builtin_altivec_vclzw: 8133 case PPC::BI__builtin_altivec_vclzd: { 8134 llvm::Type *ResultType = ConvertType(E->getType()); 8135 Value *X = EmitScalarExpr(E->getArg(0)); 8136 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8137 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 8138 return Builder.CreateCall(F, {X, Undef}); 8139 } 8140 case PPC::BI__builtin_altivec_vctzb: 8141 case PPC::BI__builtin_altivec_vctzh: 8142 case PPC::BI__builtin_altivec_vctzw: 8143 case PPC::BI__builtin_altivec_vctzd: { 8144 llvm::Type *ResultType = ConvertType(E->getType()); 8145 Value *X = EmitScalarExpr(E->getArg(0)); 8146 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8147 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 8148 return Builder.CreateCall(F, {X, Undef}); 8149 } 8150 case PPC::BI__builtin_altivec_vpopcntb: 8151 case PPC::BI__builtin_altivec_vpopcnth: 8152 case PPC::BI__builtin_altivec_vpopcntw: 8153 case PPC::BI__builtin_altivec_vpopcntd: { 8154 llvm::Type *ResultType = ConvertType(E->getType()); 8155 Value *X = EmitScalarExpr(E->getArg(0)); 8156 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 8157 return Builder.CreateCall(F, X); 8158 } 8159 // Copy sign 8160 case PPC::BI__builtin_vsx_xvcpsgnsp: 8161 case PPC::BI__builtin_vsx_xvcpsgndp: { 8162 llvm::Type *ResultType = ConvertType(E->getType()); 8163 Value *X = EmitScalarExpr(E->getArg(0)); 8164 Value *Y = EmitScalarExpr(E->getArg(1)); 8165 ID = Intrinsic::copysign; 8166 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8167 return Builder.CreateCall(F, {X, Y}); 8168 } 8169 // Rounding/truncation 8170 case PPC::BI__builtin_vsx_xvrspip: 8171 case PPC::BI__builtin_vsx_xvrdpip: 8172 case PPC::BI__builtin_vsx_xvrdpim: 8173 case PPC::BI__builtin_vsx_xvrspim: 8174 case PPC::BI__builtin_vsx_xvrdpi: 8175 case PPC::BI__builtin_vsx_xvrspi: 8176 case PPC::BI__builtin_vsx_xvrdpic: 8177 case PPC::BI__builtin_vsx_xvrspic: 8178 case PPC::BI__builtin_vsx_xvrdpiz: 8179 case PPC::BI__builtin_vsx_xvrspiz: { 8180 llvm::Type *ResultType = ConvertType(E->getType()); 8181 Value *X = EmitScalarExpr(E->getArg(0)); 8182 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim || 8183 BuiltinID == PPC::BI__builtin_vsx_xvrspim) 8184 ID = Intrinsic::floor; 8185 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi || 8186 BuiltinID == PPC::BI__builtin_vsx_xvrspi) 8187 ID = Intrinsic::round; 8188 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic || 8189 BuiltinID == PPC::BI__builtin_vsx_xvrspic) 8190 ID = Intrinsic::nearbyint; 8191 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip || 8192 BuiltinID == PPC::BI__builtin_vsx_xvrspip) 8193 ID = Intrinsic::ceil; 8194 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz || 8195 BuiltinID == PPC::BI__builtin_vsx_xvrspiz) 8196 ID = Intrinsic::trunc; 8197 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8198 return Builder.CreateCall(F, X); 8199 } 8200 8201 // Absolute value 8202 case PPC::BI__builtin_vsx_xvabsdp: 8203 case PPC::BI__builtin_vsx_xvabssp: { 8204 llvm::Type *ResultType = ConvertType(E->getType()); 8205 Value *X = EmitScalarExpr(E->getArg(0)); 8206 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 8207 return Builder.CreateCall(F, X); 8208 } 8209 8210 // FMA variations 8211 case PPC::BI__builtin_vsx_xvmaddadp: 8212 case PPC::BI__builtin_vsx_xvmaddasp: 8213 case PPC::BI__builtin_vsx_xvnmaddadp: 8214 case PPC::BI__builtin_vsx_xvnmaddasp: 8215 case PPC::BI__builtin_vsx_xvmsubadp: 8216 case PPC::BI__builtin_vsx_xvmsubasp: 8217 case PPC::BI__builtin_vsx_xvnmsubadp: 8218 case PPC::BI__builtin_vsx_xvnmsubasp: { 8219 llvm::Type *ResultType = ConvertType(E->getType()); 8220 Value *X = EmitScalarExpr(E->getArg(0)); 8221 Value *Y = EmitScalarExpr(E->getArg(1)); 8222 Value *Z = EmitScalarExpr(E->getArg(2)); 8223 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 8224 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 8225 switch (BuiltinID) { 8226 case PPC::BI__builtin_vsx_xvmaddadp: 8227 case PPC::BI__builtin_vsx_xvmaddasp: 8228 return Builder.CreateCall(F, {X, Y, Z}); 8229 case PPC::BI__builtin_vsx_xvnmaddadp: 8230 case PPC::BI__builtin_vsx_xvnmaddasp: 8231 return Builder.CreateFSub(Zero, 8232 Builder.CreateCall(F, {X, Y, Z}), "sub"); 8233 case PPC::BI__builtin_vsx_xvmsubadp: 8234 case PPC::BI__builtin_vsx_xvmsubasp: 8235 return Builder.CreateCall(F, 8236 {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8237 case PPC::BI__builtin_vsx_xvnmsubadp: 8238 case PPC::BI__builtin_vsx_xvnmsubasp: 8239 Value *FsubRes = 8240 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8241 return Builder.CreateFSub(Zero, FsubRes, "sub"); 8242 } 8243 llvm_unreachable("Unknown FMA operation"); 8244 return nullptr; // Suppress no-return warning 8245 } 8246 8247 case PPC::BI__builtin_vsx_insertword: { 8248 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw); 8249 8250 // Third argument is a compile time constant int. It must be clamped to 8251 // to the range [0, 12]. 8252 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8253 assert(ArgCI && 8254 "Third arg to xxinsertw intrinsic must be constant integer"); 8255 const int64_t MaxIndex = 12; 8256 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8257 8258 // The builtin semantics don't exactly match the xxinsertw instructions 8259 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the 8260 // word from the first argument, and inserts it in the second argument. The 8261 // instruction extracts the word from its second input register and inserts 8262 // it into its first input register, so swap the first and second arguments. 8263 std::swap(Ops[0], Ops[1]); 8264 8265 // Need to cast the second argument from a vector of unsigned int to a 8266 // vector of long long. 8267 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8268 8269 if (getTarget().isLittleEndian()) { 8270 // Create a shuffle mask of (1, 0) 8271 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8272 ConstantInt::get(Int32Ty, 0) 8273 }; 8274 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8275 8276 // Reverse the double words in the vector we will extract from. 8277 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8278 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask); 8279 8280 // Reverse the index. 8281 Index = MaxIndex - Index; 8282 } 8283 8284 // Intrinsic expects the first arg to be a vector of int. 8285 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8286 Ops[2] = ConstantInt::getSigned(Int32Ty, Index); 8287 return Builder.CreateCall(F, Ops); 8288 } 8289 8290 case PPC::BI__builtin_vsx_extractuword: { 8291 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw); 8292 8293 // Intrinsic expects the first argument to be a vector of doublewords. 8294 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8295 8296 // The second argument is a compile time constant int that needs to 8297 // be clamped to the range [0, 12]. 8298 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]); 8299 assert(ArgCI && 8300 "Second Arg to xxextractuw intrinsic must be a constant integer!"); 8301 const int64_t MaxIndex = 12; 8302 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8303 8304 if (getTarget().isLittleEndian()) { 8305 // Reverse the index. 8306 Index = MaxIndex - Index; 8307 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8308 8309 // Emit the call, then reverse the double words of the results vector. 8310 Value *Call = Builder.CreateCall(F, Ops); 8311 8312 // Create a shuffle mask of (1, 0) 8313 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8314 ConstantInt::get(Int32Ty, 0) 8315 }; 8316 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8317 8318 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask); 8319 return ShuffleCall; 8320 } else { 8321 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8322 return Builder.CreateCall(F, Ops); 8323 } 8324 } 8325 } 8326 } 8327 8328 Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, 8329 const CallExpr *E) { 8330 switch (BuiltinID) { 8331 case AMDGPU::BI__builtin_amdgcn_div_scale: 8332 case AMDGPU::BI__builtin_amdgcn_div_scalef: { 8333 // Translate from the intrinsics's struct return to the builtin's out 8334 // argument. 8335 8336 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3)); 8337 8338 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 8339 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 8340 llvm::Value *Z = EmitScalarExpr(E->getArg(2)); 8341 8342 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale, 8343 X->getType()); 8344 8345 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z}); 8346 8347 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0); 8348 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1); 8349 8350 llvm::Type *RealFlagType 8351 = FlagOutPtr.getPointer()->getType()->getPointerElementType(); 8352 8353 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType); 8354 Builder.CreateStore(FlagExt, FlagOutPtr); 8355 return Result; 8356 } 8357 case AMDGPU::BI__builtin_amdgcn_div_fmas: 8358 case AMDGPU::BI__builtin_amdgcn_div_fmasf: { 8359 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0)); 8360 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1)); 8361 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2)); 8362 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3)); 8363 8364 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas, 8365 Src0->getType()); 8366 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3); 8367 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool}); 8368 } 8369 8370 case AMDGPU::BI__builtin_amdgcn_ds_swizzle: 8371 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle); 8372 case AMDGPU::BI__builtin_amdgcn_div_fixup: 8373 case AMDGPU::BI__builtin_amdgcn_div_fixupf: 8374 case AMDGPU::BI__builtin_amdgcn_div_fixuph: 8375 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup); 8376 case AMDGPU::BI__builtin_amdgcn_trig_preop: 8377 case AMDGPU::BI__builtin_amdgcn_trig_preopf: 8378 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop); 8379 case AMDGPU::BI__builtin_amdgcn_rcp: 8380 case AMDGPU::BI__builtin_amdgcn_rcpf: 8381 case AMDGPU::BI__builtin_amdgcn_rcph: 8382 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp); 8383 case AMDGPU::BI__builtin_amdgcn_rsq: 8384 case AMDGPU::BI__builtin_amdgcn_rsqf: 8385 case AMDGPU::BI__builtin_amdgcn_rsqh: 8386 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq); 8387 case AMDGPU::BI__builtin_amdgcn_rsq_clamp: 8388 case AMDGPU::BI__builtin_amdgcn_rsq_clampf: 8389 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp); 8390 case AMDGPU::BI__builtin_amdgcn_sinf: 8391 case AMDGPU::BI__builtin_amdgcn_sinh: 8392 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin); 8393 case AMDGPU::BI__builtin_amdgcn_cosf: 8394 case AMDGPU::BI__builtin_amdgcn_cosh: 8395 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos); 8396 case AMDGPU::BI__builtin_amdgcn_log_clampf: 8397 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp); 8398 case AMDGPU::BI__builtin_amdgcn_ldexp: 8399 case AMDGPU::BI__builtin_amdgcn_ldexpf: 8400 case AMDGPU::BI__builtin_amdgcn_ldexph: 8401 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp); 8402 case AMDGPU::BI__builtin_amdgcn_frexp_mant: 8403 case AMDGPU::BI__builtin_amdgcn_frexp_mantf: 8404 case AMDGPU::BI__builtin_amdgcn_frexp_manth: 8405 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant); 8406 case AMDGPU::BI__builtin_amdgcn_frexp_exp: 8407 case AMDGPU::BI__builtin_amdgcn_frexp_expf: { 8408 Value *Src0 = EmitScalarExpr(E->getArg(0)); 8409 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 8410 { Builder.getInt32Ty(), Src0->getType() }); 8411 return Builder.CreateCall(F, Src0); 8412 } 8413 case AMDGPU::BI__builtin_amdgcn_frexp_exph: { 8414 Value *Src0 = EmitScalarExpr(E->getArg(0)); 8415 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 8416 { Builder.getInt16Ty(), Src0->getType() }); 8417 return Builder.CreateCall(F, Src0); 8418 } 8419 case AMDGPU::BI__builtin_amdgcn_fract: 8420 case AMDGPU::BI__builtin_amdgcn_fractf: 8421 case AMDGPU::BI__builtin_amdgcn_fracth: 8422 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract); 8423 case AMDGPU::BI__builtin_amdgcn_lerp: 8424 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp); 8425 case AMDGPU::BI__builtin_amdgcn_uicmp: 8426 case AMDGPU::BI__builtin_amdgcn_uicmpl: 8427 case AMDGPU::BI__builtin_amdgcn_sicmp: 8428 case AMDGPU::BI__builtin_amdgcn_sicmpl: 8429 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp); 8430 case AMDGPU::BI__builtin_amdgcn_fcmp: 8431 case AMDGPU::BI__builtin_amdgcn_fcmpf: 8432 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp); 8433 case AMDGPU::BI__builtin_amdgcn_class: 8434 case AMDGPU::BI__builtin_amdgcn_classf: 8435 case AMDGPU::BI__builtin_amdgcn_classh: 8436 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class); 8437 case AMDGPU::BI__builtin_amdgcn_fmed3f: 8438 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3); 8439 case AMDGPU::BI__builtin_amdgcn_read_exec: { 8440 CallInst *CI = cast<CallInst>( 8441 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec")); 8442 CI->setConvergent(); 8443 return CI; 8444 } 8445 8446 // amdgcn workitem 8447 case AMDGPU::BI__builtin_amdgcn_workitem_id_x: 8448 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024); 8449 case AMDGPU::BI__builtin_amdgcn_workitem_id_y: 8450 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024); 8451 case AMDGPU::BI__builtin_amdgcn_workitem_id_z: 8452 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024); 8453 8454 // r600 intrinsics 8455 case AMDGPU::BI__builtin_r600_recipsqrt_ieee: 8456 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef: 8457 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee); 8458 case AMDGPU::BI__builtin_r600_read_tidig_x: 8459 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024); 8460 case AMDGPU::BI__builtin_r600_read_tidig_y: 8461 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024); 8462 case AMDGPU::BI__builtin_r600_read_tidig_z: 8463 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024); 8464 default: 8465 return nullptr; 8466 } 8467 } 8468 8469 /// Handle a SystemZ function in which the final argument is a pointer 8470 /// to an int that receives the post-instruction CC value. At the LLVM level 8471 /// this is represented as a function that returns a {result, cc} pair. 8472 static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF, 8473 unsigned IntrinsicID, 8474 const CallExpr *E) { 8475 unsigned NumArgs = E->getNumArgs() - 1; 8476 SmallVector<Value *, 8> Args(NumArgs); 8477 for (unsigned I = 0; I < NumArgs; ++I) 8478 Args[I] = CGF.EmitScalarExpr(E->getArg(I)); 8479 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs)); 8480 Value *F = CGF.CGM.getIntrinsic(IntrinsicID); 8481 Value *Call = CGF.Builder.CreateCall(F, Args); 8482 Value *CC = CGF.Builder.CreateExtractValue(Call, 1); 8483 CGF.Builder.CreateStore(CC, CCPtr); 8484 return CGF.Builder.CreateExtractValue(Call, 0); 8485 } 8486 8487 Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, 8488 const CallExpr *E) { 8489 switch (BuiltinID) { 8490 case SystemZ::BI__builtin_tbegin: { 8491 Value *TDB = EmitScalarExpr(E->getArg(0)); 8492 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 8493 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin); 8494 return Builder.CreateCall(F, {TDB, Control}); 8495 } 8496 case SystemZ::BI__builtin_tbegin_nofloat: { 8497 Value *TDB = EmitScalarExpr(E->getArg(0)); 8498 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 8499 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat); 8500 return Builder.CreateCall(F, {TDB, Control}); 8501 } 8502 case SystemZ::BI__builtin_tbeginc: { 8503 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy); 8504 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08); 8505 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc); 8506 return Builder.CreateCall(F, {TDB, Control}); 8507 } 8508 case SystemZ::BI__builtin_tabort: { 8509 Value *Data = EmitScalarExpr(E->getArg(0)); 8510 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort); 8511 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort")); 8512 } 8513 case SystemZ::BI__builtin_non_tx_store: { 8514 Value *Address = EmitScalarExpr(E->getArg(0)); 8515 Value *Data = EmitScalarExpr(E->getArg(1)); 8516 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); 8517 return Builder.CreateCall(F, {Data, Address}); 8518 } 8519 8520 // Vector builtins. Note that most vector builtins are mapped automatically 8521 // to target-specific LLVM intrinsics. The ones handled specially here can 8522 // be represented via standard LLVM IR, which is preferable to enable common 8523 // LLVM optimizations. 8524 8525 case SystemZ::BI__builtin_s390_vpopctb: 8526 case SystemZ::BI__builtin_s390_vpopcth: 8527 case SystemZ::BI__builtin_s390_vpopctf: 8528 case SystemZ::BI__builtin_s390_vpopctg: { 8529 llvm::Type *ResultType = ConvertType(E->getType()); 8530 Value *X = EmitScalarExpr(E->getArg(0)); 8531 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 8532 return Builder.CreateCall(F, X); 8533 } 8534 8535 case SystemZ::BI__builtin_s390_vclzb: 8536 case SystemZ::BI__builtin_s390_vclzh: 8537 case SystemZ::BI__builtin_s390_vclzf: 8538 case SystemZ::BI__builtin_s390_vclzg: { 8539 llvm::Type *ResultType = ConvertType(E->getType()); 8540 Value *X = EmitScalarExpr(E->getArg(0)); 8541 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8542 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 8543 return Builder.CreateCall(F, {X, Undef}); 8544 } 8545 8546 case SystemZ::BI__builtin_s390_vctzb: 8547 case SystemZ::BI__builtin_s390_vctzh: 8548 case SystemZ::BI__builtin_s390_vctzf: 8549 case SystemZ::BI__builtin_s390_vctzg: { 8550 llvm::Type *ResultType = ConvertType(E->getType()); 8551 Value *X = EmitScalarExpr(E->getArg(0)); 8552 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8553 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 8554 return Builder.CreateCall(F, {X, Undef}); 8555 } 8556 8557 case SystemZ::BI__builtin_s390_vfsqdb: { 8558 llvm::Type *ResultType = ConvertType(E->getType()); 8559 Value *X = EmitScalarExpr(E->getArg(0)); 8560 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType); 8561 return Builder.CreateCall(F, X); 8562 } 8563 case SystemZ::BI__builtin_s390_vfmadb: { 8564 llvm::Type *ResultType = ConvertType(E->getType()); 8565 Value *X = EmitScalarExpr(E->getArg(0)); 8566 Value *Y = EmitScalarExpr(E->getArg(1)); 8567 Value *Z = EmitScalarExpr(E->getArg(2)); 8568 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 8569 return Builder.CreateCall(F, {X, Y, Z}); 8570 } 8571 case SystemZ::BI__builtin_s390_vfmsdb: { 8572 llvm::Type *ResultType = ConvertType(E->getType()); 8573 Value *X = EmitScalarExpr(E->getArg(0)); 8574 Value *Y = EmitScalarExpr(E->getArg(1)); 8575 Value *Z = EmitScalarExpr(E->getArg(2)); 8576 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 8577 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 8578 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8579 } 8580 case SystemZ::BI__builtin_s390_vflpdb: { 8581 llvm::Type *ResultType = ConvertType(E->getType()); 8582 Value *X = EmitScalarExpr(E->getArg(0)); 8583 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 8584 return Builder.CreateCall(F, X); 8585 } 8586 case SystemZ::BI__builtin_s390_vflndb: { 8587 llvm::Type *ResultType = ConvertType(E->getType()); 8588 Value *X = EmitScalarExpr(E->getArg(0)); 8589 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 8590 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 8591 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub"); 8592 } 8593 case SystemZ::BI__builtin_s390_vfidb: { 8594 llvm::Type *ResultType = ConvertType(E->getType()); 8595 Value *X = EmitScalarExpr(E->getArg(0)); 8596 // Constant-fold the M4 and M5 mask arguments. 8597 llvm::APSInt M4, M5; 8598 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext()); 8599 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext()); 8600 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?"); 8601 (void)IsConstM4; (void)IsConstM5; 8602 // Check whether this instance of vfidb can be represented via a LLVM 8603 // standard intrinsic. We only support some combinations of M4 and M5. 8604 Intrinsic::ID ID = Intrinsic::not_intrinsic; 8605 switch (M4.getZExtValue()) { 8606 default: break; 8607 case 0: // IEEE-inexact exception allowed 8608 switch (M5.getZExtValue()) { 8609 default: break; 8610 case 0: ID = Intrinsic::rint; break; 8611 } 8612 break; 8613 case 4: // IEEE-inexact exception suppressed 8614 switch (M5.getZExtValue()) { 8615 default: break; 8616 case 0: ID = Intrinsic::nearbyint; break; 8617 case 1: ID = Intrinsic::round; break; 8618 case 5: ID = Intrinsic::trunc; break; 8619 case 6: ID = Intrinsic::ceil; break; 8620 case 7: ID = Intrinsic::floor; break; 8621 } 8622 break; 8623 } 8624 if (ID != Intrinsic::not_intrinsic) { 8625 Function *F = CGM.getIntrinsic(ID, ResultType); 8626 return Builder.CreateCall(F, X); 8627 } 8628 Function *F = CGM.getIntrinsic(Intrinsic::s390_vfidb); 8629 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 8630 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5); 8631 return Builder.CreateCall(F, {X, M4Value, M5Value}); 8632 } 8633 8634 // Vector intrisincs that output the post-instruction CC value. 8635 8636 #define INTRINSIC_WITH_CC(NAME) \ 8637 case SystemZ::BI__builtin_##NAME: \ 8638 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E) 8639 8640 INTRINSIC_WITH_CC(s390_vpkshs); 8641 INTRINSIC_WITH_CC(s390_vpksfs); 8642 INTRINSIC_WITH_CC(s390_vpksgs); 8643 8644 INTRINSIC_WITH_CC(s390_vpklshs); 8645 INTRINSIC_WITH_CC(s390_vpklsfs); 8646 INTRINSIC_WITH_CC(s390_vpklsgs); 8647 8648 INTRINSIC_WITH_CC(s390_vceqbs); 8649 INTRINSIC_WITH_CC(s390_vceqhs); 8650 INTRINSIC_WITH_CC(s390_vceqfs); 8651 INTRINSIC_WITH_CC(s390_vceqgs); 8652 8653 INTRINSIC_WITH_CC(s390_vchbs); 8654 INTRINSIC_WITH_CC(s390_vchhs); 8655 INTRINSIC_WITH_CC(s390_vchfs); 8656 INTRINSIC_WITH_CC(s390_vchgs); 8657 8658 INTRINSIC_WITH_CC(s390_vchlbs); 8659 INTRINSIC_WITH_CC(s390_vchlhs); 8660 INTRINSIC_WITH_CC(s390_vchlfs); 8661 INTRINSIC_WITH_CC(s390_vchlgs); 8662 8663 INTRINSIC_WITH_CC(s390_vfaebs); 8664 INTRINSIC_WITH_CC(s390_vfaehs); 8665 INTRINSIC_WITH_CC(s390_vfaefs); 8666 8667 INTRINSIC_WITH_CC(s390_vfaezbs); 8668 INTRINSIC_WITH_CC(s390_vfaezhs); 8669 INTRINSIC_WITH_CC(s390_vfaezfs); 8670 8671 INTRINSIC_WITH_CC(s390_vfeebs); 8672 INTRINSIC_WITH_CC(s390_vfeehs); 8673 INTRINSIC_WITH_CC(s390_vfeefs); 8674 8675 INTRINSIC_WITH_CC(s390_vfeezbs); 8676 INTRINSIC_WITH_CC(s390_vfeezhs); 8677 INTRINSIC_WITH_CC(s390_vfeezfs); 8678 8679 INTRINSIC_WITH_CC(s390_vfenebs); 8680 INTRINSIC_WITH_CC(s390_vfenehs); 8681 INTRINSIC_WITH_CC(s390_vfenefs); 8682 8683 INTRINSIC_WITH_CC(s390_vfenezbs); 8684 INTRINSIC_WITH_CC(s390_vfenezhs); 8685 INTRINSIC_WITH_CC(s390_vfenezfs); 8686 8687 INTRINSIC_WITH_CC(s390_vistrbs); 8688 INTRINSIC_WITH_CC(s390_vistrhs); 8689 INTRINSIC_WITH_CC(s390_vistrfs); 8690 8691 INTRINSIC_WITH_CC(s390_vstrcbs); 8692 INTRINSIC_WITH_CC(s390_vstrchs); 8693 INTRINSIC_WITH_CC(s390_vstrcfs); 8694 8695 INTRINSIC_WITH_CC(s390_vstrczbs); 8696 INTRINSIC_WITH_CC(s390_vstrczhs); 8697 INTRINSIC_WITH_CC(s390_vstrczfs); 8698 8699 INTRINSIC_WITH_CC(s390_vfcedbs); 8700 INTRINSIC_WITH_CC(s390_vfchdbs); 8701 INTRINSIC_WITH_CC(s390_vfchedbs); 8702 8703 INTRINSIC_WITH_CC(s390_vftcidb); 8704 8705 #undef INTRINSIC_WITH_CC 8706 8707 default: 8708 return nullptr; 8709 } 8710 } 8711 8712 Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, 8713 const CallExpr *E) { 8714 auto MakeLdg = [&](unsigned IntrinsicID) { 8715 Value *Ptr = EmitScalarExpr(E->getArg(0)); 8716 AlignmentSource AlignSource; 8717 clang::CharUnits Align = 8718 getNaturalPointeeTypeAlignment(E->getArg(0)->getType(), &AlignSource); 8719 return Builder.CreateCall( 8720 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 8721 Ptr->getType()}), 8722 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())}); 8723 }; 8724 auto MakeScopedAtomic = [&](unsigned IntrinsicID) { 8725 Value *Ptr = EmitScalarExpr(E->getArg(0)); 8726 return Builder.CreateCall( 8727 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 8728 Ptr->getType()}), 8729 {Ptr, EmitScalarExpr(E->getArg(1))}); 8730 }; 8731 switch (BuiltinID) { 8732 case NVPTX::BI__nvvm_atom_add_gen_i: 8733 case NVPTX::BI__nvvm_atom_add_gen_l: 8734 case NVPTX::BI__nvvm_atom_add_gen_ll: 8735 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E); 8736 8737 case NVPTX::BI__nvvm_atom_sub_gen_i: 8738 case NVPTX::BI__nvvm_atom_sub_gen_l: 8739 case NVPTX::BI__nvvm_atom_sub_gen_ll: 8740 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E); 8741 8742 case NVPTX::BI__nvvm_atom_and_gen_i: 8743 case NVPTX::BI__nvvm_atom_and_gen_l: 8744 case NVPTX::BI__nvvm_atom_and_gen_ll: 8745 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E); 8746 8747 case NVPTX::BI__nvvm_atom_or_gen_i: 8748 case NVPTX::BI__nvvm_atom_or_gen_l: 8749 case NVPTX::BI__nvvm_atom_or_gen_ll: 8750 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E); 8751 8752 case NVPTX::BI__nvvm_atom_xor_gen_i: 8753 case NVPTX::BI__nvvm_atom_xor_gen_l: 8754 case NVPTX::BI__nvvm_atom_xor_gen_ll: 8755 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E); 8756 8757 case NVPTX::BI__nvvm_atom_xchg_gen_i: 8758 case NVPTX::BI__nvvm_atom_xchg_gen_l: 8759 case NVPTX::BI__nvvm_atom_xchg_gen_ll: 8760 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E); 8761 8762 case NVPTX::BI__nvvm_atom_max_gen_i: 8763 case NVPTX::BI__nvvm_atom_max_gen_l: 8764 case NVPTX::BI__nvvm_atom_max_gen_ll: 8765 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E); 8766 8767 case NVPTX::BI__nvvm_atom_max_gen_ui: 8768 case NVPTX::BI__nvvm_atom_max_gen_ul: 8769 case NVPTX::BI__nvvm_atom_max_gen_ull: 8770 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E); 8771 8772 case NVPTX::BI__nvvm_atom_min_gen_i: 8773 case NVPTX::BI__nvvm_atom_min_gen_l: 8774 case NVPTX::BI__nvvm_atom_min_gen_ll: 8775 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E); 8776 8777 case NVPTX::BI__nvvm_atom_min_gen_ui: 8778 case NVPTX::BI__nvvm_atom_min_gen_ul: 8779 case NVPTX::BI__nvvm_atom_min_gen_ull: 8780 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E); 8781 8782 case NVPTX::BI__nvvm_atom_cas_gen_i: 8783 case NVPTX::BI__nvvm_atom_cas_gen_l: 8784 case NVPTX::BI__nvvm_atom_cas_gen_ll: 8785 // __nvvm_atom_cas_gen_* should return the old value rather than the 8786 // success flag. 8787 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false); 8788 8789 case NVPTX::BI__nvvm_atom_add_gen_f: { 8790 Value *Ptr = EmitScalarExpr(E->getArg(0)); 8791 Value *Val = EmitScalarExpr(E->getArg(1)); 8792 // atomicrmw only deals with integer arguments so we need to use 8793 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that. 8794 Value *FnALAF32 = 8795 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType()); 8796 return Builder.CreateCall(FnALAF32, {Ptr, Val}); 8797 } 8798 8799 case NVPTX::BI__nvvm_atom_inc_gen_ui: { 8800 Value *Ptr = EmitScalarExpr(E->getArg(0)); 8801 Value *Val = EmitScalarExpr(E->getArg(1)); 8802 Value *FnALI32 = 8803 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType()); 8804 return Builder.CreateCall(FnALI32, {Ptr, Val}); 8805 } 8806 8807 case NVPTX::BI__nvvm_atom_dec_gen_ui: { 8808 Value *Ptr = EmitScalarExpr(E->getArg(0)); 8809 Value *Val = EmitScalarExpr(E->getArg(1)); 8810 Value *FnALD32 = 8811 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType()); 8812 return Builder.CreateCall(FnALD32, {Ptr, Val}); 8813 } 8814 8815 case NVPTX::BI__nvvm_ldg_c: 8816 case NVPTX::BI__nvvm_ldg_c2: 8817 case NVPTX::BI__nvvm_ldg_c4: 8818 case NVPTX::BI__nvvm_ldg_s: 8819 case NVPTX::BI__nvvm_ldg_s2: 8820 case NVPTX::BI__nvvm_ldg_s4: 8821 case NVPTX::BI__nvvm_ldg_i: 8822 case NVPTX::BI__nvvm_ldg_i2: 8823 case NVPTX::BI__nvvm_ldg_i4: 8824 case NVPTX::BI__nvvm_ldg_l: 8825 case NVPTX::BI__nvvm_ldg_ll: 8826 case NVPTX::BI__nvvm_ldg_ll2: 8827 case NVPTX::BI__nvvm_ldg_uc: 8828 case NVPTX::BI__nvvm_ldg_uc2: 8829 case NVPTX::BI__nvvm_ldg_uc4: 8830 case NVPTX::BI__nvvm_ldg_us: 8831 case NVPTX::BI__nvvm_ldg_us2: 8832 case NVPTX::BI__nvvm_ldg_us4: 8833 case NVPTX::BI__nvvm_ldg_ui: 8834 case NVPTX::BI__nvvm_ldg_ui2: 8835 case NVPTX::BI__nvvm_ldg_ui4: 8836 case NVPTX::BI__nvvm_ldg_ul: 8837 case NVPTX::BI__nvvm_ldg_ull: 8838 case NVPTX::BI__nvvm_ldg_ull2: 8839 // PTX Interoperability section 2.2: "For a vector with an even number of 8840 // elements, its alignment is set to number of elements times the alignment 8841 // of its member: n*alignof(t)." 8842 return MakeLdg(Intrinsic::nvvm_ldg_global_i); 8843 case NVPTX::BI__nvvm_ldg_f: 8844 case NVPTX::BI__nvvm_ldg_f2: 8845 case NVPTX::BI__nvvm_ldg_f4: 8846 case NVPTX::BI__nvvm_ldg_d: 8847 case NVPTX::BI__nvvm_ldg_d2: 8848 return MakeLdg(Intrinsic::nvvm_ldg_global_f); 8849 8850 case NVPTX::BI__nvvm_atom_cta_add_gen_i: 8851 case NVPTX::BI__nvvm_atom_cta_add_gen_l: 8852 case NVPTX::BI__nvvm_atom_cta_add_gen_ll: 8853 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta); 8854 case NVPTX::BI__nvvm_atom_sys_add_gen_i: 8855 case NVPTX::BI__nvvm_atom_sys_add_gen_l: 8856 case NVPTX::BI__nvvm_atom_sys_add_gen_ll: 8857 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys); 8858 case NVPTX::BI__nvvm_atom_cta_add_gen_f: 8859 case NVPTX::BI__nvvm_atom_cta_add_gen_d: 8860 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta); 8861 case NVPTX::BI__nvvm_atom_sys_add_gen_f: 8862 case NVPTX::BI__nvvm_atom_sys_add_gen_d: 8863 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys); 8864 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i: 8865 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l: 8866 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll: 8867 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta); 8868 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i: 8869 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l: 8870 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll: 8871 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys); 8872 case NVPTX::BI__nvvm_atom_cta_max_gen_i: 8873 case NVPTX::BI__nvvm_atom_cta_max_gen_ui: 8874 case NVPTX::BI__nvvm_atom_cta_max_gen_l: 8875 case NVPTX::BI__nvvm_atom_cta_max_gen_ul: 8876 case NVPTX::BI__nvvm_atom_cta_max_gen_ll: 8877 case NVPTX::BI__nvvm_atom_cta_max_gen_ull: 8878 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta); 8879 case NVPTX::BI__nvvm_atom_sys_max_gen_i: 8880 case NVPTX::BI__nvvm_atom_sys_max_gen_ui: 8881 case NVPTX::BI__nvvm_atom_sys_max_gen_l: 8882 case NVPTX::BI__nvvm_atom_sys_max_gen_ul: 8883 case NVPTX::BI__nvvm_atom_sys_max_gen_ll: 8884 case NVPTX::BI__nvvm_atom_sys_max_gen_ull: 8885 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys); 8886 case NVPTX::BI__nvvm_atom_cta_min_gen_i: 8887 case NVPTX::BI__nvvm_atom_cta_min_gen_ui: 8888 case NVPTX::BI__nvvm_atom_cta_min_gen_l: 8889 case NVPTX::BI__nvvm_atom_cta_min_gen_ul: 8890 case NVPTX::BI__nvvm_atom_cta_min_gen_ll: 8891 case NVPTX::BI__nvvm_atom_cta_min_gen_ull: 8892 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta); 8893 case NVPTX::BI__nvvm_atom_sys_min_gen_i: 8894 case NVPTX::BI__nvvm_atom_sys_min_gen_ui: 8895 case NVPTX::BI__nvvm_atom_sys_min_gen_l: 8896 case NVPTX::BI__nvvm_atom_sys_min_gen_ul: 8897 case NVPTX::BI__nvvm_atom_sys_min_gen_ll: 8898 case NVPTX::BI__nvvm_atom_sys_min_gen_ull: 8899 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys); 8900 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui: 8901 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta); 8902 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui: 8903 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta); 8904 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui: 8905 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys); 8906 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui: 8907 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys); 8908 case NVPTX::BI__nvvm_atom_cta_and_gen_i: 8909 case NVPTX::BI__nvvm_atom_cta_and_gen_l: 8910 case NVPTX::BI__nvvm_atom_cta_and_gen_ll: 8911 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta); 8912 case NVPTX::BI__nvvm_atom_sys_and_gen_i: 8913 case NVPTX::BI__nvvm_atom_sys_and_gen_l: 8914 case NVPTX::BI__nvvm_atom_sys_and_gen_ll: 8915 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys); 8916 case NVPTX::BI__nvvm_atom_cta_or_gen_i: 8917 case NVPTX::BI__nvvm_atom_cta_or_gen_l: 8918 case NVPTX::BI__nvvm_atom_cta_or_gen_ll: 8919 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta); 8920 case NVPTX::BI__nvvm_atom_sys_or_gen_i: 8921 case NVPTX::BI__nvvm_atom_sys_or_gen_l: 8922 case NVPTX::BI__nvvm_atom_sys_or_gen_ll: 8923 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys); 8924 case NVPTX::BI__nvvm_atom_cta_xor_gen_i: 8925 case NVPTX::BI__nvvm_atom_cta_xor_gen_l: 8926 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll: 8927 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta); 8928 case NVPTX::BI__nvvm_atom_sys_xor_gen_i: 8929 case NVPTX::BI__nvvm_atom_sys_xor_gen_l: 8930 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll: 8931 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys); 8932 case NVPTX::BI__nvvm_atom_cta_cas_gen_i: 8933 case NVPTX::BI__nvvm_atom_cta_cas_gen_l: 8934 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: { 8935 Value *Ptr = EmitScalarExpr(E->getArg(0)); 8936 return Builder.CreateCall( 8937 CGM.getIntrinsic( 8938 Intrinsic::nvvm_atomic_cas_gen_i_cta, 8939 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 8940 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 8941 } 8942 case NVPTX::BI__nvvm_atom_sys_cas_gen_i: 8943 case NVPTX::BI__nvvm_atom_sys_cas_gen_l: 8944 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: { 8945 Value *Ptr = EmitScalarExpr(E->getArg(0)); 8946 return Builder.CreateCall( 8947 CGM.getIntrinsic( 8948 Intrinsic::nvvm_atomic_cas_gen_i_sys, 8949 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 8950 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 8951 } 8952 default: 8953 return nullptr; 8954 } 8955 } 8956 8957 Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 8958 const CallExpr *E) { 8959 switch (BuiltinID) { 8960 case WebAssembly::BI__builtin_wasm_current_memory: { 8961 llvm::Type *ResultType = ConvertType(E->getType()); 8962 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType); 8963 return Builder.CreateCall(Callee); 8964 } 8965 case WebAssembly::BI__builtin_wasm_grow_memory: { 8966 Value *X = EmitScalarExpr(E->getArg(0)); 8967 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType()); 8968 return Builder.CreateCall(Callee, X); 8969 } 8970 8971 default: 8972 return nullptr; 8973 } 8974 } 8975