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 "ConstantEmitter.h" 20 #include "TargetInfo.h" 21 #include "clang/AST/ASTContext.h" 22 #include "clang/AST/Decl.h" 23 #include "clang/Analysis/Analyses/OSLog.h" 24 #include "clang/Basic/TargetBuiltins.h" 25 #include "clang/Basic/TargetInfo.h" 26 #include "clang/CodeGen/CGFunctionInfo.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/IR/CallSite.h" 29 #include "llvm/IR/DataLayout.h" 30 #include "llvm/IR/InlineAsm.h" 31 #include "llvm/IR/Intrinsics.h" 32 #include "llvm/IR/MDBuilder.h" 33 #include "llvm/Support/ConvertUTF.h" 34 #include "llvm/Support/ScopedPrinter.h" 35 #include "llvm/Support/TargetParser.h" 36 #include <sstream> 37 38 using namespace clang; 39 using namespace CodeGen; 40 using namespace llvm; 41 42 static 43 int64_t clamp(int64_t Value, int64_t Low, int64_t High) { 44 return std::min(High, std::max(Low, Value)); 45 } 46 47 /// getBuiltinLibFunction - Given a builtin id for a function like 48 /// "__builtin_fabsf", return a Function* for "fabsf". 49 llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, 50 unsigned BuiltinID) { 51 assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); 52 53 // Get the name, skip over the __builtin_ prefix (if necessary). 54 StringRef Name; 55 GlobalDecl D(FD); 56 57 // If the builtin has been declared explicitly with an assembler label, 58 // use the mangled name. This differs from the plain label on platforms 59 // that prefix labels. 60 if (FD->hasAttr<AsmLabelAttr>()) 61 Name = getMangledName(D); 62 else 63 Name = Context.BuiltinInfo.getName(BuiltinID) + 10; 64 65 llvm::FunctionType *Ty = 66 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); 67 68 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); 69 } 70 71 /// Emit the conversions required to turn the given value into an 72 /// integer of the given size. 73 static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V, 74 QualType T, llvm::IntegerType *IntType) { 75 V = CGF.EmitToMemory(V, T); 76 77 if (V->getType()->isPointerTy()) 78 return CGF.Builder.CreatePtrToInt(V, IntType); 79 80 assert(V->getType() == IntType); 81 return V; 82 } 83 84 static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, 85 QualType T, llvm::Type *ResultType) { 86 V = CGF.EmitFromMemory(V, T); 87 88 if (ResultType->isPointerTy()) 89 return CGF.Builder.CreateIntToPtr(V, ResultType); 90 91 assert(V->getType() == ResultType); 92 return V; 93 } 94 95 /// Utility to insert an atomic instruction based on Instrinsic::ID 96 /// and the expression node. 97 static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF, 98 llvm::AtomicRMWInst::BinOp Kind, 99 const CallExpr *E) { 100 QualType T = E->getType(); 101 assert(E->getArg(0)->getType()->isPointerType()); 102 assert(CGF.getContext().hasSameUnqualifiedType(T, 103 E->getArg(0)->getType()->getPointeeType())); 104 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 105 106 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 107 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 108 109 llvm::IntegerType *IntType = 110 llvm::IntegerType::get(CGF.getLLVMContext(), 111 CGF.getContext().getTypeSize(T)); 112 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 113 114 llvm::Value *Args[2]; 115 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 116 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 117 llvm::Type *ValueType = Args[1]->getType(); 118 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 119 120 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 121 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 122 return EmitFromInt(CGF, Result, T, ValueType); 123 } 124 125 static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) { 126 Value *Val = CGF.EmitScalarExpr(E->getArg(0)); 127 Value *Address = CGF.EmitScalarExpr(E->getArg(1)); 128 129 // Convert the type of the pointer to a pointer to the stored type. 130 Val = CGF.EmitToMemory(Val, E->getArg(0)->getType()); 131 Value *BC = CGF.Builder.CreateBitCast( 132 Address, llvm::PointerType::getUnqual(Val->getType()), "cast"); 133 LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType()); 134 LV.setNontemporal(true); 135 CGF.EmitStoreOfScalar(Val, LV, false); 136 return nullptr; 137 } 138 139 static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) { 140 Value *Address = CGF.EmitScalarExpr(E->getArg(0)); 141 142 LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType()); 143 LV.setNontemporal(true); 144 return CGF.EmitLoadOfScalar(LV, E->getExprLoc()); 145 } 146 147 static RValue EmitBinaryAtomic(CodeGenFunction &CGF, 148 llvm::AtomicRMWInst::BinOp Kind, 149 const CallExpr *E) { 150 return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E)); 151 } 152 153 /// Utility to insert an atomic instruction based Instrinsic::ID and 154 /// the expression node, where the return value is the result of the 155 /// operation. 156 static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 157 llvm::AtomicRMWInst::BinOp Kind, 158 const CallExpr *E, 159 Instruction::BinaryOps Op, 160 bool Invert = false) { 161 QualType T = E->getType(); 162 assert(E->getArg(0)->getType()->isPointerType()); 163 assert(CGF.getContext().hasSameUnqualifiedType(T, 164 E->getArg(0)->getType()->getPointeeType())); 165 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 166 167 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 168 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 169 170 llvm::IntegerType *IntType = 171 llvm::IntegerType::get(CGF.getLLVMContext(), 172 CGF.getContext().getTypeSize(T)); 173 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 174 175 llvm::Value *Args[2]; 176 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 177 llvm::Type *ValueType = Args[1]->getType(); 178 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 179 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 180 181 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 182 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 183 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); 184 if (Invert) 185 Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result, 186 llvm::ConstantInt::get(IntType, -1)); 187 Result = EmitFromInt(CGF, Result, T, ValueType); 188 return RValue::get(Result); 189 } 190 191 /// @brief Utility to insert an atomic cmpxchg instruction. 192 /// 193 /// @param CGF The current codegen function. 194 /// @param E Builtin call expression to convert to cmpxchg. 195 /// arg0 - address to operate on 196 /// arg1 - value to compare with 197 /// arg2 - new value 198 /// @param ReturnBool Specifies whether to return success flag of 199 /// cmpxchg result or the old value. 200 /// 201 /// @returns result of cmpxchg, according to ReturnBool 202 static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E, 203 bool ReturnBool) { 204 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType(); 205 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 206 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 207 208 llvm::IntegerType *IntType = llvm::IntegerType::get( 209 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T)); 210 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 211 212 Value *Args[3]; 213 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 214 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 215 llvm::Type *ValueType = Args[1]->getType(); 216 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 217 Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType); 218 219 Value *Pair = CGF.Builder.CreateAtomicCmpXchg( 220 Args[0], Args[1], Args[2], llvm::AtomicOrdering::SequentiallyConsistent, 221 llvm::AtomicOrdering::SequentiallyConsistent); 222 if (ReturnBool) 223 // Extract boolean success flag and zext it to int. 224 return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1), 225 CGF.ConvertType(E->getType())); 226 else 227 // Extract old value and emit it using the same type as compare value. 228 return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T, 229 ValueType); 230 } 231 232 // Emit a simple mangled intrinsic that has 1 argument and a return type 233 // matching the argument type. 234 static Value *emitUnaryBuiltin(CodeGenFunction &CGF, 235 const CallExpr *E, 236 unsigned IntrinsicID) { 237 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 238 239 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 240 return CGF.Builder.CreateCall(F, Src0); 241 } 242 243 // Emit an intrinsic that has 2 operands of the same type as its result. 244 static Value *emitBinaryBuiltin(CodeGenFunction &CGF, 245 const CallExpr *E, 246 unsigned IntrinsicID) { 247 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 248 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 249 250 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 251 return CGF.Builder.CreateCall(F, { Src0, Src1 }); 252 } 253 254 // Emit an intrinsic that has 3 operands of the same type as its result. 255 static Value *emitTernaryBuiltin(CodeGenFunction &CGF, 256 const CallExpr *E, 257 unsigned IntrinsicID) { 258 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 259 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 260 llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2)); 261 262 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 263 return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 }); 264 } 265 266 // Emit an intrinsic that has 1 float or double operand, and 1 integer. 267 static Value *emitFPIntBuiltin(CodeGenFunction &CGF, 268 const CallExpr *E, 269 unsigned IntrinsicID) { 270 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 271 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 272 273 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 274 return CGF.Builder.CreateCall(F, {Src0, Src1}); 275 } 276 277 /// EmitFAbs - Emit a call to @llvm.fabs(). 278 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) { 279 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType()); 280 llvm::CallInst *Call = CGF.Builder.CreateCall(F, V); 281 Call->setDoesNotAccessMemory(); 282 return Call; 283 } 284 285 /// Emit the computation of the sign bit for a floating point value. Returns 286 /// the i1 sign bit value. 287 static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) { 288 LLVMContext &C = CGF.CGM.getLLVMContext(); 289 290 llvm::Type *Ty = V->getType(); 291 int Width = Ty->getPrimitiveSizeInBits(); 292 llvm::Type *IntTy = llvm::IntegerType::get(C, Width); 293 V = CGF.Builder.CreateBitCast(V, IntTy); 294 if (Ty->isPPC_FP128Ty()) { 295 // We want the sign bit of the higher-order double. The bitcast we just 296 // did works as if the double-double was stored to memory and then 297 // read as an i128. The "store" will put the higher-order double in the 298 // lower address in both little- and big-Endian modes, but the "load" 299 // will treat those bits as a different part of the i128: the low bits in 300 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian 301 // we need to shift the high bits down to the low before truncating. 302 Width >>= 1; 303 if (CGF.getTarget().isBigEndian()) { 304 Value *ShiftCst = llvm::ConstantInt::get(IntTy, Width); 305 V = CGF.Builder.CreateLShr(V, ShiftCst); 306 } 307 // We are truncating value in order to extract the higher-order 308 // double, which we will be using to extract the sign from. 309 IntTy = llvm::IntegerType::get(C, Width); 310 V = CGF.Builder.CreateTrunc(V, IntTy); 311 } 312 Value *Zero = llvm::Constant::getNullValue(IntTy); 313 return CGF.Builder.CreateICmpSLT(V, Zero); 314 } 315 316 static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, 317 const CallExpr *E, llvm::Constant *calleeValue) { 318 CGCallee callee = CGCallee::forDirect(calleeValue, FD); 319 return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); 320 } 321 322 /// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.* 323 /// depending on IntrinsicID. 324 /// 325 /// \arg CGF The current codegen function. 326 /// \arg IntrinsicID The ID for the Intrinsic we wish to generate. 327 /// \arg X The first argument to the llvm.*.with.overflow.*. 328 /// \arg Y The second argument to the llvm.*.with.overflow.*. 329 /// \arg Carry The carry returned by the llvm.*.with.overflow.*. 330 /// \returns The result (i.e. sum/product) returned by the intrinsic. 331 static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF, 332 const llvm::Intrinsic::ID IntrinsicID, 333 llvm::Value *X, llvm::Value *Y, 334 llvm::Value *&Carry) { 335 // Make sure we have integers of the same width. 336 assert(X->getType() == Y->getType() && 337 "Arguments must be the same type. (Did you forget to make sure both " 338 "arguments have the same integer width?)"); 339 340 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType()); 341 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y}); 342 Carry = CGF.Builder.CreateExtractValue(Tmp, 1); 343 return CGF.Builder.CreateExtractValue(Tmp, 0); 344 } 345 346 static Value *emitRangedBuiltin(CodeGenFunction &CGF, 347 unsigned IntrinsicID, 348 int low, int high) { 349 llvm::MDBuilder MDHelper(CGF.getLLVMContext()); 350 llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high)); 351 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {}); 352 llvm::Instruction *Call = CGF.Builder.CreateCall(F); 353 Call->setMetadata(llvm::LLVMContext::MD_range, RNode); 354 return Call; 355 } 356 357 namespace { 358 struct WidthAndSignedness { 359 unsigned Width; 360 bool Signed; 361 }; 362 } 363 364 static WidthAndSignedness 365 getIntegerWidthAndSignedness(const clang::ASTContext &context, 366 const clang::QualType Type) { 367 assert(Type->isIntegerType() && "Given type is not an integer."); 368 unsigned Width = Type->isBooleanType() ? 1 : context.getTypeInfo(Type).Width; 369 bool Signed = Type->isSignedIntegerType(); 370 return {Width, Signed}; 371 } 372 373 // Given one or more integer types, this function produces an integer type that 374 // encompasses them: any value in one of the given types could be expressed in 375 // the encompassing type. 376 static struct WidthAndSignedness 377 EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) { 378 assert(Types.size() > 0 && "Empty list of types."); 379 380 // If any of the given types is signed, we must return a signed type. 381 bool Signed = false; 382 for (const auto &Type : Types) { 383 Signed |= Type.Signed; 384 } 385 386 // The encompassing type must have a width greater than or equal to the width 387 // of the specified types. Aditionally, if the encompassing type is signed, 388 // its width must be strictly greater than the width of any unsigned types 389 // given. 390 unsigned Width = 0; 391 for (const auto &Type : Types) { 392 unsigned MinWidth = Type.Width + (Signed && !Type.Signed); 393 if (Width < MinWidth) { 394 Width = MinWidth; 395 } 396 } 397 398 return {Width, Signed}; 399 } 400 401 Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) { 402 llvm::Type *DestType = Int8PtrTy; 403 if (ArgValue->getType() != DestType) 404 ArgValue = 405 Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data()); 406 407 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend; 408 return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue); 409 } 410 411 /// Checks if using the result of __builtin_object_size(p, @p From) in place of 412 /// __builtin_object_size(p, @p To) is correct 413 static bool areBOSTypesCompatible(int From, int To) { 414 // Note: Our __builtin_object_size implementation currently treats Type=0 and 415 // Type=2 identically. Encoding this implementation detail here may make 416 // improving __builtin_object_size difficult in the future, so it's omitted. 417 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2); 418 } 419 420 static llvm::Value * 421 getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) { 422 return ConstantInt::get(ResType, (Type & 2) ? 0 : -1, /*isSigned=*/true); 423 } 424 425 llvm::Value * 426 CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, 427 llvm::IntegerType *ResType, 428 llvm::Value *EmittedE) { 429 uint64_t ObjectSize; 430 if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type)) 431 return emitBuiltinObjectSize(E, Type, ResType, EmittedE); 432 return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); 433 } 434 435 /// Returns a Value corresponding to the size of the given expression. 436 /// This Value may be either of the following: 437 /// - A llvm::Argument (if E is a param with the pass_object_size attribute on 438 /// it) 439 /// - A call to the @llvm.objectsize intrinsic 440 /// 441 /// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null 442 /// and we wouldn't otherwise try to reference a pass_object_size parameter, 443 /// we'll call @llvm.objectsize on EmittedE, rather than emitting E. 444 llvm::Value * 445 CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, 446 llvm::IntegerType *ResType, 447 llvm::Value *EmittedE) { 448 // We need to reference an argument if the pointer is a parameter with the 449 // pass_object_size attribute. 450 if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) { 451 auto *Param = dyn_cast<ParmVarDecl>(D->getDecl()); 452 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>(); 453 if (Param != nullptr && PS != nullptr && 454 areBOSTypesCompatible(PS->getType(), Type)) { 455 auto Iter = SizeArguments.find(Param); 456 assert(Iter != SizeArguments.end()); 457 458 const ImplicitParamDecl *D = Iter->second; 459 auto DIter = LocalDeclMap.find(D); 460 assert(DIter != LocalDeclMap.end()); 461 462 return EmitLoadOfScalar(DIter->second, /*volatile=*/false, 463 getContext().getSizeType(), E->getLocStart()); 464 } 465 } 466 467 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't 468 // evaluate E for side-effects. In either case, we shouldn't lower to 469 // @llvm.objectsize. 470 if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext()))) 471 return getDefaultBuiltinObjectSizeResult(Type, ResType); 472 473 Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E); 474 assert(Ptr->getType()->isPointerTy() && 475 "Non-pointer passed to __builtin_object_size?"); 476 477 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()}); 478 479 // LLVM only supports 0 and 2, make sure that we pass along that as a boolean. 480 Value *Min = Builder.getInt1((Type & 2) != 0); 481 // For GCC compatability, __builtin_object_size treat NULL as unknown size. 482 Value *NullIsUnknown = Builder.getTrue(); 483 return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown}); 484 } 485 486 // Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we 487 // handle them here. 488 enum class CodeGenFunction::MSVCIntrin { 489 _BitScanForward, 490 _BitScanReverse, 491 _InterlockedAnd, 492 _InterlockedDecrement, 493 _InterlockedExchange, 494 _InterlockedExchangeAdd, 495 _InterlockedExchangeSub, 496 _InterlockedIncrement, 497 _InterlockedOr, 498 _InterlockedXor, 499 _interlockedbittestandset, 500 __fastfail, 501 }; 502 503 Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, 504 const CallExpr *E) { 505 switch (BuiltinID) { 506 case MSVCIntrin::_BitScanForward: 507 case MSVCIntrin::_BitScanReverse: { 508 Value *ArgValue = EmitScalarExpr(E->getArg(1)); 509 510 llvm::Type *ArgType = ArgValue->getType(); 511 llvm::Type *IndexType = 512 EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); 513 llvm::Type *ResultType = ConvertType(E->getType()); 514 515 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 516 Value *ResZero = llvm::Constant::getNullValue(ResultType); 517 Value *ResOne = llvm::ConstantInt::get(ResultType, 1); 518 519 BasicBlock *Begin = Builder.GetInsertBlock(); 520 BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn); 521 Builder.SetInsertPoint(End); 522 PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result"); 523 524 Builder.SetInsertPoint(Begin); 525 Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); 526 BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn); 527 Builder.CreateCondBr(IsZero, End, NotZero); 528 Result->addIncoming(ResZero, Begin); 529 530 Builder.SetInsertPoint(NotZero); 531 Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); 532 533 if (BuiltinID == MSVCIntrin::_BitScanForward) { 534 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 535 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 536 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 537 Builder.CreateStore(ZeroCount, IndexAddress, false); 538 } else { 539 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 540 Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); 541 542 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 543 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 544 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 545 Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); 546 Builder.CreateStore(Index, IndexAddress, false); 547 } 548 Builder.CreateBr(End); 549 Result->addIncoming(ResOne, NotZero); 550 551 Builder.SetInsertPoint(End); 552 return Result; 553 } 554 case MSVCIntrin::_InterlockedAnd: 555 return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E); 556 case MSVCIntrin::_InterlockedExchange: 557 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E); 558 case MSVCIntrin::_InterlockedExchangeAdd: 559 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E); 560 case MSVCIntrin::_InterlockedExchangeSub: 561 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Sub, E); 562 case MSVCIntrin::_InterlockedOr: 563 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E); 564 case MSVCIntrin::_InterlockedXor: 565 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E); 566 567 case MSVCIntrin::_interlockedbittestandset: { 568 llvm::Value *Addr = EmitScalarExpr(E->getArg(0)); 569 llvm::Value *Bit = EmitScalarExpr(E->getArg(1)); 570 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 571 AtomicRMWInst::Or, Addr, 572 Builder.CreateShl(ConstantInt::get(Bit->getType(), 1), Bit), 573 llvm::AtomicOrdering::SequentiallyConsistent); 574 // Shift the relevant bit to the least significant position, truncate to 575 // the result type, and test the low bit. 576 llvm::Value *Shifted = Builder.CreateLShr(RMWI, Bit); 577 llvm::Value *Truncated = 578 Builder.CreateTrunc(Shifted, ConvertType(E->getType())); 579 return Builder.CreateAnd(Truncated, 580 ConstantInt::get(Truncated->getType(), 1)); 581 } 582 583 case MSVCIntrin::_InterlockedDecrement: { 584 llvm::Type *IntTy = ConvertType(E->getType()); 585 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 586 AtomicRMWInst::Sub, 587 EmitScalarExpr(E->getArg(0)), 588 ConstantInt::get(IntTy, 1), 589 llvm::AtomicOrdering::SequentiallyConsistent); 590 return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1)); 591 } 592 case MSVCIntrin::_InterlockedIncrement: { 593 llvm::Type *IntTy = ConvertType(E->getType()); 594 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 595 AtomicRMWInst::Add, 596 EmitScalarExpr(E->getArg(0)), 597 ConstantInt::get(IntTy, 1), 598 llvm::AtomicOrdering::SequentiallyConsistent); 599 return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1)); 600 } 601 602 case MSVCIntrin::__fastfail: { 603 // Request immediate process termination from the kernel. The instruction 604 // sequences to do this are documented on MSDN: 605 // https://msdn.microsoft.com/en-us/library/dn774154.aspx 606 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch(); 607 StringRef Asm, Constraints; 608 switch (ISA) { 609 default: 610 ErrorUnsupported(E, "__fastfail call for this architecture"); 611 break; 612 case llvm::Triple::x86: 613 case llvm::Triple::x86_64: 614 Asm = "int $$0x29"; 615 Constraints = "{cx}"; 616 break; 617 case llvm::Triple::thumb: 618 Asm = "udf #251"; 619 Constraints = "{r0}"; 620 break; 621 } 622 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false); 623 llvm::InlineAsm *IA = 624 llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true); 625 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get( 626 getLLVMContext(), llvm::AttributeList::FunctionIndex, 627 llvm::Attribute::NoReturn); 628 CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0))); 629 CS.setAttributes(NoReturnAttr); 630 return CS.getInstruction(); 631 } 632 } 633 llvm_unreachable("Incorrect MSVC intrinsic!"); 634 } 635 636 namespace { 637 // ARC cleanup for __builtin_os_log_format 638 struct CallObjCArcUse final : EHScopeStack::Cleanup { 639 CallObjCArcUse(llvm::Value *object) : object(object) {} 640 llvm::Value *object; 641 642 void Emit(CodeGenFunction &CGF, Flags flags) override { 643 CGF.EmitARCIntrinsicUse(object); 644 } 645 }; 646 } 647 648 Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E, 649 BuiltinCheckKind Kind) { 650 assert((Kind == BCK_CLZPassedZero || Kind == BCK_CTZPassedZero) 651 && "Unsupported builtin check kind"); 652 653 Value *ArgValue = EmitScalarExpr(E); 654 if (!SanOpts.has(SanitizerKind::Builtin) || !getTarget().isCLZForZeroUndef()) 655 return ArgValue; 656 657 SanitizerScope SanScope(this); 658 Value *Cond = Builder.CreateICmpNE( 659 ArgValue, llvm::Constant::getNullValue(ArgValue->getType())); 660 EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin), 661 SanitizerHandler::InvalidBuiltin, 662 {EmitCheckSourceLocation(E->getExprLoc()), 663 llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)}, 664 None); 665 return ArgValue; 666 } 667 668 /// Get the argument type for arguments to os_log_helper. 669 static CanQualType getOSLogArgType(ASTContext &C, int Size) { 670 QualType UnsignedTy = C.getIntTypeForBitwidth(Size * 8, /*Signed=*/false); 671 return C.getCanonicalType(UnsignedTy); 672 } 673 674 llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction( 675 const analyze_os_log::OSLogBufferLayout &Layout, 676 CharUnits BufferAlignment) { 677 ASTContext &Ctx = getContext(); 678 679 llvm::SmallString<64> Name; 680 { 681 raw_svector_ostream OS(Name); 682 OS << "__os_log_helper"; 683 OS << "_" << BufferAlignment.getQuantity(); 684 OS << "_" << int(Layout.getSummaryByte()); 685 OS << "_" << int(Layout.getNumArgsByte()); 686 for (const auto &Item : Layout.Items) 687 OS << "_" << int(Item.getSizeByte()) << "_" 688 << int(Item.getDescriptorByte()); 689 } 690 691 if (llvm::Function *F = CGM.getModule().getFunction(Name)) 692 return F; 693 694 llvm::SmallVector<ImplicitParamDecl, 4> Params; 695 Params.emplace_back(Ctx, nullptr, SourceLocation(), &Ctx.Idents.get("buffer"), 696 Ctx.VoidPtrTy, ImplicitParamDecl::Other); 697 698 for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) { 699 char Size = Layout.Items[I].getSizeByte(); 700 if (!Size) 701 continue; 702 703 Params.emplace_back( 704 Ctx, nullptr, SourceLocation(), 705 &Ctx.Idents.get(std::string("arg") + llvm::to_string(I)), 706 getOSLogArgType(Ctx, Size), ImplicitParamDecl::Other); 707 } 708 709 FunctionArgList Args; 710 for (auto &P : Params) 711 Args.push_back(&P); 712 713 // The helper function has linkonce_odr linkage to enable the linker to merge 714 // identical functions. To ensure the merging always happens, 'noinline' is 715 // attached to the function when compiling with -Oz. 716 const CGFunctionInfo &FI = 717 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args); 718 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI); 719 llvm::Function *Fn = llvm::Function::Create( 720 FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule()); 721 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); 722 CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn); 723 CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn); 724 725 // Attach 'noinline' at -Oz. 726 if (CGM.getCodeGenOpts().OptimizeSize == 2) 727 Fn->addFnAttr(llvm::Attribute::NoInline); 728 729 auto NL = ApplyDebugLocation::CreateEmpty(*this); 730 IdentifierInfo *II = &Ctx.Idents.get(Name); 731 FunctionDecl *FD = FunctionDecl::Create( 732 Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, 733 Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false); 734 735 StartFunction(FD, Ctx.VoidTy, Fn, FI, Args); 736 737 // Create a scope with an artificial location for the body of this function. 738 auto AL = ApplyDebugLocation::CreateArtificial(*this); 739 740 CharUnits Offset; 741 Address BufAddr(Builder.CreateLoad(GetAddrOfLocalVar(&Params[0]), "buf"), 742 BufferAlignment); 743 Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()), 744 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary")); 745 Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()), 746 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs")); 747 748 unsigned I = 1; 749 for (const auto &Item : Layout.Items) { 750 Builder.CreateStore( 751 Builder.getInt8(Item.getDescriptorByte()), 752 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor")); 753 Builder.CreateStore( 754 Builder.getInt8(Item.getSizeByte()), 755 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize")); 756 757 CharUnits Size = Item.size(); 758 if (!Size.getQuantity()) 759 continue; 760 761 Address Arg = GetAddrOfLocalVar(&Params[I]); 762 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset, "argData"); 763 Addr = Builder.CreateBitCast(Addr, Arg.getPointer()->getType(), 764 "argDataCast"); 765 Builder.CreateStore(Builder.CreateLoad(Arg), Addr); 766 Offset += Size; 767 ++I; 768 } 769 770 FinishFunction(); 771 772 return Fn; 773 } 774 775 RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { 776 assert(E.getNumArgs() >= 2 && 777 "__builtin_os_log_format takes at least 2 arguments"); 778 ASTContext &Ctx = getContext(); 779 analyze_os_log::OSLogBufferLayout Layout; 780 analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout); 781 Address BufAddr = EmitPointerWithAlignment(E.getArg(0)); 782 llvm::SmallVector<llvm::Value *, 4> RetainableOperands; 783 784 // Ignore argument 1, the format string. It is not currently used. 785 CallArgList Args; 786 Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy); 787 788 for (const auto &Item : Layout.Items) { 789 int Size = Item.getSizeByte(); 790 if (!Size) 791 continue; 792 793 llvm::Value *ArgVal; 794 795 if (const Expr *TheExpr = Item.getExpr()) { 796 ArgVal = EmitScalarExpr(TheExpr, /*Ignore*/ false); 797 798 // Check if this is a retainable type. 799 if (TheExpr->getType()->isObjCRetainableType()) { 800 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar && 801 "Only scalar can be a ObjC retainable type"); 802 // Check if the object is constant, if not, save it in 803 // RetainableOperands. 804 if (!isa<Constant>(ArgVal)) 805 RetainableOperands.push_back(ArgVal); 806 } 807 } else { 808 ArgVal = Builder.getInt32(Item.getConstValue().getQuantity()); 809 } 810 811 unsigned ArgValSize = 812 CGM.getDataLayout().getTypeSizeInBits(ArgVal->getType()); 813 llvm::IntegerType *IntTy = llvm::Type::getIntNTy(getLLVMContext(), 814 ArgValSize); 815 ArgVal = Builder.CreateBitOrPointerCast(ArgVal, IntTy); 816 CanQualType ArgTy = getOSLogArgType(Ctx, Size); 817 // If ArgVal has type x86_fp80, zero-extend ArgVal. 818 ArgVal = Builder.CreateZExtOrBitCast(ArgVal, ConvertType(ArgTy)); 819 Args.add(RValue::get(ArgVal), ArgTy); 820 } 821 822 const CGFunctionInfo &FI = 823 CGM.getTypes().arrangeBuiltinFunctionCall(Ctx.VoidTy, Args); 824 llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction( 825 Layout, BufAddr.getAlignment()); 826 EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args); 827 828 // Push a clang.arc.use cleanup for each object in RetainableOperands. The 829 // cleanup will cause the use to appear after the final log call, keeping 830 // the object valid while it’s held in the log buffer. Note that if there’s 831 // a release cleanup on the object, it will already be active; since 832 // cleanups are emitted in reverse order, the use will occur before the 833 // object is released. 834 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount && 835 CGM.getCodeGenOpts().OptimizationLevel != 0) 836 for (llvm::Value *Object : RetainableOperands) 837 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), Object); 838 839 return RValue::get(BufAddr.getPointer()); 840 } 841 842 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 843 unsigned BuiltinID, const CallExpr *E, 844 ReturnValueSlot ReturnValue) { 845 // See if we can constant fold this builtin. If so, don't emit it at all. 846 Expr::EvalResult Result; 847 if (E->EvaluateAsRValue(Result, CGM.getContext()) && 848 !Result.hasSideEffects()) { 849 if (Result.Val.isInt()) 850 return RValue::get(llvm::ConstantInt::get(getLLVMContext(), 851 Result.Val.getInt())); 852 if (Result.Val.isFloat()) 853 return RValue::get(llvm::ConstantFP::get(getLLVMContext(), 854 Result.Val.getFloat())); 855 } 856 857 // There are LLVM math intrinsics/instructions corresponding to math library 858 // functions except the LLVM op will never set errno while the math library 859 // might. Also, math builtins have the same semantics as their math library 860 // twins. Thus, we can transform math library and builtin calls to their 861 // LLVM counterparts if the call is marked 'const' (known to never set errno). 862 if (FD->hasAttr<ConstAttr>()) { 863 switch (BuiltinID) { 864 case Builtin::BIceil: 865 case Builtin::BIceilf: 866 case Builtin::BIceill: 867 case Builtin::BI__builtin_ceil: 868 case Builtin::BI__builtin_ceilf: 869 case Builtin::BI__builtin_ceill: 870 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil)); 871 872 case Builtin::BIcopysign: 873 case Builtin::BIcopysignf: 874 case Builtin::BIcopysignl: 875 case Builtin::BI__builtin_copysign: 876 case Builtin::BI__builtin_copysignf: 877 case Builtin::BI__builtin_copysignl: 878 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign)); 879 880 case Builtin::BIcos: 881 case Builtin::BIcosf: 882 case Builtin::BIcosl: 883 case Builtin::BI__builtin_cos: 884 case Builtin::BI__builtin_cosf: 885 case Builtin::BI__builtin_cosl: 886 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::cos)); 887 888 case Builtin::BIexp: 889 case Builtin::BIexpf: 890 case Builtin::BIexpl: 891 case Builtin::BI__builtin_exp: 892 case Builtin::BI__builtin_expf: 893 case Builtin::BI__builtin_expl: 894 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::exp)); 895 896 case Builtin::BIexp2: 897 case Builtin::BIexp2f: 898 case Builtin::BIexp2l: 899 case Builtin::BI__builtin_exp2: 900 case Builtin::BI__builtin_exp2f: 901 case Builtin::BI__builtin_exp2l: 902 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::exp2)); 903 904 case Builtin::BIfabs: 905 case Builtin::BIfabsf: 906 case Builtin::BIfabsl: 907 case Builtin::BI__builtin_fabs: 908 case Builtin::BI__builtin_fabsf: 909 case Builtin::BI__builtin_fabsl: 910 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs)); 911 912 case Builtin::BIfloor: 913 case Builtin::BIfloorf: 914 case Builtin::BIfloorl: 915 case Builtin::BI__builtin_floor: 916 case Builtin::BI__builtin_floorf: 917 case Builtin::BI__builtin_floorl: 918 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor)); 919 920 case Builtin::BIfma: 921 case Builtin::BIfmaf: 922 case Builtin::BIfmal: 923 case Builtin::BI__builtin_fma: 924 case Builtin::BI__builtin_fmaf: 925 case Builtin::BI__builtin_fmal: 926 return RValue::get(emitTernaryBuiltin(*this, E, Intrinsic::fma)); 927 928 case Builtin::BIfmax: 929 case Builtin::BIfmaxf: 930 case Builtin::BIfmaxl: 931 case Builtin::BI__builtin_fmax: 932 case Builtin::BI__builtin_fmaxf: 933 case Builtin::BI__builtin_fmaxl: 934 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum)); 935 936 case Builtin::BIfmin: 937 case Builtin::BIfminf: 938 case Builtin::BIfminl: 939 case Builtin::BI__builtin_fmin: 940 case Builtin::BI__builtin_fminf: 941 case Builtin::BI__builtin_fminl: 942 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum)); 943 944 // fmod() is a special-case. It maps to the frem instruction rather than an 945 // LLVM intrinsic. 946 case Builtin::BIfmod: 947 case Builtin::BIfmodf: 948 case Builtin::BIfmodl: 949 case Builtin::BI__builtin_fmod: 950 case Builtin::BI__builtin_fmodf: 951 case Builtin::BI__builtin_fmodl: { 952 Value *Arg1 = EmitScalarExpr(E->getArg(0)); 953 Value *Arg2 = EmitScalarExpr(E->getArg(1)); 954 return RValue::get(Builder.CreateFRem(Arg1, Arg2, "fmod")); 955 } 956 957 case Builtin::BIlog: 958 case Builtin::BIlogf: 959 case Builtin::BIlogl: 960 case Builtin::BI__builtin_log: 961 case Builtin::BI__builtin_logf: 962 case Builtin::BI__builtin_logl: 963 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::log)); 964 965 case Builtin::BIlog10: 966 case Builtin::BIlog10f: 967 case Builtin::BIlog10l: 968 case Builtin::BI__builtin_log10: 969 case Builtin::BI__builtin_log10f: 970 case Builtin::BI__builtin_log10l: 971 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::log10)); 972 973 case Builtin::BIlog2: 974 case Builtin::BIlog2f: 975 case Builtin::BIlog2l: 976 case Builtin::BI__builtin_log2: 977 case Builtin::BI__builtin_log2f: 978 case Builtin::BI__builtin_log2l: 979 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::log2)); 980 981 case Builtin::BInearbyint: 982 case Builtin::BInearbyintf: 983 case Builtin::BInearbyintl: 984 case Builtin::BI__builtin_nearbyint: 985 case Builtin::BI__builtin_nearbyintf: 986 case Builtin::BI__builtin_nearbyintl: 987 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint)); 988 989 case Builtin::BIpow: 990 case Builtin::BIpowf: 991 case Builtin::BIpowl: 992 case Builtin::BI__builtin_pow: 993 case Builtin::BI__builtin_powf: 994 case Builtin::BI__builtin_powl: 995 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::pow)); 996 997 case Builtin::BIrint: 998 case Builtin::BIrintf: 999 case Builtin::BIrintl: 1000 case Builtin::BI__builtin_rint: 1001 case Builtin::BI__builtin_rintf: 1002 case Builtin::BI__builtin_rintl: 1003 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint)); 1004 1005 case Builtin::BIround: 1006 case Builtin::BIroundf: 1007 case Builtin::BIroundl: 1008 case Builtin::BI__builtin_round: 1009 case Builtin::BI__builtin_roundf: 1010 case Builtin::BI__builtin_roundl: 1011 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round)); 1012 1013 case Builtin::BIsin: 1014 case Builtin::BIsinf: 1015 case Builtin::BIsinl: 1016 case Builtin::BI__builtin_sin: 1017 case Builtin::BI__builtin_sinf: 1018 case Builtin::BI__builtin_sinl: 1019 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::sin)); 1020 1021 case Builtin::BIsqrt: 1022 case Builtin::BIsqrtf: 1023 case Builtin::BIsqrtl: 1024 case Builtin::BI__builtin_sqrt: 1025 case Builtin::BI__builtin_sqrtf: 1026 case Builtin::BI__builtin_sqrtl: 1027 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::sqrt)); 1028 1029 case Builtin::BItrunc: 1030 case Builtin::BItruncf: 1031 case Builtin::BItruncl: 1032 case Builtin::BI__builtin_trunc: 1033 case Builtin::BI__builtin_truncf: 1034 case Builtin::BI__builtin_truncl: 1035 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc)); 1036 1037 default: 1038 break; 1039 } 1040 } 1041 1042 switch (BuiltinID) { 1043 default: break; 1044 case Builtin::BI__builtin___CFStringMakeConstantString: 1045 case Builtin::BI__builtin___NSStringMakeConstantString: 1046 return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType())); 1047 case Builtin::BI__builtin_stdarg_start: 1048 case Builtin::BI__builtin_va_start: 1049 case Builtin::BI__va_start: 1050 case Builtin::BI__builtin_va_end: 1051 return RValue::get( 1052 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start 1053 ? EmitScalarExpr(E->getArg(0)) 1054 : EmitVAListRef(E->getArg(0)).getPointer(), 1055 BuiltinID != Builtin::BI__builtin_va_end)); 1056 case Builtin::BI__builtin_va_copy: { 1057 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer(); 1058 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer(); 1059 1060 llvm::Type *Type = Int8PtrTy; 1061 1062 DstPtr = Builder.CreateBitCast(DstPtr, Type); 1063 SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 1064 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), 1065 {DstPtr, SrcPtr})); 1066 } 1067 case Builtin::BI__builtin_abs: 1068 case Builtin::BI__builtin_labs: 1069 case Builtin::BI__builtin_llabs: { 1070 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1071 1072 Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 1073 Value *CmpResult = 1074 Builder.CreateICmpSGE(ArgValue, 1075 llvm::Constant::getNullValue(ArgValue->getType()), 1076 "abscond"); 1077 Value *Result = 1078 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 1079 1080 return RValue::get(Result); 1081 } 1082 case Builtin::BI__builtin_conj: 1083 case Builtin::BI__builtin_conjf: 1084 case Builtin::BI__builtin_conjl: { 1085 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 1086 Value *Real = ComplexVal.first; 1087 Value *Imag = ComplexVal.second; 1088 Value *Zero = 1089 Imag->getType()->isFPOrFPVectorTy() 1090 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) 1091 : llvm::Constant::getNullValue(Imag->getType()); 1092 1093 Imag = Builder.CreateFSub(Zero, Imag, "sub"); 1094 return RValue::getComplex(std::make_pair(Real, Imag)); 1095 } 1096 case Builtin::BI__builtin_creal: 1097 case Builtin::BI__builtin_crealf: 1098 case Builtin::BI__builtin_creall: 1099 case Builtin::BIcreal: 1100 case Builtin::BIcrealf: 1101 case Builtin::BIcreall: { 1102 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 1103 return RValue::get(ComplexVal.first); 1104 } 1105 1106 case Builtin::BI__builtin_cimag: 1107 case Builtin::BI__builtin_cimagf: 1108 case Builtin::BI__builtin_cimagl: 1109 case Builtin::BIcimag: 1110 case Builtin::BIcimagf: 1111 case Builtin::BIcimagl: { 1112 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 1113 return RValue::get(ComplexVal.second); 1114 } 1115 1116 case Builtin::BI__builtin_ctzs: 1117 case Builtin::BI__builtin_ctz: 1118 case Builtin::BI__builtin_ctzl: 1119 case Builtin::BI__builtin_ctzll: { 1120 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero); 1121 1122 llvm::Type *ArgType = ArgValue->getType(); 1123 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 1124 1125 llvm::Type *ResultType = ConvertType(E->getType()); 1126 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 1127 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 1128 if (Result->getType() != ResultType) 1129 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1130 "cast"); 1131 return RValue::get(Result); 1132 } 1133 case Builtin::BI__builtin_clzs: 1134 case Builtin::BI__builtin_clz: 1135 case Builtin::BI__builtin_clzl: 1136 case Builtin::BI__builtin_clzll: { 1137 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero); 1138 1139 llvm::Type *ArgType = ArgValue->getType(); 1140 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 1141 1142 llvm::Type *ResultType = ConvertType(E->getType()); 1143 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 1144 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 1145 if (Result->getType() != ResultType) 1146 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1147 "cast"); 1148 return RValue::get(Result); 1149 } 1150 case Builtin::BI__builtin_ffs: 1151 case Builtin::BI__builtin_ffsl: 1152 case Builtin::BI__builtin_ffsll: { 1153 // ffs(x) -> x ? cttz(x) + 1 : 0 1154 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1155 1156 llvm::Type *ArgType = ArgValue->getType(); 1157 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 1158 1159 llvm::Type *ResultType = ConvertType(E->getType()); 1160 Value *Tmp = 1161 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}), 1162 llvm::ConstantInt::get(ArgType, 1)); 1163 Value *Zero = llvm::Constant::getNullValue(ArgType); 1164 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 1165 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 1166 if (Result->getType() != ResultType) 1167 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1168 "cast"); 1169 return RValue::get(Result); 1170 } 1171 case Builtin::BI__builtin_parity: 1172 case Builtin::BI__builtin_parityl: 1173 case Builtin::BI__builtin_parityll: { 1174 // parity(x) -> ctpop(x) & 1 1175 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1176 1177 llvm::Type *ArgType = ArgValue->getType(); 1178 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 1179 1180 llvm::Type *ResultType = ConvertType(E->getType()); 1181 Value *Tmp = Builder.CreateCall(F, ArgValue); 1182 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1)); 1183 if (Result->getType() != ResultType) 1184 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1185 "cast"); 1186 return RValue::get(Result); 1187 } 1188 case Builtin::BI__popcnt16: 1189 case Builtin::BI__popcnt: 1190 case Builtin::BI__popcnt64: 1191 case Builtin::BI__builtin_popcount: 1192 case Builtin::BI__builtin_popcountl: 1193 case Builtin::BI__builtin_popcountll: { 1194 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1195 1196 llvm::Type *ArgType = ArgValue->getType(); 1197 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 1198 1199 llvm::Type *ResultType = ConvertType(E->getType()); 1200 Value *Result = Builder.CreateCall(F, ArgValue); 1201 if (Result->getType() != ResultType) 1202 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1203 "cast"); 1204 return RValue::get(Result); 1205 } 1206 case Builtin::BI_rotr8: 1207 case Builtin::BI_rotr16: 1208 case Builtin::BI_rotr: 1209 case Builtin::BI_lrotr: 1210 case Builtin::BI_rotr64: { 1211 Value *Val = EmitScalarExpr(E->getArg(0)); 1212 Value *Shift = EmitScalarExpr(E->getArg(1)); 1213 1214 llvm::Type *ArgType = Val->getType(); 1215 Shift = Builder.CreateIntCast(Shift, ArgType, false); 1216 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 1217 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 1218 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 1219 1220 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 1221 Shift = Builder.CreateAnd(Shift, Mask); 1222 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); 1223 1224 Value *RightShifted = Builder.CreateLShr(Val, Shift); 1225 Value *LeftShifted = Builder.CreateShl(Val, LeftShift); 1226 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 1227 1228 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 1229 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 1230 return RValue::get(Result); 1231 } 1232 case Builtin::BI_rotl8: 1233 case Builtin::BI_rotl16: 1234 case Builtin::BI_rotl: 1235 case Builtin::BI_lrotl: 1236 case Builtin::BI_rotl64: { 1237 Value *Val = EmitScalarExpr(E->getArg(0)); 1238 Value *Shift = EmitScalarExpr(E->getArg(1)); 1239 1240 llvm::Type *ArgType = Val->getType(); 1241 Shift = Builder.CreateIntCast(Shift, ArgType, false); 1242 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 1243 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 1244 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 1245 1246 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 1247 Shift = Builder.CreateAnd(Shift, Mask); 1248 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); 1249 1250 Value *LeftShifted = Builder.CreateShl(Val, Shift); 1251 Value *RightShifted = Builder.CreateLShr(Val, RightShift); 1252 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 1253 1254 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 1255 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 1256 return RValue::get(Result); 1257 } 1258 case Builtin::BI__builtin_unpredictable: { 1259 // Always return the argument of __builtin_unpredictable. LLVM does not 1260 // handle this builtin. Metadata for this builtin should be added directly 1261 // to instructions such as branches or switches that use it. 1262 return RValue::get(EmitScalarExpr(E->getArg(0))); 1263 } 1264 case Builtin::BI__builtin_expect: { 1265 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1266 llvm::Type *ArgType = ArgValue->getType(); 1267 1268 Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); 1269 // Don't generate llvm.expect on -O0 as the backend won't use it for 1270 // anything. 1271 // Note, we still IRGen ExpectedValue because it could have side-effects. 1272 if (CGM.getCodeGenOpts().OptimizationLevel == 0) 1273 return RValue::get(ArgValue); 1274 1275 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType); 1276 Value *Result = 1277 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval"); 1278 return RValue::get(Result); 1279 } 1280 case Builtin::BI__builtin_assume_aligned: { 1281 Value *PtrValue = EmitScalarExpr(E->getArg(0)); 1282 Value *OffsetValue = 1283 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr; 1284 1285 Value *AlignmentValue = EmitScalarExpr(E->getArg(1)); 1286 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue); 1287 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue(); 1288 1289 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue); 1290 return RValue::get(PtrValue); 1291 } 1292 case Builtin::BI__assume: 1293 case Builtin::BI__builtin_assume: { 1294 if (E->getArg(0)->HasSideEffects(getContext())) 1295 return RValue::get(nullptr); 1296 1297 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1298 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume); 1299 return RValue::get(Builder.CreateCall(FnAssume, ArgValue)); 1300 } 1301 case Builtin::BI__builtin_bswap16: 1302 case Builtin::BI__builtin_bswap32: 1303 case Builtin::BI__builtin_bswap64: { 1304 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap)); 1305 } 1306 case Builtin::BI__builtin_bitreverse8: 1307 case Builtin::BI__builtin_bitreverse16: 1308 case Builtin::BI__builtin_bitreverse32: 1309 case Builtin::BI__builtin_bitreverse64: { 1310 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse)); 1311 } 1312 case Builtin::BI__builtin_object_size: { 1313 unsigned Type = 1314 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); 1315 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType())); 1316 1317 // We pass this builtin onto the optimizer so that it can figure out the 1318 // object size in more complex cases. 1319 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType, 1320 /*EmittedE=*/nullptr)); 1321 } 1322 case Builtin::BI__builtin_prefetch: { 1323 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 1324 // FIXME: Technically these constants should of type 'int', yes? 1325 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 1326 llvm::ConstantInt::get(Int32Ty, 0); 1327 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 1328 llvm::ConstantInt::get(Int32Ty, 3); 1329 Value *Data = llvm::ConstantInt::get(Int32Ty, 1); 1330 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 1331 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data})); 1332 } 1333 case Builtin::BI__builtin_readcyclecounter: { 1334 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter); 1335 return RValue::get(Builder.CreateCall(F)); 1336 } 1337 case Builtin::BI__builtin___clear_cache: { 1338 Value *Begin = EmitScalarExpr(E->getArg(0)); 1339 Value *End = EmitScalarExpr(E->getArg(1)); 1340 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache); 1341 return RValue::get(Builder.CreateCall(F, {Begin, End})); 1342 } 1343 case Builtin::BI__builtin_trap: 1344 return RValue::get(EmitTrapCall(Intrinsic::trap)); 1345 case Builtin::BI__debugbreak: 1346 return RValue::get(EmitTrapCall(Intrinsic::debugtrap)); 1347 case Builtin::BI__builtin_unreachable: { 1348 if (SanOpts.has(SanitizerKind::Unreachable)) { 1349 SanitizerScope SanScope(this); 1350 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()), 1351 SanitizerKind::Unreachable), 1352 SanitizerHandler::BuiltinUnreachable, 1353 EmitCheckSourceLocation(E->getExprLoc()), None); 1354 } else 1355 Builder.CreateUnreachable(); 1356 1357 // We do need to preserve an insertion point. 1358 EmitBlock(createBasicBlock("unreachable.cont")); 1359 1360 return RValue::get(nullptr); 1361 } 1362 1363 case Builtin::BI__builtin_powi: 1364 case Builtin::BI__builtin_powif: 1365 case Builtin::BI__builtin_powil: { 1366 Value *Base = EmitScalarExpr(E->getArg(0)); 1367 Value *Exponent = EmitScalarExpr(E->getArg(1)); 1368 llvm::Type *ArgType = Base->getType(); 1369 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType); 1370 return RValue::get(Builder.CreateCall(F, {Base, Exponent})); 1371 } 1372 1373 case Builtin::BI__builtin_isgreater: 1374 case Builtin::BI__builtin_isgreaterequal: 1375 case Builtin::BI__builtin_isless: 1376 case Builtin::BI__builtin_islessequal: 1377 case Builtin::BI__builtin_islessgreater: 1378 case Builtin::BI__builtin_isunordered: { 1379 // Ordered comparisons: we know the arguments to these are matching scalar 1380 // floating point values. 1381 Value *LHS = EmitScalarExpr(E->getArg(0)); 1382 Value *RHS = EmitScalarExpr(E->getArg(1)); 1383 1384 switch (BuiltinID) { 1385 default: llvm_unreachable("Unknown ordered comparison"); 1386 case Builtin::BI__builtin_isgreater: 1387 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 1388 break; 1389 case Builtin::BI__builtin_isgreaterequal: 1390 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 1391 break; 1392 case Builtin::BI__builtin_isless: 1393 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 1394 break; 1395 case Builtin::BI__builtin_islessequal: 1396 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 1397 break; 1398 case Builtin::BI__builtin_islessgreater: 1399 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 1400 break; 1401 case Builtin::BI__builtin_isunordered: 1402 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 1403 break; 1404 } 1405 // ZExt bool to int type. 1406 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()))); 1407 } 1408 case Builtin::BI__builtin_isnan: { 1409 Value *V = EmitScalarExpr(E->getArg(0)); 1410 V = Builder.CreateFCmpUNO(V, V, "cmp"); 1411 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1412 } 1413 1414 case Builtin::BIfinite: 1415 case Builtin::BI__finite: 1416 case Builtin::BIfinitef: 1417 case Builtin::BI__finitef: 1418 case Builtin::BIfinitel: 1419 case Builtin::BI__finitel: 1420 case Builtin::BI__builtin_isinf: 1421 case Builtin::BI__builtin_isfinite: { 1422 // isinf(x) --> fabs(x) == infinity 1423 // isfinite(x) --> fabs(x) != infinity 1424 // x != NaN via the ordered compare in either case. 1425 Value *V = EmitScalarExpr(E->getArg(0)); 1426 Value *Fabs = EmitFAbs(*this, V); 1427 Constant *Infinity = ConstantFP::getInfinity(V->getType()); 1428 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf) 1429 ? CmpInst::FCMP_OEQ 1430 : CmpInst::FCMP_ONE; 1431 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf"); 1432 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType()))); 1433 } 1434 1435 case Builtin::BI__builtin_isinf_sign: { 1436 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0 1437 Value *Arg = EmitScalarExpr(E->getArg(0)); 1438 Value *AbsArg = EmitFAbs(*this, Arg); 1439 Value *IsInf = Builder.CreateFCmpOEQ( 1440 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf"); 1441 Value *IsNeg = EmitSignBit(*this, Arg); 1442 1443 llvm::Type *IntTy = ConvertType(E->getType()); 1444 Value *Zero = Constant::getNullValue(IntTy); 1445 Value *One = ConstantInt::get(IntTy, 1); 1446 Value *NegativeOne = ConstantInt::get(IntTy, -1); 1447 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One); 1448 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero); 1449 return RValue::get(Result); 1450 } 1451 1452 case Builtin::BI__builtin_isnormal: { 1453 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 1454 Value *V = EmitScalarExpr(E->getArg(0)); 1455 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 1456 1457 Value *Abs = EmitFAbs(*this, V); 1458 Value *IsLessThanInf = 1459 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 1460 APFloat Smallest = APFloat::getSmallestNormalized( 1461 getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 1462 Value *IsNormal = 1463 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 1464 "isnormal"); 1465 V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 1466 V = Builder.CreateAnd(V, IsNormal, "and"); 1467 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1468 } 1469 1470 case Builtin::BI__builtin_fpclassify: { 1471 Value *V = EmitScalarExpr(E->getArg(5)); 1472 llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 1473 1474 // Create Result 1475 BasicBlock *Begin = Builder.GetInsertBlock(); 1476 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 1477 Builder.SetInsertPoint(End); 1478 PHINode *Result = 1479 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4, 1480 "fpclassify_result"); 1481 1482 // if (V==0) return FP_ZERO 1483 Builder.SetInsertPoint(Begin); 1484 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 1485 "iszero"); 1486 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 1487 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 1488 Builder.CreateCondBr(IsZero, End, NotZero); 1489 Result->addIncoming(ZeroLiteral, Begin); 1490 1491 // if (V != V) return FP_NAN 1492 Builder.SetInsertPoint(NotZero); 1493 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 1494 Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 1495 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 1496 Builder.CreateCondBr(IsNan, End, NotNan); 1497 Result->addIncoming(NanLiteral, NotZero); 1498 1499 // if (fabs(V) == infinity) return FP_INFINITY 1500 Builder.SetInsertPoint(NotNan); 1501 Value *VAbs = EmitFAbs(*this, V); 1502 Value *IsInf = 1503 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 1504 "isinf"); 1505 Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 1506 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 1507 Builder.CreateCondBr(IsInf, End, NotInf); 1508 Result->addIncoming(InfLiteral, NotNan); 1509 1510 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 1511 Builder.SetInsertPoint(NotInf); 1512 APFloat Smallest = APFloat::getSmallestNormalized( 1513 getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 1514 Value *IsNormal = 1515 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 1516 "isnormal"); 1517 Value *NormalResult = 1518 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 1519 EmitScalarExpr(E->getArg(3))); 1520 Builder.CreateBr(End); 1521 Result->addIncoming(NormalResult, NotInf); 1522 1523 // return Result 1524 Builder.SetInsertPoint(End); 1525 return RValue::get(Result); 1526 } 1527 1528 case Builtin::BIalloca: 1529 case Builtin::BI_alloca: 1530 case Builtin::BI__builtin_alloca: { 1531 Value *Size = EmitScalarExpr(E->getArg(0)); 1532 const TargetInfo &TI = getContext().getTargetInfo(); 1533 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__. 1534 unsigned SuitableAlignmentInBytes = 1535 CGM.getContext() 1536 .toCharUnitsFromBits(TI.getSuitableAlign()) 1537 .getQuantity(); 1538 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1539 AI->setAlignment(SuitableAlignmentInBytes); 1540 return RValue::get(AI); 1541 } 1542 1543 case Builtin::BI__builtin_alloca_with_align: { 1544 Value *Size = EmitScalarExpr(E->getArg(0)); 1545 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1)); 1546 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue); 1547 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue(); 1548 unsigned AlignmentInBytes = 1549 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity(); 1550 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1551 AI->setAlignment(AlignmentInBytes); 1552 return RValue::get(AI); 1553 } 1554 1555 case Builtin::BIbzero: 1556 case Builtin::BI__builtin_bzero: { 1557 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1558 Value *SizeVal = EmitScalarExpr(E->getArg(1)); 1559 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1560 E->getArg(0)->getExprLoc(), FD, 0); 1561 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false); 1562 return RValue::get(nullptr); 1563 } 1564 case Builtin::BImemcpy: 1565 case Builtin::BI__builtin_memcpy: { 1566 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1567 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1568 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1569 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1570 E->getArg(0)->getExprLoc(), FD, 0); 1571 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1572 E->getArg(1)->getExprLoc(), FD, 1); 1573 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1574 return RValue::get(Dest.getPointer()); 1575 } 1576 1577 case Builtin::BI__builtin_char_memchr: 1578 BuiltinID = Builtin::BI__builtin_memchr; 1579 break; 1580 1581 case Builtin::BI__builtin___memcpy_chk: { 1582 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. 1583 llvm::APSInt Size, DstSize; 1584 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1585 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1586 break; 1587 if (Size.ugt(DstSize)) 1588 break; 1589 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1590 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1591 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1592 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1593 return RValue::get(Dest.getPointer()); 1594 } 1595 1596 case Builtin::BI__builtin_objc_memmove_collectable: { 1597 Address DestAddr = EmitPointerWithAlignment(E->getArg(0)); 1598 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1)); 1599 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1600 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 1601 DestAddr, SrcAddr, SizeVal); 1602 return RValue::get(DestAddr.getPointer()); 1603 } 1604 1605 case Builtin::BI__builtin___memmove_chk: { 1606 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. 1607 llvm::APSInt Size, DstSize; 1608 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1609 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1610 break; 1611 if (Size.ugt(DstSize)) 1612 break; 1613 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1614 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1615 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1616 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1617 return RValue::get(Dest.getPointer()); 1618 } 1619 1620 case Builtin::BImemmove: 1621 case Builtin::BI__builtin_memmove: { 1622 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1623 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1624 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1625 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1626 E->getArg(0)->getExprLoc(), FD, 0); 1627 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1628 E->getArg(1)->getExprLoc(), FD, 1); 1629 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1630 return RValue::get(Dest.getPointer()); 1631 } 1632 case Builtin::BImemset: 1633 case Builtin::BI__builtin_memset: { 1634 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1635 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1636 Builder.getInt8Ty()); 1637 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1638 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1639 E->getArg(0)->getExprLoc(), FD, 0); 1640 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1641 return RValue::get(Dest.getPointer()); 1642 } 1643 case Builtin::BI__builtin___memset_chk: { 1644 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. 1645 llvm::APSInt Size, DstSize; 1646 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1647 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1648 break; 1649 if (Size.ugt(DstSize)) 1650 break; 1651 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1652 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1653 Builder.getInt8Ty()); 1654 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1655 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1656 return RValue::get(Dest.getPointer()); 1657 } 1658 case Builtin::BI__builtin_dwarf_cfa: { 1659 // The offset in bytes from the first argument to the CFA. 1660 // 1661 // Why on earth is this in the frontend? Is there any reason at 1662 // all that the backend can't reasonably determine this while 1663 // lowering llvm.eh.dwarf.cfa()? 1664 // 1665 // TODO: If there's a satisfactory reason, add a target hook for 1666 // this instead of hard-coding 0, which is correct for most targets. 1667 int32_t Offset = 0; 1668 1669 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa); 1670 return RValue::get(Builder.CreateCall(F, 1671 llvm::ConstantInt::get(Int32Ty, Offset))); 1672 } 1673 case Builtin::BI__builtin_return_address: { 1674 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), 1675 getContext().UnsignedIntTy); 1676 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1677 return RValue::get(Builder.CreateCall(F, Depth)); 1678 } 1679 case Builtin::BI_ReturnAddress: { 1680 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1681 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0))); 1682 } 1683 case Builtin::BI__builtin_frame_address: { 1684 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), 1685 getContext().UnsignedIntTy); 1686 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress); 1687 return RValue::get(Builder.CreateCall(F, Depth)); 1688 } 1689 case Builtin::BI__builtin_extract_return_addr: { 1690 Value *Address = EmitScalarExpr(E->getArg(0)); 1691 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 1692 return RValue::get(Result); 1693 } 1694 case Builtin::BI__builtin_frob_return_addr: { 1695 Value *Address = EmitScalarExpr(E->getArg(0)); 1696 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 1697 return RValue::get(Result); 1698 } 1699 case Builtin::BI__builtin_dwarf_sp_column: { 1700 llvm::IntegerType *Ty 1701 = cast<llvm::IntegerType>(ConvertType(E->getType())); 1702 int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 1703 if (Column == -1) { 1704 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 1705 return RValue::get(llvm::UndefValue::get(Ty)); 1706 } 1707 return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 1708 } 1709 case Builtin::BI__builtin_init_dwarf_reg_size_table: { 1710 Value *Address = EmitScalarExpr(E->getArg(0)); 1711 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 1712 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 1713 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 1714 } 1715 case Builtin::BI__builtin_eh_return: { 1716 Value *Int = EmitScalarExpr(E->getArg(0)); 1717 Value *Ptr = EmitScalarExpr(E->getArg(1)); 1718 1719 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 1720 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 1721 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 1722 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 1723 ? Intrinsic::eh_return_i32 1724 : Intrinsic::eh_return_i64); 1725 Builder.CreateCall(F, {Int, Ptr}); 1726 Builder.CreateUnreachable(); 1727 1728 // We do need to preserve an insertion point. 1729 EmitBlock(createBasicBlock("builtin_eh_return.cont")); 1730 1731 return RValue::get(nullptr); 1732 } 1733 case Builtin::BI__builtin_unwind_init: { 1734 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init); 1735 return RValue::get(Builder.CreateCall(F)); 1736 } 1737 case Builtin::BI__builtin_extend_pointer: { 1738 // Extends a pointer to the size of an _Unwind_Word, which is 1739 // uint64_t on all platforms. Generally this gets poked into a 1740 // register and eventually used as an address, so if the 1741 // addressing registers are wider than pointers and the platform 1742 // doesn't implicitly ignore high-order bits when doing 1743 // addressing, we need to make sure we zext / sext based on 1744 // the platform's expectations. 1745 // 1746 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 1747 1748 // Cast the pointer to intptr_t. 1749 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1750 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 1751 1752 // If that's 64 bits, we're done. 1753 if (IntPtrTy->getBitWidth() == 64) 1754 return RValue::get(Result); 1755 1756 // Otherwise, ask the codegen data what to do. 1757 if (getTargetHooks().extendPointerWithSExt()) 1758 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 1759 else 1760 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 1761 } 1762 case Builtin::BI__builtin_setjmp: { 1763 // Buffer is a void**. 1764 Address Buf = EmitPointerWithAlignment(E->getArg(0)); 1765 1766 // Store the frame pointer to the setjmp buffer. 1767 Value *FrameAddr = 1768 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 1769 ConstantInt::get(Int32Ty, 0)); 1770 Builder.CreateStore(FrameAddr, Buf); 1771 1772 // Store the stack pointer to the setjmp buffer. 1773 Value *StackAddr = 1774 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 1775 Address StackSaveSlot = 1776 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize()); 1777 Builder.CreateStore(StackAddr, StackSaveSlot); 1778 1779 // Call LLVM's EH setjmp, which is lightweight. 1780 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 1781 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1782 return RValue::get(Builder.CreateCall(F, Buf.getPointer())); 1783 } 1784 case Builtin::BI__builtin_longjmp: { 1785 Value *Buf = EmitScalarExpr(E->getArg(0)); 1786 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1787 1788 // Call LLVM's EH longjmp, which is lightweight. 1789 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 1790 1791 // longjmp doesn't return; mark this as unreachable. 1792 Builder.CreateUnreachable(); 1793 1794 // We do need to preserve an insertion point. 1795 EmitBlock(createBasicBlock("longjmp.cont")); 1796 1797 return RValue::get(nullptr); 1798 } 1799 case Builtin::BI__sync_fetch_and_add: 1800 case Builtin::BI__sync_fetch_and_sub: 1801 case Builtin::BI__sync_fetch_and_or: 1802 case Builtin::BI__sync_fetch_and_and: 1803 case Builtin::BI__sync_fetch_and_xor: 1804 case Builtin::BI__sync_fetch_and_nand: 1805 case Builtin::BI__sync_add_and_fetch: 1806 case Builtin::BI__sync_sub_and_fetch: 1807 case Builtin::BI__sync_and_and_fetch: 1808 case Builtin::BI__sync_or_and_fetch: 1809 case Builtin::BI__sync_xor_and_fetch: 1810 case Builtin::BI__sync_nand_and_fetch: 1811 case Builtin::BI__sync_val_compare_and_swap: 1812 case Builtin::BI__sync_bool_compare_and_swap: 1813 case Builtin::BI__sync_lock_test_and_set: 1814 case Builtin::BI__sync_lock_release: 1815 case Builtin::BI__sync_swap: 1816 llvm_unreachable("Shouldn't make it through sema"); 1817 case Builtin::BI__sync_fetch_and_add_1: 1818 case Builtin::BI__sync_fetch_and_add_2: 1819 case Builtin::BI__sync_fetch_and_add_4: 1820 case Builtin::BI__sync_fetch_and_add_8: 1821 case Builtin::BI__sync_fetch_and_add_16: 1822 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E); 1823 case Builtin::BI__sync_fetch_and_sub_1: 1824 case Builtin::BI__sync_fetch_and_sub_2: 1825 case Builtin::BI__sync_fetch_and_sub_4: 1826 case Builtin::BI__sync_fetch_and_sub_8: 1827 case Builtin::BI__sync_fetch_and_sub_16: 1828 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E); 1829 case Builtin::BI__sync_fetch_and_or_1: 1830 case Builtin::BI__sync_fetch_and_or_2: 1831 case Builtin::BI__sync_fetch_and_or_4: 1832 case Builtin::BI__sync_fetch_and_or_8: 1833 case Builtin::BI__sync_fetch_and_or_16: 1834 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E); 1835 case Builtin::BI__sync_fetch_and_and_1: 1836 case Builtin::BI__sync_fetch_and_and_2: 1837 case Builtin::BI__sync_fetch_and_and_4: 1838 case Builtin::BI__sync_fetch_and_and_8: 1839 case Builtin::BI__sync_fetch_and_and_16: 1840 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E); 1841 case Builtin::BI__sync_fetch_and_xor_1: 1842 case Builtin::BI__sync_fetch_and_xor_2: 1843 case Builtin::BI__sync_fetch_and_xor_4: 1844 case Builtin::BI__sync_fetch_and_xor_8: 1845 case Builtin::BI__sync_fetch_and_xor_16: 1846 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E); 1847 case Builtin::BI__sync_fetch_and_nand_1: 1848 case Builtin::BI__sync_fetch_and_nand_2: 1849 case Builtin::BI__sync_fetch_and_nand_4: 1850 case Builtin::BI__sync_fetch_and_nand_8: 1851 case Builtin::BI__sync_fetch_and_nand_16: 1852 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E); 1853 1854 // Clang extensions: not overloaded yet. 1855 case Builtin::BI__sync_fetch_and_min: 1856 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E); 1857 case Builtin::BI__sync_fetch_and_max: 1858 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E); 1859 case Builtin::BI__sync_fetch_and_umin: 1860 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E); 1861 case Builtin::BI__sync_fetch_and_umax: 1862 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E); 1863 1864 case Builtin::BI__sync_add_and_fetch_1: 1865 case Builtin::BI__sync_add_and_fetch_2: 1866 case Builtin::BI__sync_add_and_fetch_4: 1867 case Builtin::BI__sync_add_and_fetch_8: 1868 case Builtin::BI__sync_add_and_fetch_16: 1869 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E, 1870 llvm::Instruction::Add); 1871 case Builtin::BI__sync_sub_and_fetch_1: 1872 case Builtin::BI__sync_sub_and_fetch_2: 1873 case Builtin::BI__sync_sub_and_fetch_4: 1874 case Builtin::BI__sync_sub_and_fetch_8: 1875 case Builtin::BI__sync_sub_and_fetch_16: 1876 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E, 1877 llvm::Instruction::Sub); 1878 case Builtin::BI__sync_and_and_fetch_1: 1879 case Builtin::BI__sync_and_and_fetch_2: 1880 case Builtin::BI__sync_and_and_fetch_4: 1881 case Builtin::BI__sync_and_and_fetch_8: 1882 case Builtin::BI__sync_and_and_fetch_16: 1883 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E, 1884 llvm::Instruction::And); 1885 case Builtin::BI__sync_or_and_fetch_1: 1886 case Builtin::BI__sync_or_and_fetch_2: 1887 case Builtin::BI__sync_or_and_fetch_4: 1888 case Builtin::BI__sync_or_and_fetch_8: 1889 case Builtin::BI__sync_or_and_fetch_16: 1890 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E, 1891 llvm::Instruction::Or); 1892 case Builtin::BI__sync_xor_and_fetch_1: 1893 case Builtin::BI__sync_xor_and_fetch_2: 1894 case Builtin::BI__sync_xor_and_fetch_4: 1895 case Builtin::BI__sync_xor_and_fetch_8: 1896 case Builtin::BI__sync_xor_and_fetch_16: 1897 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E, 1898 llvm::Instruction::Xor); 1899 case Builtin::BI__sync_nand_and_fetch_1: 1900 case Builtin::BI__sync_nand_and_fetch_2: 1901 case Builtin::BI__sync_nand_and_fetch_4: 1902 case Builtin::BI__sync_nand_and_fetch_8: 1903 case Builtin::BI__sync_nand_and_fetch_16: 1904 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E, 1905 llvm::Instruction::And, true); 1906 1907 case Builtin::BI__sync_val_compare_and_swap_1: 1908 case Builtin::BI__sync_val_compare_and_swap_2: 1909 case Builtin::BI__sync_val_compare_and_swap_4: 1910 case Builtin::BI__sync_val_compare_and_swap_8: 1911 case Builtin::BI__sync_val_compare_and_swap_16: 1912 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false)); 1913 1914 case Builtin::BI__sync_bool_compare_and_swap_1: 1915 case Builtin::BI__sync_bool_compare_and_swap_2: 1916 case Builtin::BI__sync_bool_compare_and_swap_4: 1917 case Builtin::BI__sync_bool_compare_and_swap_8: 1918 case Builtin::BI__sync_bool_compare_and_swap_16: 1919 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true)); 1920 1921 case Builtin::BI__sync_swap_1: 1922 case Builtin::BI__sync_swap_2: 1923 case Builtin::BI__sync_swap_4: 1924 case Builtin::BI__sync_swap_8: 1925 case Builtin::BI__sync_swap_16: 1926 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1927 1928 case Builtin::BI__sync_lock_test_and_set_1: 1929 case Builtin::BI__sync_lock_test_and_set_2: 1930 case Builtin::BI__sync_lock_test_and_set_4: 1931 case Builtin::BI__sync_lock_test_and_set_8: 1932 case Builtin::BI__sync_lock_test_and_set_16: 1933 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1934 1935 case Builtin::BI__sync_lock_release_1: 1936 case Builtin::BI__sync_lock_release_2: 1937 case Builtin::BI__sync_lock_release_4: 1938 case Builtin::BI__sync_lock_release_8: 1939 case Builtin::BI__sync_lock_release_16: { 1940 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1941 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 1942 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 1943 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 1944 StoreSize.getQuantity() * 8); 1945 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 1946 llvm::StoreInst *Store = 1947 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr, 1948 StoreSize); 1949 Store->setAtomic(llvm::AtomicOrdering::Release); 1950 return RValue::get(nullptr); 1951 } 1952 1953 case Builtin::BI__sync_synchronize: { 1954 // We assume this is supposed to correspond to a C++0x-style 1955 // sequentially-consistent fence (i.e. this is only usable for 1956 // synchonization, not device I/O or anything like that). This intrinsic 1957 // is really badly designed in the sense that in theory, there isn't 1958 // any way to safely use it... but in practice, it mostly works 1959 // to use it with non-atomic loads and stores to get acquire/release 1960 // semantics. 1961 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent); 1962 return RValue::get(nullptr); 1963 } 1964 1965 case Builtin::BI__builtin_nontemporal_load: 1966 return RValue::get(EmitNontemporalLoad(*this, E)); 1967 case Builtin::BI__builtin_nontemporal_store: 1968 return RValue::get(EmitNontemporalStore(*this, E)); 1969 case Builtin::BI__c11_atomic_is_lock_free: 1970 case Builtin::BI__atomic_is_lock_free: { 1971 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the 1972 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since 1973 // _Atomic(T) is always properly-aligned. 1974 const char *LibCallName = "__atomic_is_lock_free"; 1975 CallArgList Args; 1976 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))), 1977 getContext().getSizeType()); 1978 if (BuiltinID == Builtin::BI__atomic_is_lock_free) 1979 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))), 1980 getContext().VoidPtrTy); 1981 else 1982 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)), 1983 getContext().VoidPtrTy); 1984 const CGFunctionInfo &FuncInfo = 1985 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args); 1986 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); 1987 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); 1988 return EmitCall(FuncInfo, CGCallee::forDirect(Func), 1989 ReturnValueSlot(), Args); 1990 } 1991 1992 case Builtin::BI__atomic_test_and_set: { 1993 // Look at the argument type to determine whether this is a volatile 1994 // operation. The parameter type is always volatile. 1995 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1996 bool Volatile = 1997 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1998 1999 Value *Ptr = EmitScalarExpr(E->getArg(0)); 2000 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 2001 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 2002 Value *NewVal = Builder.getInt8(1); 2003 Value *Order = EmitScalarExpr(E->getArg(1)); 2004 if (isa<llvm::ConstantInt>(Order)) { 2005 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 2006 AtomicRMWInst *Result = nullptr; 2007 switch (ord) { 2008 case 0: // memory_order_relaxed 2009 default: // invalid order 2010 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 2011 llvm::AtomicOrdering::Monotonic); 2012 break; 2013 case 1: // memory_order_consume 2014 case 2: // memory_order_acquire 2015 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 2016 llvm::AtomicOrdering::Acquire); 2017 break; 2018 case 3: // memory_order_release 2019 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 2020 llvm::AtomicOrdering::Release); 2021 break; 2022 case 4: // memory_order_acq_rel 2023 2024 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 2025 llvm::AtomicOrdering::AcquireRelease); 2026 break; 2027 case 5: // memory_order_seq_cst 2028 Result = Builder.CreateAtomicRMW( 2029 llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 2030 llvm::AtomicOrdering::SequentiallyConsistent); 2031 break; 2032 } 2033 Result->setVolatile(Volatile); 2034 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 2035 } 2036 2037 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 2038 2039 llvm::BasicBlock *BBs[5] = { 2040 createBasicBlock("monotonic", CurFn), 2041 createBasicBlock("acquire", CurFn), 2042 createBasicBlock("release", CurFn), 2043 createBasicBlock("acqrel", CurFn), 2044 createBasicBlock("seqcst", CurFn) 2045 }; 2046 llvm::AtomicOrdering Orders[5] = { 2047 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire, 2048 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease, 2049 llvm::AtomicOrdering::SequentiallyConsistent}; 2050 2051 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 2052 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 2053 2054 Builder.SetInsertPoint(ContBB); 2055 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set"); 2056 2057 for (unsigned i = 0; i < 5; ++i) { 2058 Builder.SetInsertPoint(BBs[i]); 2059 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 2060 Ptr, NewVal, Orders[i]); 2061 RMW->setVolatile(Volatile); 2062 Result->addIncoming(RMW, BBs[i]); 2063 Builder.CreateBr(ContBB); 2064 } 2065 2066 SI->addCase(Builder.getInt32(0), BBs[0]); 2067 SI->addCase(Builder.getInt32(1), BBs[1]); 2068 SI->addCase(Builder.getInt32(2), BBs[1]); 2069 SI->addCase(Builder.getInt32(3), BBs[2]); 2070 SI->addCase(Builder.getInt32(4), BBs[3]); 2071 SI->addCase(Builder.getInt32(5), BBs[4]); 2072 2073 Builder.SetInsertPoint(ContBB); 2074 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 2075 } 2076 2077 case Builtin::BI__atomic_clear: { 2078 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 2079 bool Volatile = 2080 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 2081 2082 Address Ptr = EmitPointerWithAlignment(E->getArg(0)); 2083 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace(); 2084 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 2085 Value *NewVal = Builder.getInt8(0); 2086 Value *Order = EmitScalarExpr(E->getArg(1)); 2087 if (isa<llvm::ConstantInt>(Order)) { 2088 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 2089 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 2090 switch (ord) { 2091 case 0: // memory_order_relaxed 2092 default: // invalid order 2093 Store->setOrdering(llvm::AtomicOrdering::Monotonic); 2094 break; 2095 case 3: // memory_order_release 2096 Store->setOrdering(llvm::AtomicOrdering::Release); 2097 break; 2098 case 5: // memory_order_seq_cst 2099 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent); 2100 break; 2101 } 2102 return RValue::get(nullptr); 2103 } 2104 2105 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 2106 2107 llvm::BasicBlock *BBs[3] = { 2108 createBasicBlock("monotonic", CurFn), 2109 createBasicBlock("release", CurFn), 2110 createBasicBlock("seqcst", CurFn) 2111 }; 2112 llvm::AtomicOrdering Orders[3] = { 2113 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release, 2114 llvm::AtomicOrdering::SequentiallyConsistent}; 2115 2116 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 2117 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 2118 2119 for (unsigned i = 0; i < 3; ++i) { 2120 Builder.SetInsertPoint(BBs[i]); 2121 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 2122 Store->setOrdering(Orders[i]); 2123 Builder.CreateBr(ContBB); 2124 } 2125 2126 SI->addCase(Builder.getInt32(0), BBs[0]); 2127 SI->addCase(Builder.getInt32(3), BBs[1]); 2128 SI->addCase(Builder.getInt32(5), BBs[2]); 2129 2130 Builder.SetInsertPoint(ContBB); 2131 return RValue::get(nullptr); 2132 } 2133 2134 case Builtin::BI__atomic_thread_fence: 2135 case Builtin::BI__atomic_signal_fence: 2136 case Builtin::BI__c11_atomic_thread_fence: 2137 case Builtin::BI__c11_atomic_signal_fence: { 2138 llvm::SyncScope::ID SSID; 2139 if (BuiltinID == Builtin::BI__atomic_signal_fence || 2140 BuiltinID == Builtin::BI__c11_atomic_signal_fence) 2141 SSID = llvm::SyncScope::SingleThread; 2142 else 2143 SSID = llvm::SyncScope::System; 2144 Value *Order = EmitScalarExpr(E->getArg(0)); 2145 if (isa<llvm::ConstantInt>(Order)) { 2146 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 2147 switch (ord) { 2148 case 0: // memory_order_relaxed 2149 default: // invalid order 2150 break; 2151 case 1: // memory_order_consume 2152 case 2: // memory_order_acquire 2153 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID); 2154 break; 2155 case 3: // memory_order_release 2156 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID); 2157 break; 2158 case 4: // memory_order_acq_rel 2159 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID); 2160 break; 2161 case 5: // memory_order_seq_cst 2162 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID); 2163 break; 2164 } 2165 return RValue::get(nullptr); 2166 } 2167 2168 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB; 2169 AcquireBB = createBasicBlock("acquire", CurFn); 2170 ReleaseBB = createBasicBlock("release", CurFn); 2171 AcqRelBB = createBasicBlock("acqrel", CurFn); 2172 SeqCstBB = createBasicBlock("seqcst", CurFn); 2173 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 2174 2175 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 2176 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB); 2177 2178 Builder.SetInsertPoint(AcquireBB); 2179 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID); 2180 Builder.CreateBr(ContBB); 2181 SI->addCase(Builder.getInt32(1), AcquireBB); 2182 SI->addCase(Builder.getInt32(2), AcquireBB); 2183 2184 Builder.SetInsertPoint(ReleaseBB); 2185 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID); 2186 Builder.CreateBr(ContBB); 2187 SI->addCase(Builder.getInt32(3), ReleaseBB); 2188 2189 Builder.SetInsertPoint(AcqRelBB); 2190 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID); 2191 Builder.CreateBr(ContBB); 2192 SI->addCase(Builder.getInt32(4), AcqRelBB); 2193 2194 Builder.SetInsertPoint(SeqCstBB); 2195 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID); 2196 Builder.CreateBr(ContBB); 2197 SI->addCase(Builder.getInt32(5), SeqCstBB); 2198 2199 Builder.SetInsertPoint(ContBB); 2200 return RValue::get(nullptr); 2201 } 2202 2203 case Builtin::BI__builtin_signbit: 2204 case Builtin::BI__builtin_signbitf: 2205 case Builtin::BI__builtin_signbitl: { 2206 return RValue::get( 2207 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))), 2208 ConvertType(E->getType()))); 2209 } 2210 case Builtin::BI__annotation: { 2211 // Re-encode each wide string to UTF8 and make an MDString. 2212 SmallVector<Metadata *, 1> Strings; 2213 for (const Expr *Arg : E->arguments()) { 2214 const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts()); 2215 assert(Str->getCharByteWidth() == 2); 2216 StringRef WideBytes = Str->getBytes(); 2217 std::string StrUtf8; 2218 if (!convertUTF16ToUTF8String( 2219 makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) { 2220 CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument"); 2221 continue; 2222 } 2223 Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8)); 2224 } 2225 2226 // Build and MDTuple of MDStrings and emit the intrinsic call. 2227 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {}); 2228 MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings); 2229 Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple)); 2230 return RValue::getIgnored(); 2231 } 2232 case Builtin::BI__builtin_annotation: { 2233 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 2234 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 2235 AnnVal->getType()); 2236 2237 // Get the annotation string, go through casts. Sema requires this to be a 2238 // non-wide string literal, potentially casted, so the cast<> is safe. 2239 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 2240 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 2241 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 2242 } 2243 case Builtin::BI__builtin_addcb: 2244 case Builtin::BI__builtin_addcs: 2245 case Builtin::BI__builtin_addc: 2246 case Builtin::BI__builtin_addcl: 2247 case Builtin::BI__builtin_addcll: 2248 case Builtin::BI__builtin_subcb: 2249 case Builtin::BI__builtin_subcs: 2250 case Builtin::BI__builtin_subc: 2251 case Builtin::BI__builtin_subcl: 2252 case Builtin::BI__builtin_subcll: { 2253 2254 // We translate all of these builtins from expressions of the form: 2255 // int x = ..., y = ..., carryin = ..., carryout, result; 2256 // result = __builtin_addc(x, y, carryin, &carryout); 2257 // 2258 // to LLVM IR of the form: 2259 // 2260 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 2261 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 2262 // %carry1 = extractvalue {i32, i1} %tmp1, 1 2263 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 2264 // i32 %carryin) 2265 // %result = extractvalue {i32, i1} %tmp2, 0 2266 // %carry2 = extractvalue {i32, i1} %tmp2, 1 2267 // %tmp3 = or i1 %carry1, %carry2 2268 // %tmp4 = zext i1 %tmp3 to i32 2269 // store i32 %tmp4, i32* %carryout 2270 2271 // Scalarize our inputs. 2272 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2273 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2274 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 2275 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3)); 2276 2277 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 2278 llvm::Intrinsic::ID IntrinsicId; 2279 switch (BuiltinID) { 2280 default: llvm_unreachable("Unknown multiprecision builtin id."); 2281 case Builtin::BI__builtin_addcb: 2282 case Builtin::BI__builtin_addcs: 2283 case Builtin::BI__builtin_addc: 2284 case Builtin::BI__builtin_addcl: 2285 case Builtin::BI__builtin_addcll: 2286 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2287 break; 2288 case Builtin::BI__builtin_subcb: 2289 case Builtin::BI__builtin_subcs: 2290 case Builtin::BI__builtin_subc: 2291 case Builtin::BI__builtin_subcl: 2292 case Builtin::BI__builtin_subcll: 2293 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2294 break; 2295 } 2296 2297 // Construct our resulting LLVM IR expression. 2298 llvm::Value *Carry1; 2299 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 2300 X, Y, Carry1); 2301 llvm::Value *Carry2; 2302 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 2303 Sum1, Carryin, Carry2); 2304 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 2305 X->getType()); 2306 Builder.CreateStore(CarryOut, CarryOutPtr); 2307 return RValue::get(Sum2); 2308 } 2309 2310 case Builtin::BI__builtin_add_overflow: 2311 case Builtin::BI__builtin_sub_overflow: 2312 case Builtin::BI__builtin_mul_overflow: { 2313 const clang::Expr *LeftArg = E->getArg(0); 2314 const clang::Expr *RightArg = E->getArg(1); 2315 const clang::Expr *ResultArg = E->getArg(2); 2316 2317 clang::QualType ResultQTy = 2318 ResultArg->getType()->castAs<PointerType>()->getPointeeType(); 2319 2320 WidthAndSignedness LeftInfo = 2321 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType()); 2322 WidthAndSignedness RightInfo = 2323 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType()); 2324 WidthAndSignedness ResultInfo = 2325 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy); 2326 WidthAndSignedness EncompassingInfo = 2327 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo}); 2328 2329 llvm::Type *EncompassingLLVMTy = 2330 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width); 2331 2332 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy); 2333 2334 llvm::Intrinsic::ID IntrinsicId; 2335 switch (BuiltinID) { 2336 default: 2337 llvm_unreachable("Unknown overflow builtin id."); 2338 case Builtin::BI__builtin_add_overflow: 2339 IntrinsicId = EncompassingInfo.Signed 2340 ? llvm::Intrinsic::sadd_with_overflow 2341 : llvm::Intrinsic::uadd_with_overflow; 2342 break; 2343 case Builtin::BI__builtin_sub_overflow: 2344 IntrinsicId = EncompassingInfo.Signed 2345 ? llvm::Intrinsic::ssub_with_overflow 2346 : llvm::Intrinsic::usub_with_overflow; 2347 break; 2348 case Builtin::BI__builtin_mul_overflow: 2349 IntrinsicId = EncompassingInfo.Signed 2350 ? llvm::Intrinsic::smul_with_overflow 2351 : llvm::Intrinsic::umul_with_overflow; 2352 break; 2353 } 2354 2355 llvm::Value *Left = EmitScalarExpr(LeftArg); 2356 llvm::Value *Right = EmitScalarExpr(RightArg); 2357 Address ResultPtr = EmitPointerWithAlignment(ResultArg); 2358 2359 // Extend each operand to the encompassing type. 2360 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed); 2361 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed); 2362 2363 // Perform the operation on the extended values. 2364 llvm::Value *Overflow, *Result; 2365 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow); 2366 2367 if (EncompassingInfo.Width > ResultInfo.Width) { 2368 // The encompassing type is wider than the result type, so we need to 2369 // truncate it. 2370 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy); 2371 2372 // To see if the truncation caused an overflow, we will extend 2373 // the result and then compare it to the original result. 2374 llvm::Value *ResultTruncExt = Builder.CreateIntCast( 2375 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed); 2376 llvm::Value *TruncationOverflow = 2377 Builder.CreateICmpNE(Result, ResultTruncExt); 2378 2379 Overflow = Builder.CreateOr(Overflow, TruncationOverflow); 2380 Result = ResultTrunc; 2381 } 2382 2383 // Finally, store the result using the pointer. 2384 bool isVolatile = 2385 ResultArg->getType()->getPointeeType().isVolatileQualified(); 2386 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile); 2387 2388 return RValue::get(Overflow); 2389 } 2390 2391 case Builtin::BI__builtin_uadd_overflow: 2392 case Builtin::BI__builtin_uaddl_overflow: 2393 case Builtin::BI__builtin_uaddll_overflow: 2394 case Builtin::BI__builtin_usub_overflow: 2395 case Builtin::BI__builtin_usubl_overflow: 2396 case Builtin::BI__builtin_usubll_overflow: 2397 case Builtin::BI__builtin_umul_overflow: 2398 case Builtin::BI__builtin_umull_overflow: 2399 case Builtin::BI__builtin_umulll_overflow: 2400 case Builtin::BI__builtin_sadd_overflow: 2401 case Builtin::BI__builtin_saddl_overflow: 2402 case Builtin::BI__builtin_saddll_overflow: 2403 case Builtin::BI__builtin_ssub_overflow: 2404 case Builtin::BI__builtin_ssubl_overflow: 2405 case Builtin::BI__builtin_ssubll_overflow: 2406 case Builtin::BI__builtin_smul_overflow: 2407 case Builtin::BI__builtin_smull_overflow: 2408 case Builtin::BI__builtin_smulll_overflow: { 2409 2410 // We translate all of these builtins directly to the relevant llvm IR node. 2411 2412 // Scalarize our inputs. 2413 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2414 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2415 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2)); 2416 2417 // Decide which of the overflow intrinsics we are lowering to: 2418 llvm::Intrinsic::ID IntrinsicId; 2419 switch (BuiltinID) { 2420 default: llvm_unreachable("Unknown overflow builtin id."); 2421 case Builtin::BI__builtin_uadd_overflow: 2422 case Builtin::BI__builtin_uaddl_overflow: 2423 case Builtin::BI__builtin_uaddll_overflow: 2424 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2425 break; 2426 case Builtin::BI__builtin_usub_overflow: 2427 case Builtin::BI__builtin_usubl_overflow: 2428 case Builtin::BI__builtin_usubll_overflow: 2429 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2430 break; 2431 case Builtin::BI__builtin_umul_overflow: 2432 case Builtin::BI__builtin_umull_overflow: 2433 case Builtin::BI__builtin_umulll_overflow: 2434 IntrinsicId = llvm::Intrinsic::umul_with_overflow; 2435 break; 2436 case Builtin::BI__builtin_sadd_overflow: 2437 case Builtin::BI__builtin_saddl_overflow: 2438 case Builtin::BI__builtin_saddll_overflow: 2439 IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 2440 break; 2441 case Builtin::BI__builtin_ssub_overflow: 2442 case Builtin::BI__builtin_ssubl_overflow: 2443 case Builtin::BI__builtin_ssubll_overflow: 2444 IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 2445 break; 2446 case Builtin::BI__builtin_smul_overflow: 2447 case Builtin::BI__builtin_smull_overflow: 2448 case Builtin::BI__builtin_smulll_overflow: 2449 IntrinsicId = llvm::Intrinsic::smul_with_overflow; 2450 break; 2451 } 2452 2453 2454 llvm::Value *Carry; 2455 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 2456 Builder.CreateStore(Sum, SumOutPtr); 2457 2458 return RValue::get(Carry); 2459 } 2460 case Builtin::BI__builtin_addressof: 2461 return RValue::get(EmitLValue(E->getArg(0)).getPointer()); 2462 case Builtin::BI__builtin_operator_new: 2463 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2464 E->getArg(0), false); 2465 case Builtin::BI__builtin_operator_delete: 2466 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2467 E->getArg(0), true); 2468 case Builtin::BI__noop: 2469 // __noop always evaluates to an integer literal zero. 2470 return RValue::get(ConstantInt::get(IntTy, 0)); 2471 case Builtin::BI__builtin_call_with_static_chain: { 2472 const CallExpr *Call = cast<CallExpr>(E->getArg(0)); 2473 const Expr *Chain = E->getArg(1); 2474 return EmitCall(Call->getCallee()->getType(), 2475 EmitCallee(Call->getCallee()), Call, ReturnValue, 2476 EmitScalarExpr(Chain)); 2477 } 2478 case Builtin::BI_InterlockedExchange8: 2479 case Builtin::BI_InterlockedExchange16: 2480 case Builtin::BI_InterlockedExchange: 2481 case Builtin::BI_InterlockedExchangePointer: 2482 return RValue::get( 2483 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E)); 2484 case Builtin::BI_InterlockedCompareExchangePointer: { 2485 llvm::Type *RTy; 2486 llvm::IntegerType *IntType = 2487 IntegerType::get(getLLVMContext(), 2488 getContext().getTypeSize(E->getType())); 2489 llvm::Type *IntPtrType = IntType->getPointerTo(); 2490 2491 llvm::Value *Destination = 2492 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType); 2493 2494 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1)); 2495 RTy = Exchange->getType(); 2496 Exchange = Builder.CreatePtrToInt(Exchange, IntType); 2497 2498 llvm::Value *Comparand = 2499 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType); 2500 2501 auto Result = 2502 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange, 2503 AtomicOrdering::SequentiallyConsistent, 2504 AtomicOrdering::SequentiallyConsistent); 2505 Result->setVolatile(true); 2506 2507 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result, 2508 0), 2509 RTy)); 2510 } 2511 case Builtin::BI_InterlockedCompareExchange8: 2512 case Builtin::BI_InterlockedCompareExchange16: 2513 case Builtin::BI_InterlockedCompareExchange: 2514 case Builtin::BI_InterlockedCompareExchange64: { 2515 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg( 2516 EmitScalarExpr(E->getArg(0)), 2517 EmitScalarExpr(E->getArg(2)), 2518 EmitScalarExpr(E->getArg(1)), 2519 AtomicOrdering::SequentiallyConsistent, 2520 AtomicOrdering::SequentiallyConsistent); 2521 CXI->setVolatile(true); 2522 return RValue::get(Builder.CreateExtractValue(CXI, 0)); 2523 } 2524 case Builtin::BI_InterlockedIncrement16: 2525 case Builtin::BI_InterlockedIncrement: 2526 return RValue::get( 2527 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E)); 2528 case Builtin::BI_InterlockedDecrement16: 2529 case Builtin::BI_InterlockedDecrement: 2530 return RValue::get( 2531 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E)); 2532 case Builtin::BI_InterlockedAnd8: 2533 case Builtin::BI_InterlockedAnd16: 2534 case Builtin::BI_InterlockedAnd: 2535 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E)); 2536 case Builtin::BI_InterlockedExchangeAdd8: 2537 case Builtin::BI_InterlockedExchangeAdd16: 2538 case Builtin::BI_InterlockedExchangeAdd: 2539 return RValue::get( 2540 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E)); 2541 case Builtin::BI_InterlockedExchangeSub8: 2542 case Builtin::BI_InterlockedExchangeSub16: 2543 case Builtin::BI_InterlockedExchangeSub: 2544 return RValue::get( 2545 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E)); 2546 case Builtin::BI_InterlockedOr8: 2547 case Builtin::BI_InterlockedOr16: 2548 case Builtin::BI_InterlockedOr: 2549 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E)); 2550 case Builtin::BI_InterlockedXor8: 2551 case Builtin::BI_InterlockedXor16: 2552 case Builtin::BI_InterlockedXor: 2553 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E)); 2554 case Builtin::BI_interlockedbittestandset: 2555 return RValue::get( 2556 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E)); 2557 2558 case Builtin::BI__exception_code: 2559 case Builtin::BI_exception_code: 2560 return RValue::get(EmitSEHExceptionCode()); 2561 case Builtin::BI__exception_info: 2562 case Builtin::BI_exception_info: 2563 return RValue::get(EmitSEHExceptionInfo()); 2564 case Builtin::BI__abnormal_termination: 2565 case Builtin::BI_abnormal_termination: 2566 return RValue::get(EmitSEHAbnormalTermination()); 2567 case Builtin::BI_setjmpex: { 2568 if (getTarget().getTriple().isOSMSVCRT()) { 2569 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2570 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2571 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2572 llvm::Attribute::ReturnsTwice); 2573 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction( 2574 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2575 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true); 2576 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2577 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2578 llvm::Value *FrameAddr = 2579 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2580 ConstantInt::get(Int32Ty, 0)); 2581 llvm::Value *Args[] = {Buf, FrameAddr}; 2582 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args); 2583 CS.setAttributes(ReturnsTwiceAttr); 2584 return RValue::get(CS.getInstruction()); 2585 } 2586 break; 2587 } 2588 case Builtin::BI_setjmp: { 2589 if (getTarget().getTriple().isOSMSVCRT()) { 2590 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2591 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2592 llvm::Attribute::ReturnsTwice); 2593 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2594 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2595 llvm::CallSite CS; 2596 if (getTarget().getTriple().getArch() == llvm::Triple::x86) { 2597 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy}; 2598 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction( 2599 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true), 2600 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true); 2601 llvm::Value *Count = ConstantInt::get(IntTy, 0); 2602 llvm::Value *Args[] = {Buf, Count}; 2603 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args); 2604 } else { 2605 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2606 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( 2607 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2608 "_setjmp", ReturnsTwiceAttr, /*Local=*/true); 2609 llvm::Value *FrameAddr = 2610 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2611 ConstantInt::get(Int32Ty, 0)); 2612 llvm::Value *Args[] = {Buf, FrameAddr}; 2613 CS = EmitRuntimeCallOrInvoke(SetJmp, Args); 2614 } 2615 CS.setAttributes(ReturnsTwiceAttr); 2616 return RValue::get(CS.getInstruction()); 2617 } 2618 break; 2619 } 2620 2621 case Builtin::BI__GetExceptionInfo: { 2622 if (llvm::GlobalVariable *GV = 2623 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType())) 2624 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy)); 2625 break; 2626 } 2627 2628 case Builtin::BI__fastfail: 2629 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E)); 2630 2631 case Builtin::BI__builtin_coro_size: { 2632 auto & Context = getContext(); 2633 auto SizeTy = Context.getSizeType(); 2634 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy)); 2635 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T); 2636 return RValue::get(Builder.CreateCall(F)); 2637 } 2638 2639 case Builtin::BI__builtin_coro_id: 2640 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id); 2641 case Builtin::BI__builtin_coro_promise: 2642 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise); 2643 case Builtin::BI__builtin_coro_resume: 2644 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume); 2645 case Builtin::BI__builtin_coro_frame: 2646 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame); 2647 case Builtin::BI__builtin_coro_free: 2648 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free); 2649 case Builtin::BI__builtin_coro_destroy: 2650 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy); 2651 case Builtin::BI__builtin_coro_done: 2652 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done); 2653 case Builtin::BI__builtin_coro_alloc: 2654 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc); 2655 case Builtin::BI__builtin_coro_begin: 2656 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin); 2657 case Builtin::BI__builtin_coro_end: 2658 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end); 2659 case Builtin::BI__builtin_coro_suspend: 2660 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend); 2661 case Builtin::BI__builtin_coro_param: 2662 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param); 2663 2664 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions 2665 case Builtin::BIread_pipe: 2666 case Builtin::BIwrite_pipe: { 2667 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2668 *Arg1 = EmitScalarExpr(E->getArg(1)); 2669 CGOpenCLRuntime OpenCLRT(CGM); 2670 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2671 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2672 2673 // Type of the generic packet parameter. 2674 unsigned GenericAS = 2675 getContext().getTargetAddressSpace(LangAS::opencl_generic); 2676 llvm::Type *I8PTy = llvm::PointerType::get( 2677 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS); 2678 2679 // Testing which overloaded version we should generate the call for. 2680 if (2U == E->getNumArgs()) { 2681 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2" 2682 : "__write_pipe_2"; 2683 // Creating a generic function type to be able to call with any builtin or 2684 // user defined type. 2685 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty}; 2686 llvm::FunctionType *FTy = llvm::FunctionType::get( 2687 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2688 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy); 2689 return RValue::get( 2690 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2691 {Arg0, BCast, PacketSize, PacketAlign})); 2692 } else { 2693 assert(4 == E->getNumArgs() && 2694 "Illegal number of parameters to pipe function"); 2695 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4" 2696 : "__write_pipe_4"; 2697 2698 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy, 2699 Int32Ty, Int32Ty}; 2700 Value *Arg2 = EmitScalarExpr(E->getArg(2)), 2701 *Arg3 = EmitScalarExpr(E->getArg(3)); 2702 llvm::FunctionType *FTy = llvm::FunctionType::get( 2703 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2704 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy); 2705 // We know the third argument is an integer type, but we may need to cast 2706 // it to i32. 2707 if (Arg2->getType() != Int32Ty) 2708 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty); 2709 return RValue::get(Builder.CreateCall( 2710 CGM.CreateRuntimeFunction(FTy, Name), 2711 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign})); 2712 } 2713 } 2714 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write 2715 // functions 2716 case Builtin::BIreserve_read_pipe: 2717 case Builtin::BIreserve_write_pipe: 2718 case Builtin::BIwork_group_reserve_read_pipe: 2719 case Builtin::BIwork_group_reserve_write_pipe: 2720 case Builtin::BIsub_group_reserve_read_pipe: 2721 case Builtin::BIsub_group_reserve_write_pipe: { 2722 // Composing the mangled name for the function. 2723 const char *Name; 2724 if (BuiltinID == Builtin::BIreserve_read_pipe) 2725 Name = "__reserve_read_pipe"; 2726 else if (BuiltinID == Builtin::BIreserve_write_pipe) 2727 Name = "__reserve_write_pipe"; 2728 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe) 2729 Name = "__work_group_reserve_read_pipe"; 2730 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe) 2731 Name = "__work_group_reserve_write_pipe"; 2732 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe) 2733 Name = "__sub_group_reserve_read_pipe"; 2734 else 2735 Name = "__sub_group_reserve_write_pipe"; 2736 2737 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2738 *Arg1 = EmitScalarExpr(E->getArg(1)); 2739 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy); 2740 CGOpenCLRuntime OpenCLRT(CGM); 2741 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2742 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2743 2744 // Building the generic function prototype. 2745 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty}; 2746 llvm::FunctionType *FTy = llvm::FunctionType::get( 2747 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2748 // We know the second argument is an integer type, but we may need to cast 2749 // it to i32. 2750 if (Arg1->getType() != Int32Ty) 2751 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty); 2752 return RValue::get( 2753 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2754 {Arg0, Arg1, PacketSize, PacketAlign})); 2755 } 2756 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write 2757 // functions 2758 case Builtin::BIcommit_read_pipe: 2759 case Builtin::BIcommit_write_pipe: 2760 case Builtin::BIwork_group_commit_read_pipe: 2761 case Builtin::BIwork_group_commit_write_pipe: 2762 case Builtin::BIsub_group_commit_read_pipe: 2763 case Builtin::BIsub_group_commit_write_pipe: { 2764 const char *Name; 2765 if (BuiltinID == Builtin::BIcommit_read_pipe) 2766 Name = "__commit_read_pipe"; 2767 else if (BuiltinID == Builtin::BIcommit_write_pipe) 2768 Name = "__commit_write_pipe"; 2769 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe) 2770 Name = "__work_group_commit_read_pipe"; 2771 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe) 2772 Name = "__work_group_commit_write_pipe"; 2773 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe) 2774 Name = "__sub_group_commit_read_pipe"; 2775 else 2776 Name = "__sub_group_commit_write_pipe"; 2777 2778 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2779 *Arg1 = EmitScalarExpr(E->getArg(1)); 2780 CGOpenCLRuntime OpenCLRT(CGM); 2781 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2782 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2783 2784 // Building the generic function prototype. 2785 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty}; 2786 llvm::FunctionType *FTy = 2787 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 2788 llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2789 2790 return RValue::get( 2791 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2792 {Arg0, Arg1, PacketSize, PacketAlign})); 2793 } 2794 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions 2795 case Builtin::BIget_pipe_num_packets: 2796 case Builtin::BIget_pipe_max_packets: { 2797 const char *Name; 2798 if (BuiltinID == Builtin::BIget_pipe_num_packets) 2799 Name = "__get_pipe_num_packets"; 2800 else 2801 Name = "__get_pipe_max_packets"; 2802 2803 // Building the generic function prototype. 2804 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 2805 CGOpenCLRuntime OpenCLRT(CGM); 2806 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2807 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2808 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty}; 2809 llvm::FunctionType *FTy = llvm::FunctionType::get( 2810 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2811 2812 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2813 {Arg0, PacketSize, PacketAlign})); 2814 } 2815 2816 // OpenCL v2.0 s6.13.9 - Address space qualifier functions. 2817 case Builtin::BIto_global: 2818 case Builtin::BIto_local: 2819 case Builtin::BIto_private: { 2820 auto Arg0 = EmitScalarExpr(E->getArg(0)); 2821 auto NewArgT = llvm::PointerType::get(Int8Ty, 2822 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2823 auto NewRetT = llvm::PointerType::get(Int8Ty, 2824 CGM.getContext().getTargetAddressSpace( 2825 E->getType()->getPointeeType().getAddressSpace())); 2826 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false); 2827 llvm::Value *NewArg; 2828 if (Arg0->getType()->getPointerAddressSpace() != 2829 NewArgT->getPointerAddressSpace()) 2830 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT); 2831 else 2832 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT); 2833 auto NewName = std::string("__") + E->getDirectCallee()->getName().str(); 2834 auto NewCall = 2835 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg}); 2836 return RValue::get(Builder.CreateBitOrPointerCast(NewCall, 2837 ConvertType(E->getType()))); 2838 } 2839 2840 // OpenCL v2.0, s6.13.17 - Enqueue kernel function. 2841 // It contains four different overload formats specified in Table 6.13.17.1. 2842 case Builtin::BIenqueue_kernel: { 2843 StringRef Name; // Generated function call name 2844 unsigned NumArgs = E->getNumArgs(); 2845 2846 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy); 2847 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2848 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2849 2850 llvm::Value *Queue = EmitScalarExpr(E->getArg(0)); 2851 llvm::Value *Flags = EmitScalarExpr(E->getArg(1)); 2852 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2)); 2853 llvm::Value *Range = NDRangeL.getAddress().getPointer(); 2854 llvm::Type *RangeTy = NDRangeL.getAddress().getType(); 2855 2856 if (NumArgs == 4) { 2857 // The most basic form of the call with parameters: 2858 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void) 2859 Name = "__enqueue_kernel_basic"; 2860 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy, 2861 GenericVoidPtrTy}; 2862 llvm::FunctionType *FTy = llvm::FunctionType::get( 2863 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2864 2865 auto Info = 2866 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2867 llvm::Value *Kernel = 2868 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2869 llvm::Value *Block = 2870 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2871 2872 AttrBuilder B; 2873 B.addAttribute(Attribute::ByVal); 2874 llvm::AttributeList ByValAttrSet = 2875 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B); 2876 2877 auto RTCall = 2878 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet), 2879 {Queue, Flags, Range, Kernel, Block}); 2880 RTCall->setAttributes(ByValAttrSet); 2881 return RValue::get(RTCall); 2882 } 2883 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature"); 2884 2885 // Create a temporary array to hold the sizes of local pointer arguments 2886 // for the block. \p First is the position of the first size argument. 2887 auto CreateArrayForSizeVar = [=](unsigned First) { 2888 auto *AT = llvm::ArrayType::get(SizeTy, NumArgs - First); 2889 auto *Arr = Builder.CreateAlloca(AT); 2890 llvm::Value *Ptr; 2891 // Each of the following arguments specifies the size of the corresponding 2892 // argument passed to the enqueued block. 2893 auto *Zero = llvm::ConstantInt::get(IntTy, 0); 2894 for (unsigned I = First; I < NumArgs; ++I) { 2895 auto *Index = llvm::ConstantInt::get(IntTy, I - First); 2896 auto *GEP = Builder.CreateGEP(Arr, {Zero, Index}); 2897 if (I == First) 2898 Ptr = GEP; 2899 auto *V = 2900 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy); 2901 Builder.CreateAlignedStore( 2902 V, GEP, CGM.getDataLayout().getPrefTypeAlignment(SizeTy)); 2903 } 2904 return Ptr; 2905 }; 2906 2907 // Could have events and/or vaargs. 2908 if (E->getArg(3)->getType()->isBlockPointerType()) { 2909 // No events passed, but has variadic arguments. 2910 Name = "__enqueue_kernel_vaargs"; 2911 auto Info = 2912 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2913 llvm::Value *Kernel = 2914 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2915 auto *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2916 auto *PtrToSizeArray = CreateArrayForSizeVar(4); 2917 2918 // Create a vector of the arguments, as well as a constant value to 2919 // express to the runtime the number of variadic arguments. 2920 std::vector<llvm::Value *> Args = { 2921 Queue, Flags, Range, 2922 Kernel, Block, ConstantInt::get(IntTy, NumArgs - 4), 2923 PtrToSizeArray}; 2924 std::vector<llvm::Type *> ArgTys = { 2925 QueueTy, IntTy, RangeTy, 2926 GenericVoidPtrTy, GenericVoidPtrTy, IntTy, 2927 PtrToSizeArray->getType()}; 2928 2929 llvm::FunctionType *FTy = llvm::FunctionType::get( 2930 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2931 return RValue::get( 2932 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2933 llvm::ArrayRef<llvm::Value *>(Args))); 2934 } 2935 // Any calls now have event arguments passed. 2936 if (NumArgs >= 7) { 2937 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy); 2938 llvm::Type *EventPtrTy = EventTy->getPointerTo( 2939 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2940 2941 llvm::Value *NumEvents = 2942 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty); 2943 llvm::Value *EventList = 2944 E->getArg(4)->getType()->isArrayType() 2945 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer() 2946 : EmitScalarExpr(E->getArg(4)); 2947 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5)); 2948 // Convert to generic address space. 2949 EventList = Builder.CreatePointerCast(EventList, EventPtrTy); 2950 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy); 2951 auto Info = 2952 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(6)); 2953 llvm::Value *Kernel = 2954 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2955 llvm::Value *Block = 2956 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2957 2958 std::vector<llvm::Type *> ArgTys = { 2959 QueueTy, Int32Ty, RangeTy, Int32Ty, 2960 EventPtrTy, EventPtrTy, GenericVoidPtrTy, GenericVoidPtrTy}; 2961 2962 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents, 2963 EventList, ClkEvent, Kernel, Block}; 2964 2965 if (NumArgs == 7) { 2966 // Has events but no variadics. 2967 Name = "__enqueue_kernel_basic_events"; 2968 llvm::FunctionType *FTy = llvm::FunctionType::get( 2969 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2970 return RValue::get( 2971 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2972 llvm::ArrayRef<llvm::Value *>(Args))); 2973 } 2974 // Has event info and variadics 2975 // Pass the number of variadics to the runtime function too. 2976 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7)); 2977 ArgTys.push_back(Int32Ty); 2978 Name = "__enqueue_kernel_events_vaargs"; 2979 2980 auto *PtrToSizeArray = CreateArrayForSizeVar(7); 2981 Args.push_back(PtrToSizeArray); 2982 ArgTys.push_back(PtrToSizeArray->getType()); 2983 2984 llvm::FunctionType *FTy = llvm::FunctionType::get( 2985 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2986 return RValue::get( 2987 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2988 llvm::ArrayRef<llvm::Value *>(Args))); 2989 } 2990 LLVM_FALLTHROUGH; 2991 } 2992 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block 2993 // parameter. 2994 case Builtin::BIget_kernel_work_group_size: { 2995 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2996 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2997 auto Info = 2998 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 2999 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 3000 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 3001 return RValue::get(Builder.CreateCall( 3002 CGM.CreateRuntimeFunction( 3003 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 3004 false), 3005 "__get_kernel_work_group_size_impl"), 3006 {Kernel, Arg})); 3007 } 3008 case Builtin::BIget_kernel_preferred_work_group_size_multiple: { 3009 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 3010 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 3011 auto Info = 3012 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 3013 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 3014 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 3015 return RValue::get(Builder.CreateCall( 3016 CGM.CreateRuntimeFunction( 3017 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 3018 false), 3019 "__get_kernel_preferred_work_group_multiple_impl"), 3020 {Kernel, Arg})); 3021 } 3022 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange: 3023 case Builtin::BIget_kernel_sub_group_count_for_ndrange: { 3024 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 3025 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 3026 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0)); 3027 llvm::Value *NDRange = NDRangeL.getAddress().getPointer(); 3028 auto Info = 3029 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(1)); 3030 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 3031 Value *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 3032 const char *Name = 3033 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange 3034 ? "__get_kernel_max_sub_group_size_for_ndrange_impl" 3035 : "__get_kernel_sub_group_count_for_ndrange_impl"; 3036 return RValue::get(Builder.CreateCall( 3037 CGM.CreateRuntimeFunction( 3038 llvm::FunctionType::get( 3039 IntTy, {NDRange->getType(), GenericVoidPtrTy, GenericVoidPtrTy}, 3040 false), 3041 Name), 3042 {NDRange, Kernel, Block})); 3043 } 3044 3045 case Builtin::BI__builtin_store_half: 3046 case Builtin::BI__builtin_store_halff: { 3047 Value *Val = EmitScalarExpr(E->getArg(0)); 3048 Address Address = EmitPointerWithAlignment(E->getArg(1)); 3049 Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy()); 3050 return RValue::get(Builder.CreateStore(HalfVal, Address)); 3051 } 3052 case Builtin::BI__builtin_load_half: { 3053 Address Address = EmitPointerWithAlignment(E->getArg(0)); 3054 Value *HalfVal = Builder.CreateLoad(Address); 3055 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy())); 3056 } 3057 case Builtin::BI__builtin_load_halff: { 3058 Address Address = EmitPointerWithAlignment(E->getArg(0)); 3059 Value *HalfVal = Builder.CreateLoad(Address); 3060 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy())); 3061 } 3062 case Builtin::BIprintf: 3063 if (getTarget().getTriple().isNVPTX()) 3064 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue); 3065 break; 3066 case Builtin::BI__builtin_canonicalize: 3067 case Builtin::BI__builtin_canonicalizef: 3068 case Builtin::BI__builtin_canonicalizel: 3069 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize)); 3070 3071 case Builtin::BI__builtin_thread_pointer: { 3072 if (!getContext().getTargetInfo().isTLSSupported()) 3073 CGM.ErrorUnsupported(E, "__builtin_thread_pointer"); 3074 // Fall through - it's already mapped to the intrinsic by GCCBuiltin. 3075 break; 3076 } 3077 case Builtin::BI__builtin_os_log_format: 3078 return emitBuiltinOSLogFormat(*E); 3079 3080 case Builtin::BI__builtin_os_log_format_buffer_size: { 3081 analyze_os_log::OSLogBufferLayout Layout; 3082 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); 3083 return RValue::get(ConstantInt::get(ConvertType(E->getType()), 3084 Layout.size().getQuantity())); 3085 } 3086 3087 case Builtin::BI__xray_customevent: { 3088 if (!ShouldXRayInstrumentFunction()) 3089 return RValue::getIgnored(); 3090 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) 3091 if (XRayAttr->neverXRayInstrument() && !AlwaysEmitXRayCustomEvents()) 3092 return RValue::getIgnored(); 3093 3094 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent); 3095 auto FTy = F->getFunctionType(); 3096 auto Arg0 = E->getArg(0); 3097 auto Arg0Val = EmitScalarExpr(Arg0); 3098 auto Arg0Ty = Arg0->getType(); 3099 auto PTy0 = FTy->getParamType(0); 3100 if (PTy0 != Arg0Val->getType()) { 3101 if (Arg0Ty->isArrayType()) 3102 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer(); 3103 else 3104 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0); 3105 } 3106 auto Arg1 = EmitScalarExpr(E->getArg(1)); 3107 auto PTy1 = FTy->getParamType(1); 3108 if (PTy1 != Arg1->getType()) 3109 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1); 3110 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1})); 3111 } 3112 3113 case Builtin::BI__builtin_ms_va_start: 3114 case Builtin::BI__builtin_ms_va_end: 3115 return RValue::get( 3116 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(), 3117 BuiltinID == Builtin::BI__builtin_ms_va_start)); 3118 3119 case Builtin::BI__builtin_ms_va_copy: { 3120 // Lower this manually. We can't reliably determine whether or not any 3121 // given va_copy() is for a Win64 va_list from the calling convention 3122 // alone, because it's legal to do this from a System V ABI function. 3123 // With opaque pointer types, we won't have enough information in LLVM 3124 // IR to determine this from the argument types, either. Best to do it 3125 // now, while we have enough information. 3126 Address DestAddr = EmitMSVAListRef(E->getArg(0)); 3127 Address SrcAddr = EmitMSVAListRef(E->getArg(1)); 3128 3129 llvm::Type *BPP = Int8PtrPtrTy; 3130 3131 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"), 3132 DestAddr.getAlignment()); 3133 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"), 3134 SrcAddr.getAlignment()); 3135 3136 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); 3137 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr)); 3138 } 3139 } 3140 3141 // If this is an alias for a lib function (e.g. __builtin_sin), emit 3142 // the call using the normal call path, but using the unmangled 3143 // version of the function name. 3144 if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 3145 return emitLibraryCall(*this, FD, E, 3146 CGM.getBuiltinLibFunction(FD, BuiltinID)); 3147 3148 // If this is a predefined lib function (e.g. malloc), emit the call 3149 // using exactly the normal call path. 3150 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 3151 return emitLibraryCall(*this, FD, E, 3152 cast<llvm::Constant>(EmitScalarExpr(E->getCallee()))); 3153 3154 // Check that a call to a target specific builtin has the correct target 3155 // features. 3156 // This is down here to avoid non-target specific builtins, however, if 3157 // generic builtins start to require generic target features then we 3158 // can move this up to the beginning of the function. 3159 checkTargetFeatures(E, FD); 3160 3161 // See if we have a target specific intrinsic. 3162 const char *Name = getContext().BuiltinInfo.getName(BuiltinID); 3163 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 3164 StringRef Prefix = 3165 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); 3166 if (!Prefix.empty()) { 3167 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name); 3168 // NOTE we dont need to perform a compatibility flag check here since the 3169 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the 3170 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. 3171 if (IntrinsicID == Intrinsic::not_intrinsic) 3172 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name); 3173 } 3174 3175 if (IntrinsicID != Intrinsic::not_intrinsic) { 3176 SmallVector<Value*, 16> Args; 3177 3178 // Find out if any arguments are required to be integer constant 3179 // expressions. 3180 unsigned ICEArguments = 0; 3181 ASTContext::GetBuiltinTypeError Error; 3182 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 3183 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 3184 3185 Function *F = CGM.getIntrinsic(IntrinsicID); 3186 llvm::FunctionType *FTy = F->getFunctionType(); 3187 3188 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 3189 Value *ArgValue; 3190 // If this is a normal argument, just emit it as a scalar. 3191 if ((ICEArguments & (1 << i)) == 0) { 3192 ArgValue = EmitScalarExpr(E->getArg(i)); 3193 } else { 3194 // If this is required to be a constant, constant fold it so that we 3195 // know that the generated intrinsic gets a ConstantInt. 3196 llvm::APSInt Result; 3197 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 3198 assert(IsConst && "Constant arg isn't actually constant?"); 3199 (void)IsConst; 3200 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 3201 } 3202 3203 // If the intrinsic arg type is different from the builtin arg type 3204 // we need to do a bit cast. 3205 llvm::Type *PTy = FTy->getParamType(i); 3206 if (PTy != ArgValue->getType()) { 3207 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 3208 "Must be able to losslessly bit cast to param"); 3209 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 3210 } 3211 3212 Args.push_back(ArgValue); 3213 } 3214 3215 Value *V = Builder.CreateCall(F, Args); 3216 QualType BuiltinRetType = E->getType(); 3217 3218 llvm::Type *RetTy = VoidTy; 3219 if (!BuiltinRetType->isVoidType()) 3220 RetTy = ConvertType(BuiltinRetType); 3221 3222 if (RetTy != V->getType()) { 3223 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 3224 "Must be able to losslessly bit cast result type"); 3225 V = Builder.CreateBitCast(V, RetTy); 3226 } 3227 3228 return RValue::get(V); 3229 } 3230 3231 // See if we have a target specific builtin that needs to be lowered. 3232 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 3233 return RValue::get(V); 3234 3235 ErrorUnsupported(E, "builtin function"); 3236 3237 // Unknown builtin, for now just dump it out and return undef. 3238 return GetUndefRValue(E->getType()); 3239 } 3240 3241 static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, 3242 unsigned BuiltinID, const CallExpr *E, 3243 llvm::Triple::ArchType Arch) { 3244 switch (Arch) { 3245 case llvm::Triple::arm: 3246 case llvm::Triple::armeb: 3247 case llvm::Triple::thumb: 3248 case llvm::Triple::thumbeb: 3249 return CGF->EmitARMBuiltinExpr(BuiltinID, E); 3250 case llvm::Triple::aarch64: 3251 case llvm::Triple::aarch64_be: 3252 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E); 3253 case llvm::Triple::x86: 3254 case llvm::Triple::x86_64: 3255 return CGF->EmitX86BuiltinExpr(BuiltinID, E); 3256 case llvm::Triple::ppc: 3257 case llvm::Triple::ppc64: 3258 case llvm::Triple::ppc64le: 3259 return CGF->EmitPPCBuiltinExpr(BuiltinID, E); 3260 case llvm::Triple::r600: 3261 case llvm::Triple::amdgcn: 3262 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E); 3263 case llvm::Triple::systemz: 3264 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E); 3265 case llvm::Triple::nvptx: 3266 case llvm::Triple::nvptx64: 3267 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E); 3268 case llvm::Triple::wasm32: 3269 case llvm::Triple::wasm64: 3270 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E); 3271 case llvm::Triple::hexagon: 3272 return CGF->EmitHexagonBuiltinExpr(BuiltinID, E); 3273 default: 3274 return nullptr; 3275 } 3276 } 3277 3278 Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 3279 const CallExpr *E) { 3280 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { 3281 assert(getContext().getAuxTargetInfo() && "Missing aux target info"); 3282 return EmitTargetArchBuiltinExpr( 3283 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E, 3284 getContext().getAuxTargetInfo()->getTriple().getArch()); 3285 } 3286 3287 return EmitTargetArchBuiltinExpr(this, BuiltinID, E, 3288 getTarget().getTriple().getArch()); 3289 } 3290 3291 static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 3292 NeonTypeFlags TypeFlags, 3293 bool V1Ty=false) { 3294 int IsQuad = TypeFlags.isQuad(); 3295 switch (TypeFlags.getEltType()) { 3296 case NeonTypeFlags::Int8: 3297 case NeonTypeFlags::Poly8: 3298 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); 3299 case NeonTypeFlags::Int16: 3300 case NeonTypeFlags::Poly16: 3301 case NeonTypeFlags::Float16: 3302 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); 3303 case NeonTypeFlags::Int32: 3304 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); 3305 case NeonTypeFlags::Int64: 3306 case NeonTypeFlags::Poly64: 3307 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad)); 3308 case NeonTypeFlags::Poly128: 3309 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm. 3310 // There is a lot of i128 and f128 API missing. 3311 // so we use v16i8 to represent poly128 and get pattern matched. 3312 return llvm::VectorType::get(CGF->Int8Ty, 16); 3313 case NeonTypeFlags::Float32: 3314 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); 3315 case NeonTypeFlags::Float64: 3316 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad)); 3317 } 3318 llvm_unreachable("Unknown vector element type!"); 3319 } 3320 3321 static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF, 3322 NeonTypeFlags IntTypeFlags) { 3323 int IsQuad = IntTypeFlags.isQuad(); 3324 switch (IntTypeFlags.getEltType()) { 3325 case NeonTypeFlags::Int32: 3326 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad)); 3327 case NeonTypeFlags::Int64: 3328 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad)); 3329 default: 3330 llvm_unreachable("Type can't be converted to floating-point!"); 3331 } 3332 } 3333 3334 Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 3335 unsigned nElts = V->getType()->getVectorNumElements(); 3336 Value* SV = llvm::ConstantVector::getSplat(nElts, C); 3337 return Builder.CreateShuffleVector(V, V, SV, "lane"); 3338 } 3339 3340 Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 3341 const char *name, 3342 unsigned shift, bool rightshift) { 3343 unsigned j = 0; 3344 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3345 ai != ae; ++ai, ++j) 3346 if (shift > 0 && shift == j) 3347 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 3348 else 3349 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 3350 3351 return Builder.CreateCall(F, Ops, name); 3352 } 3353 3354 Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 3355 bool neg) { 3356 int SV = cast<ConstantInt>(V)->getSExtValue(); 3357 return ConstantInt::get(Ty, neg ? -SV : SV); 3358 } 3359 3360 // \brief Right-shift a vector by a constant. 3361 Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, 3362 llvm::Type *Ty, bool usgn, 3363 const char *name) { 3364 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3365 3366 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); 3367 int EltSize = VTy->getScalarSizeInBits(); 3368 3369 Vec = Builder.CreateBitCast(Vec, Ty); 3370 3371 // lshr/ashr are undefined when the shift amount is equal to the vector 3372 // element size. 3373 if (ShiftAmt == EltSize) { 3374 if (usgn) { 3375 // Right-shifting an unsigned value by its size yields 0. 3376 return llvm::ConstantAggregateZero::get(VTy); 3377 } else { 3378 // Right-shifting a signed value by its size is equivalent 3379 // to a shift of size-1. 3380 --ShiftAmt; 3381 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); 3382 } 3383 } 3384 3385 Shift = EmitNeonShiftVector(Shift, Ty, false); 3386 if (usgn) 3387 return Builder.CreateLShr(Vec, Shift, name); 3388 else 3389 return Builder.CreateAShr(Vec, Shift, name); 3390 } 3391 3392 enum { 3393 AddRetType = (1 << 0), 3394 Add1ArgType = (1 << 1), 3395 Add2ArgTypes = (1 << 2), 3396 3397 VectorizeRetType = (1 << 3), 3398 VectorizeArgTypes = (1 << 4), 3399 3400 InventFloatType = (1 << 5), 3401 UnsignedAlts = (1 << 6), 3402 3403 Use64BitVectors = (1 << 7), 3404 Use128BitVectors = (1 << 8), 3405 3406 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes, 3407 VectorRet = AddRetType | VectorizeRetType, 3408 VectorRetGetArgs01 = 3409 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes, 3410 FpCmpzModifiers = 3411 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType 3412 }; 3413 3414 namespace { 3415 struct NeonIntrinsicInfo { 3416 const char *NameHint; 3417 unsigned BuiltinID; 3418 unsigned LLVMIntrinsic; 3419 unsigned AltLLVMIntrinsic; 3420 unsigned TypeModifier; 3421 3422 bool operator<(unsigned RHSBuiltinID) const { 3423 return BuiltinID < RHSBuiltinID; 3424 } 3425 bool operator<(const NeonIntrinsicInfo &TE) const { 3426 return BuiltinID < TE.BuiltinID; 3427 } 3428 }; 3429 } // end anonymous namespace 3430 3431 #define NEONMAP0(NameBase) \ 3432 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 } 3433 3434 #define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ 3435 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3436 Intrinsic::LLVMIntrinsic, 0, TypeModifier } 3437 3438 #define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \ 3439 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3440 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ 3441 TypeModifier } 3442 3443 static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { 3444 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3445 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3446 NEONMAP1(vabs_v, arm_neon_vabs, 0), 3447 NEONMAP1(vabsq_v, arm_neon_vabs, 0), 3448 NEONMAP0(vaddhn_v), 3449 NEONMAP1(vaesdq_v, arm_neon_aesd, 0), 3450 NEONMAP1(vaeseq_v, arm_neon_aese, 0), 3451 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), 3452 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), 3453 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), 3454 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), 3455 NEONMAP1(vcage_v, arm_neon_vacge, 0), 3456 NEONMAP1(vcageq_v, arm_neon_vacge, 0), 3457 NEONMAP1(vcagt_v, arm_neon_vacgt, 0), 3458 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0), 3459 NEONMAP1(vcale_v, arm_neon_vacge, 0), 3460 NEONMAP1(vcaleq_v, arm_neon_vacge, 0), 3461 NEONMAP1(vcalt_v, arm_neon_vacgt, 0), 3462 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0), 3463 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType), 3464 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType), 3465 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3466 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3467 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3468 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3469 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0), 3470 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), 3471 NEONMAP0(vcvt_f32_v), 3472 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3473 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3474 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3475 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3476 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3477 NEONMAP0(vcvt_s32_v), 3478 NEONMAP0(vcvt_s64_v), 3479 NEONMAP0(vcvt_u32_v), 3480 NEONMAP0(vcvt_u64_v), 3481 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), 3482 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), 3483 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), 3484 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), 3485 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), 3486 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), 3487 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), 3488 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), 3489 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), 3490 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), 3491 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), 3492 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), 3493 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), 3494 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), 3495 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), 3496 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), 3497 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), 3498 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), 3499 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), 3500 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), 3501 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), 3502 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), 3503 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), 3504 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), 3505 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), 3506 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), 3507 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), 3508 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), 3509 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), 3510 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), 3511 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), 3512 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), 3513 NEONMAP0(vcvtq_f32_v), 3514 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3515 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3516 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3517 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3518 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3519 NEONMAP0(vcvtq_s32_v), 3520 NEONMAP0(vcvtq_s64_v), 3521 NEONMAP0(vcvtq_u32_v), 3522 NEONMAP0(vcvtq_u64_v), 3523 NEONMAP0(vext_v), 3524 NEONMAP0(vextq_v), 3525 NEONMAP0(vfma_v), 3526 NEONMAP0(vfmaq_v), 3527 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3528 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3529 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3530 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3531 NEONMAP0(vld1_dup_v), 3532 NEONMAP1(vld1_v, arm_neon_vld1, 0), 3533 NEONMAP0(vld1q_dup_v), 3534 NEONMAP1(vld1q_v, arm_neon_vld1, 0), 3535 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0), 3536 NEONMAP1(vld2_v, arm_neon_vld2, 0), 3537 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0), 3538 NEONMAP1(vld2q_v, arm_neon_vld2, 0), 3539 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0), 3540 NEONMAP1(vld3_v, arm_neon_vld3, 0), 3541 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0), 3542 NEONMAP1(vld3q_v, arm_neon_vld3, 0), 3543 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0), 3544 NEONMAP1(vld4_v, arm_neon_vld4, 0), 3545 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0), 3546 NEONMAP1(vld4q_v, arm_neon_vld4, 0), 3547 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3548 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType), 3549 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType), 3550 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3551 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3552 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType), 3553 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType), 3554 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3555 NEONMAP0(vmovl_v), 3556 NEONMAP0(vmovn_v), 3557 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType), 3558 NEONMAP0(vmull_v), 3559 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType), 3560 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3561 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3562 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType), 3563 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3564 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3565 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType), 3566 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts), 3567 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts), 3568 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType), 3569 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType), 3570 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3571 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3572 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0), 3573 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0), 3574 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType), 3575 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType), 3576 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType), 3577 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts), 3578 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), 3579 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), 3580 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), 3581 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), 3582 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), 3583 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3584 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3585 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3586 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3587 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3588 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3589 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0), 3590 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0), 3591 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3592 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3593 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType), 3594 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3595 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3596 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType), 3597 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType), 3598 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3599 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3600 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType), 3601 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType), 3602 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType), 3603 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType), 3604 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType), 3605 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType), 3606 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType), 3607 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType), 3608 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType), 3609 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType), 3610 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType), 3611 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType), 3612 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3613 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3614 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3615 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3616 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3617 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3618 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType), 3619 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType), 3620 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType), 3621 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0), 3622 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0), 3623 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0), 3624 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0), 3625 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0), 3626 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0), 3627 NEONMAP0(vshl_n_v), 3628 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3629 NEONMAP0(vshll_n_v), 3630 NEONMAP0(vshlq_n_v), 3631 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3632 NEONMAP0(vshr_n_v), 3633 NEONMAP0(vshrn_n_v), 3634 NEONMAP0(vshrq_n_v), 3635 NEONMAP1(vst1_v, arm_neon_vst1, 0), 3636 NEONMAP1(vst1q_v, arm_neon_vst1, 0), 3637 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0), 3638 NEONMAP1(vst2_v, arm_neon_vst2, 0), 3639 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0), 3640 NEONMAP1(vst2q_v, arm_neon_vst2, 0), 3641 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0), 3642 NEONMAP1(vst3_v, arm_neon_vst3, 0), 3643 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0), 3644 NEONMAP1(vst3q_v, arm_neon_vst3, 0), 3645 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0), 3646 NEONMAP1(vst4_v, arm_neon_vst4, 0), 3647 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0), 3648 NEONMAP1(vst4q_v, arm_neon_vst4, 0), 3649 NEONMAP0(vsubhn_v), 3650 NEONMAP0(vtrn_v), 3651 NEONMAP0(vtrnq_v), 3652 NEONMAP0(vtst_v), 3653 NEONMAP0(vtstq_v), 3654 NEONMAP0(vuzp_v), 3655 NEONMAP0(vuzpq_v), 3656 NEONMAP0(vzip_v), 3657 NEONMAP0(vzipq_v) 3658 }; 3659 3660 static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = { 3661 NEONMAP1(vabs_v, aarch64_neon_abs, 0), 3662 NEONMAP1(vabsq_v, aarch64_neon_abs, 0), 3663 NEONMAP0(vaddhn_v), 3664 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0), 3665 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0), 3666 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0), 3667 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0), 3668 NEONMAP1(vcage_v, aarch64_neon_facge, 0), 3669 NEONMAP1(vcageq_v, aarch64_neon_facge, 0), 3670 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0), 3671 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0), 3672 NEONMAP1(vcale_v, aarch64_neon_facge, 0), 3673 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0), 3674 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0), 3675 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0), 3676 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType), 3677 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType), 3678 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3679 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3680 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3681 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3682 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0), 3683 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0), 3684 NEONMAP0(vcvt_f32_v), 3685 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3686 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3687 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3688 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3689 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3690 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3691 NEONMAP0(vcvtq_f32_v), 3692 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3693 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3694 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3695 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3696 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3697 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3698 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType), 3699 NEONMAP0(vext_v), 3700 NEONMAP0(vextq_v), 3701 NEONMAP0(vfma_v), 3702 NEONMAP0(vfmaq_v), 3703 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3704 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3705 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3706 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3707 NEONMAP0(vmovl_v), 3708 NEONMAP0(vmovn_v), 3709 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType), 3710 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType), 3711 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType), 3712 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3713 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3714 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType), 3715 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType), 3716 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType), 3717 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3718 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3719 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0), 3720 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0), 3721 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType), 3722 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType), 3723 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType), 3724 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts), 3725 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType), 3726 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType), 3727 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType), 3728 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType), 3729 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType), 3730 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3731 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3732 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts), 3733 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3734 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts), 3735 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3736 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0), 3737 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0), 3738 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3739 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3740 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType), 3741 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3742 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3743 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType), 3744 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType), 3745 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3746 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3747 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3748 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3749 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3750 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3751 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3752 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3753 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType), 3754 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType), 3755 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType), 3756 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0), 3757 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0), 3758 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0), 3759 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0), 3760 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0), 3761 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0), 3762 NEONMAP0(vshl_n_v), 3763 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3764 NEONMAP0(vshll_n_v), 3765 NEONMAP0(vshlq_n_v), 3766 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3767 NEONMAP0(vshr_n_v), 3768 NEONMAP0(vshrn_n_v), 3769 NEONMAP0(vshrq_n_v), 3770 NEONMAP0(vsubhn_v), 3771 NEONMAP0(vtst_v), 3772 NEONMAP0(vtstq_v), 3773 }; 3774 3775 static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = { 3776 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType), 3777 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType), 3778 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType), 3779 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3780 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3781 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3782 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3783 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3784 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3785 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3786 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3787 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType), 3788 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3789 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType), 3790 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3791 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3792 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3793 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3794 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3795 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3796 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3797 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3798 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3799 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3800 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3801 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3802 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3803 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3804 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3805 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3806 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3807 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3808 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3809 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3810 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3811 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3812 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3813 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3814 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3815 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3816 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3817 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3818 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3819 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3820 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3821 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3822 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3823 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3824 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0), 3825 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3826 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3827 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3828 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3829 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3830 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3831 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3832 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3833 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3834 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3835 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3836 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3837 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3838 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3839 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3840 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3841 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3842 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3843 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3844 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3845 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0), 3846 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType), 3847 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType), 3848 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3849 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3850 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3851 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3852 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3853 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3854 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3855 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3856 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3857 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3858 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3859 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType), 3860 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3861 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType), 3862 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3863 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3864 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType), 3865 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType), 3866 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3867 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3868 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType), 3869 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType), 3870 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors), 3871 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType), 3872 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors), 3873 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0), 3874 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType), 3875 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType), 3876 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3877 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3878 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3879 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3880 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType), 3881 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3882 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3883 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3884 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType), 3885 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3886 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType), 3887 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors), 3888 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType), 3889 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3890 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3891 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType), 3892 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType), 3893 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3894 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3895 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType), 3896 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType), 3897 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType), 3898 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType), 3899 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3900 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3901 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3902 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3903 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType), 3904 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3905 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3906 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3907 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3908 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3909 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3910 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType), 3911 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType), 3912 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3913 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3914 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3915 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3916 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType), 3917 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType), 3918 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType), 3919 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType), 3920 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3921 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3922 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType), 3923 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType), 3924 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType), 3925 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3926 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3927 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3928 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3929 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType), 3930 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3931 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3932 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3933 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3934 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType), 3935 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType), 3936 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3937 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3938 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType), 3939 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType), 3940 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType), 3941 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType), 3942 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType), 3943 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType), 3944 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType), 3945 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType), 3946 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType), 3947 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType), 3948 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType), 3949 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType), 3950 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0), 3951 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0), 3952 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0), 3953 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0), 3954 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType), 3955 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType), 3956 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType), 3957 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType), 3958 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3959 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType), 3960 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3961 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType), 3962 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType), 3963 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType), 3964 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3965 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType), 3966 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3967 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType), 3968 }; 3969 3970 #undef NEONMAP0 3971 #undef NEONMAP1 3972 #undef NEONMAP2 3973 3974 static bool NEONSIMDIntrinsicsProvenSorted = false; 3975 3976 static bool AArch64SIMDIntrinsicsProvenSorted = false; 3977 static bool AArch64SISDIntrinsicsProvenSorted = false; 3978 3979 3980 static const NeonIntrinsicInfo * 3981 findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap, 3982 unsigned BuiltinID, bool &MapProvenSorted) { 3983 3984 #ifndef NDEBUG 3985 if (!MapProvenSorted) { 3986 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap))); 3987 MapProvenSorted = true; 3988 } 3989 #endif 3990 3991 const NeonIntrinsicInfo *Builtin = 3992 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID); 3993 3994 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) 3995 return Builtin; 3996 3997 return nullptr; 3998 } 3999 4000 Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 4001 unsigned Modifier, 4002 llvm::Type *ArgType, 4003 const CallExpr *E) { 4004 int VectorSize = 0; 4005 if (Modifier & Use64BitVectors) 4006 VectorSize = 64; 4007 else if (Modifier & Use128BitVectors) 4008 VectorSize = 128; 4009 4010 // Return type. 4011 SmallVector<llvm::Type *, 3> Tys; 4012 if (Modifier & AddRetType) { 4013 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 4014 if (Modifier & VectorizeRetType) 4015 Ty = llvm::VectorType::get( 4016 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1); 4017 4018 Tys.push_back(Ty); 4019 } 4020 4021 // Arguments. 4022 if (Modifier & VectorizeArgTypes) { 4023 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1; 4024 ArgType = llvm::VectorType::get(ArgType, Elts); 4025 } 4026 4027 if (Modifier & (Add1ArgType | Add2ArgTypes)) 4028 Tys.push_back(ArgType); 4029 4030 if (Modifier & Add2ArgTypes) 4031 Tys.push_back(ArgType); 4032 4033 if (Modifier & InventFloatType) 4034 Tys.push_back(FloatTy); 4035 4036 return CGM.getIntrinsic(IntrinsicID, Tys); 4037 } 4038 4039 static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF, 4040 const NeonIntrinsicInfo &SISDInfo, 4041 SmallVectorImpl<Value *> &Ops, 4042 const CallExpr *E) { 4043 unsigned BuiltinID = SISDInfo.BuiltinID; 4044 unsigned int Int = SISDInfo.LLVMIntrinsic; 4045 unsigned Modifier = SISDInfo.TypeModifier; 4046 const char *s = SISDInfo.NameHint; 4047 4048 switch (BuiltinID) { 4049 case NEON::BI__builtin_neon_vcled_s64: 4050 case NEON::BI__builtin_neon_vcled_u64: 4051 case NEON::BI__builtin_neon_vcles_f32: 4052 case NEON::BI__builtin_neon_vcled_f64: 4053 case NEON::BI__builtin_neon_vcltd_s64: 4054 case NEON::BI__builtin_neon_vcltd_u64: 4055 case NEON::BI__builtin_neon_vclts_f32: 4056 case NEON::BI__builtin_neon_vcltd_f64: 4057 case NEON::BI__builtin_neon_vcales_f32: 4058 case NEON::BI__builtin_neon_vcaled_f64: 4059 case NEON::BI__builtin_neon_vcalts_f32: 4060 case NEON::BI__builtin_neon_vcaltd_f64: 4061 // Only one direction of comparisons actually exist, cmle is actually a cmge 4062 // with swapped operands. The table gives us the right intrinsic but we 4063 // still need to do the swap. 4064 std::swap(Ops[0], Ops[1]); 4065 break; 4066 } 4067 4068 assert(Int && "Generic code assumes a valid intrinsic"); 4069 4070 // Determine the type(s) of this overloaded AArch64 intrinsic. 4071 const Expr *Arg = E->getArg(0); 4072 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType()); 4073 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E); 4074 4075 int j = 0; 4076 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0); 4077 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 4078 ai != ae; ++ai, ++j) { 4079 llvm::Type *ArgTy = ai->getType(); 4080 if (Ops[j]->getType()->getPrimitiveSizeInBits() == 4081 ArgTy->getPrimitiveSizeInBits()) 4082 continue; 4083 4084 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy()); 4085 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate 4086 // it before inserting. 4087 Ops[j] = 4088 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType()); 4089 Ops[j] = 4090 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0); 4091 } 4092 4093 Value *Result = CGF.EmitNeonCall(F, Ops, s); 4094 llvm::Type *ResultType = CGF.ConvertType(E->getType()); 4095 if (ResultType->getPrimitiveSizeInBits() < 4096 Result->getType()->getPrimitiveSizeInBits()) 4097 return CGF.Builder.CreateExtractElement(Result, C0); 4098 4099 return CGF.Builder.CreateBitCast(Result, ResultType, s); 4100 } 4101 4102 Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( 4103 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, 4104 const char *NameHint, unsigned Modifier, const CallExpr *E, 4105 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) { 4106 // Get the last argument, which specifies the vector type. 4107 llvm::APSInt NeonTypeConst; 4108 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 4109 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext())) 4110 return nullptr; 4111 4112 // Determine the type of this overloaded NEON intrinsic. 4113 NeonTypeFlags Type(NeonTypeConst.getZExtValue()); 4114 bool Usgn = Type.isUnsigned(); 4115 bool Quad = Type.isQuad(); 4116 4117 llvm::VectorType *VTy = GetNeonType(this, Type); 4118 llvm::Type *Ty = VTy; 4119 if (!Ty) 4120 return nullptr; 4121 4122 auto getAlignmentValue32 = [&](Address addr) -> Value* { 4123 return Builder.getInt32(addr.getAlignment().getQuantity()); 4124 }; 4125 4126 unsigned Int = LLVMIntrinsic; 4127 if ((Modifier & UnsignedAlts) && !Usgn) 4128 Int = AltLLVMIntrinsic; 4129 4130 switch (BuiltinID) { 4131 default: break; 4132 case NEON::BI__builtin_neon_vabs_v: 4133 case NEON::BI__builtin_neon_vabsq_v: 4134 if (VTy->getElementType()->isFloatingPointTy()) 4135 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); 4136 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs"); 4137 case NEON::BI__builtin_neon_vaddhn_v: { 4138 llvm::VectorType *SrcTy = 4139 llvm::VectorType::getExtendedElementVectorType(VTy); 4140 4141 // %sum = add <4 x i32> %lhs, %rhs 4142 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4143 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4144 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 4145 4146 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4147 Constant *ShiftAmt = 4148 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4149 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 4150 4151 // %res = trunc <4 x i32> %high to <4 x i16> 4152 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 4153 } 4154 case NEON::BI__builtin_neon_vcale_v: 4155 case NEON::BI__builtin_neon_vcaleq_v: 4156 case NEON::BI__builtin_neon_vcalt_v: 4157 case NEON::BI__builtin_neon_vcaltq_v: 4158 std::swap(Ops[0], Ops[1]); 4159 LLVM_FALLTHROUGH; 4160 case NEON::BI__builtin_neon_vcage_v: 4161 case NEON::BI__builtin_neon_vcageq_v: 4162 case NEON::BI__builtin_neon_vcagt_v: 4163 case NEON::BI__builtin_neon_vcagtq_v: { 4164 llvm::Type *VecFlt = llvm::VectorType::get( 4165 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, 4166 VTy->getNumElements()); 4167 llvm::Type *Tys[] = { VTy, VecFlt }; 4168 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4169 return EmitNeonCall(F, Ops, NameHint); 4170 } 4171 case NEON::BI__builtin_neon_vclz_v: 4172 case NEON::BI__builtin_neon_vclzq_v: 4173 // We generate target-independent intrinsic, which needs a second argument 4174 // for whether or not clz of zero is undefined; on ARM it isn't. 4175 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 4176 break; 4177 case NEON::BI__builtin_neon_vcvt_f32_v: 4178 case NEON::BI__builtin_neon_vcvtq_f32_v: 4179 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4180 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); 4181 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 4182 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 4183 case NEON::BI__builtin_neon_vcvt_n_f32_v: 4184 case NEON::BI__builtin_neon_vcvt_n_f64_v: 4185 case NEON::BI__builtin_neon_vcvtq_n_f32_v: 4186 case NEON::BI__builtin_neon_vcvtq_n_f64_v: { 4187 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty }; 4188 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic; 4189 Function *F = CGM.getIntrinsic(Int, Tys); 4190 return EmitNeonCall(F, Ops, "vcvt_n"); 4191 } 4192 case NEON::BI__builtin_neon_vcvt_n_s32_v: 4193 case NEON::BI__builtin_neon_vcvt_n_u32_v: 4194 case NEON::BI__builtin_neon_vcvt_n_s64_v: 4195 case NEON::BI__builtin_neon_vcvt_n_u64_v: 4196 case NEON::BI__builtin_neon_vcvtq_n_s32_v: 4197 case NEON::BI__builtin_neon_vcvtq_n_u32_v: 4198 case NEON::BI__builtin_neon_vcvtq_n_s64_v: 4199 case NEON::BI__builtin_neon_vcvtq_n_u64_v: { 4200 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4201 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4202 return EmitNeonCall(F, Ops, "vcvt_n"); 4203 } 4204 case NEON::BI__builtin_neon_vcvt_s32_v: 4205 case NEON::BI__builtin_neon_vcvt_u32_v: 4206 case NEON::BI__builtin_neon_vcvt_s64_v: 4207 case NEON::BI__builtin_neon_vcvt_u64_v: 4208 case NEON::BI__builtin_neon_vcvtq_s32_v: 4209 case NEON::BI__builtin_neon_vcvtq_u32_v: 4210 case NEON::BI__builtin_neon_vcvtq_s64_v: 4211 case NEON::BI__builtin_neon_vcvtq_u64_v: { 4212 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 4213 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 4214 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 4215 } 4216 case NEON::BI__builtin_neon_vcvta_s32_v: 4217 case NEON::BI__builtin_neon_vcvta_s64_v: 4218 case NEON::BI__builtin_neon_vcvta_u32_v: 4219 case NEON::BI__builtin_neon_vcvta_u64_v: 4220 case NEON::BI__builtin_neon_vcvtaq_s32_v: 4221 case NEON::BI__builtin_neon_vcvtaq_s64_v: 4222 case NEON::BI__builtin_neon_vcvtaq_u32_v: 4223 case NEON::BI__builtin_neon_vcvtaq_u64_v: 4224 case NEON::BI__builtin_neon_vcvtn_s32_v: 4225 case NEON::BI__builtin_neon_vcvtn_s64_v: 4226 case NEON::BI__builtin_neon_vcvtn_u32_v: 4227 case NEON::BI__builtin_neon_vcvtn_u64_v: 4228 case NEON::BI__builtin_neon_vcvtnq_s32_v: 4229 case NEON::BI__builtin_neon_vcvtnq_s64_v: 4230 case NEON::BI__builtin_neon_vcvtnq_u32_v: 4231 case NEON::BI__builtin_neon_vcvtnq_u64_v: 4232 case NEON::BI__builtin_neon_vcvtp_s32_v: 4233 case NEON::BI__builtin_neon_vcvtp_s64_v: 4234 case NEON::BI__builtin_neon_vcvtp_u32_v: 4235 case NEON::BI__builtin_neon_vcvtp_u64_v: 4236 case NEON::BI__builtin_neon_vcvtpq_s32_v: 4237 case NEON::BI__builtin_neon_vcvtpq_s64_v: 4238 case NEON::BI__builtin_neon_vcvtpq_u32_v: 4239 case NEON::BI__builtin_neon_vcvtpq_u64_v: 4240 case NEON::BI__builtin_neon_vcvtm_s32_v: 4241 case NEON::BI__builtin_neon_vcvtm_s64_v: 4242 case NEON::BI__builtin_neon_vcvtm_u32_v: 4243 case NEON::BI__builtin_neon_vcvtm_u64_v: 4244 case NEON::BI__builtin_neon_vcvtmq_s32_v: 4245 case NEON::BI__builtin_neon_vcvtmq_s64_v: 4246 case NEON::BI__builtin_neon_vcvtmq_u32_v: 4247 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 4248 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4249 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint); 4250 } 4251 case NEON::BI__builtin_neon_vext_v: 4252 case NEON::BI__builtin_neon_vextq_v: { 4253 int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 4254 SmallVector<uint32_t, 16> Indices; 4255 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4256 Indices.push_back(i+CV); 4257 4258 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4259 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4260 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext"); 4261 } 4262 case NEON::BI__builtin_neon_vfma_v: 4263 case NEON::BI__builtin_neon_vfmaq_v: { 4264 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 4265 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4266 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4267 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4268 4269 // NEON intrinsic puts accumulator first, unlike the LLVM fma. 4270 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 4271 } 4272 case NEON::BI__builtin_neon_vld1_v: 4273 case NEON::BI__builtin_neon_vld1q_v: { 4274 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4275 Ops.push_back(getAlignmentValue32(PtrOp0)); 4276 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1"); 4277 } 4278 case NEON::BI__builtin_neon_vld2_v: 4279 case NEON::BI__builtin_neon_vld2q_v: 4280 case NEON::BI__builtin_neon_vld3_v: 4281 case NEON::BI__builtin_neon_vld3q_v: 4282 case NEON::BI__builtin_neon_vld4_v: 4283 case NEON::BI__builtin_neon_vld4q_v: { 4284 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4285 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4286 Value *Align = getAlignmentValue32(PtrOp1); 4287 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint); 4288 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4289 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4290 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4291 } 4292 case NEON::BI__builtin_neon_vld1_dup_v: 4293 case NEON::BI__builtin_neon_vld1q_dup_v: { 4294 Value *V = UndefValue::get(Ty); 4295 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 4296 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty); 4297 LoadInst *Ld = Builder.CreateLoad(PtrOp0); 4298 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 4299 Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 4300 return EmitNeonSplat(Ops[0], CI); 4301 } 4302 case NEON::BI__builtin_neon_vld2_lane_v: 4303 case NEON::BI__builtin_neon_vld2q_lane_v: 4304 case NEON::BI__builtin_neon_vld3_lane_v: 4305 case NEON::BI__builtin_neon_vld3q_lane_v: 4306 case NEON::BI__builtin_neon_vld4_lane_v: 4307 case NEON::BI__builtin_neon_vld4q_lane_v: { 4308 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4309 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4310 for (unsigned I = 2; I < Ops.size() - 1; ++I) 4311 Ops[I] = Builder.CreateBitCast(Ops[I], Ty); 4312 Ops.push_back(getAlignmentValue32(PtrOp1)); 4313 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint); 4314 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4315 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4316 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4317 } 4318 case NEON::BI__builtin_neon_vmovl_v: { 4319 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 4320 Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 4321 if (Usgn) 4322 return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 4323 return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 4324 } 4325 case NEON::BI__builtin_neon_vmovn_v: { 4326 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4327 Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 4328 return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 4329 } 4330 case NEON::BI__builtin_neon_vmull_v: 4331 // FIXME: the integer vmull operations could be emitted in terms of pure 4332 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 4333 // hoisting the exts outside loops. Until global ISel comes along that can 4334 // see through such movement this leads to bad CodeGen. So we need an 4335 // intrinsic for now. 4336 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 4337 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 4338 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 4339 case NEON::BI__builtin_neon_vpadal_v: 4340 case NEON::BI__builtin_neon_vpadalq_v: { 4341 // The source operand type has twice as many elements of half the size. 4342 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4343 llvm::Type *EltTy = 4344 llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4345 llvm::Type *NarrowTy = 4346 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4347 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4348 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); 4349 } 4350 case NEON::BI__builtin_neon_vpaddl_v: 4351 case NEON::BI__builtin_neon_vpaddlq_v: { 4352 // The source operand type has twice as many elements of half the size. 4353 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4354 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4355 llvm::Type *NarrowTy = 4356 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4357 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4358 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 4359 } 4360 case NEON::BI__builtin_neon_vqdmlal_v: 4361 case NEON::BI__builtin_neon_vqdmlsl_v: { 4362 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 4363 Ops[1] = 4364 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal"); 4365 Ops.resize(2); 4366 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint); 4367 } 4368 case NEON::BI__builtin_neon_vqshl_n_v: 4369 case NEON::BI__builtin_neon_vqshlq_n_v: 4370 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 4371 1, false); 4372 case NEON::BI__builtin_neon_vqshlu_n_v: 4373 case NEON::BI__builtin_neon_vqshluq_n_v: 4374 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n", 4375 1, false); 4376 case NEON::BI__builtin_neon_vrecpe_v: 4377 case NEON::BI__builtin_neon_vrecpeq_v: 4378 case NEON::BI__builtin_neon_vrsqrte_v: 4379 case NEON::BI__builtin_neon_vrsqrteq_v: 4380 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic; 4381 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint); 4382 4383 case NEON::BI__builtin_neon_vrshr_n_v: 4384 case NEON::BI__builtin_neon_vrshrq_n_v: 4385 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 4386 1, true); 4387 case NEON::BI__builtin_neon_vshl_n_v: 4388 case NEON::BI__builtin_neon_vshlq_n_v: 4389 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 4390 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 4391 "vshl_n"); 4392 case NEON::BI__builtin_neon_vshll_n_v: { 4393 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 4394 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4395 if (Usgn) 4396 Ops[0] = Builder.CreateZExt(Ops[0], VTy); 4397 else 4398 Ops[0] = Builder.CreateSExt(Ops[0], VTy); 4399 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 4400 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 4401 } 4402 case NEON::BI__builtin_neon_vshrn_n_v: { 4403 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4404 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4405 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 4406 if (Usgn) 4407 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 4408 else 4409 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 4410 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 4411 } 4412 case NEON::BI__builtin_neon_vshr_n_v: 4413 case NEON::BI__builtin_neon_vshrq_n_v: 4414 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n"); 4415 case NEON::BI__builtin_neon_vst1_v: 4416 case NEON::BI__builtin_neon_vst1q_v: 4417 case NEON::BI__builtin_neon_vst2_v: 4418 case NEON::BI__builtin_neon_vst2q_v: 4419 case NEON::BI__builtin_neon_vst3_v: 4420 case NEON::BI__builtin_neon_vst3q_v: 4421 case NEON::BI__builtin_neon_vst4_v: 4422 case NEON::BI__builtin_neon_vst4q_v: 4423 case NEON::BI__builtin_neon_vst2_lane_v: 4424 case NEON::BI__builtin_neon_vst2q_lane_v: 4425 case NEON::BI__builtin_neon_vst3_lane_v: 4426 case NEON::BI__builtin_neon_vst3q_lane_v: 4427 case NEON::BI__builtin_neon_vst4_lane_v: 4428 case NEON::BI__builtin_neon_vst4q_lane_v: { 4429 llvm::Type *Tys[] = {Int8PtrTy, Ty}; 4430 Ops.push_back(getAlignmentValue32(PtrOp0)); 4431 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 4432 } 4433 case NEON::BI__builtin_neon_vsubhn_v: { 4434 llvm::VectorType *SrcTy = 4435 llvm::VectorType::getExtendedElementVectorType(VTy); 4436 4437 // %sum = add <4 x i32> %lhs, %rhs 4438 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4439 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4440 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 4441 4442 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4443 Constant *ShiftAmt = 4444 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4445 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 4446 4447 // %res = trunc <4 x i32> %high to <4 x i16> 4448 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 4449 } 4450 case NEON::BI__builtin_neon_vtrn_v: 4451 case NEON::BI__builtin_neon_vtrnq_v: { 4452 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4453 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4454 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4455 Value *SV = nullptr; 4456 4457 for (unsigned vi = 0; vi != 2; ++vi) { 4458 SmallVector<uint32_t, 16> Indices; 4459 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4460 Indices.push_back(i+vi); 4461 Indices.push_back(i+e+vi); 4462 } 4463 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4464 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 4465 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4466 } 4467 return SV; 4468 } 4469 case NEON::BI__builtin_neon_vtst_v: 4470 case NEON::BI__builtin_neon_vtstq_v: { 4471 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4472 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4473 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 4474 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 4475 ConstantAggregateZero::get(Ty)); 4476 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 4477 } 4478 case NEON::BI__builtin_neon_vuzp_v: 4479 case NEON::BI__builtin_neon_vuzpq_v: { 4480 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4481 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4482 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4483 Value *SV = nullptr; 4484 4485 for (unsigned vi = 0; vi != 2; ++vi) { 4486 SmallVector<uint32_t, 16> Indices; 4487 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4488 Indices.push_back(2*i+vi); 4489 4490 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4491 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 4492 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4493 } 4494 return SV; 4495 } 4496 case NEON::BI__builtin_neon_vzip_v: 4497 case NEON::BI__builtin_neon_vzipq_v: { 4498 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4499 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4500 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4501 Value *SV = nullptr; 4502 4503 for (unsigned vi = 0; vi != 2; ++vi) { 4504 SmallVector<uint32_t, 16> Indices; 4505 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4506 Indices.push_back((i + vi*e) >> 1); 4507 Indices.push_back(((i + vi*e) >> 1)+e); 4508 } 4509 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4510 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 4511 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4512 } 4513 return SV; 4514 } 4515 } 4516 4517 assert(Int && "Expected valid intrinsic number"); 4518 4519 // Determine the type(s) of this overloaded AArch64 intrinsic. 4520 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E); 4521 4522 Value *Result = EmitNeonCall(F, Ops, NameHint); 4523 llvm::Type *ResultType = ConvertType(E->getType()); 4524 // AArch64 intrinsic one-element vector type cast to 4525 // scalar type expected by the builtin 4526 return Builder.CreateBitCast(Result, ResultType, NameHint); 4527 } 4528 4529 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( 4530 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, 4531 const CmpInst::Predicate Ip, const Twine &Name) { 4532 llvm::Type *OTy = Op->getType(); 4533 4534 // FIXME: this is utterly horrific. We should not be looking at previous 4535 // codegen context to find out what needs doing. Unfortunately TableGen 4536 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32 4537 // (etc). 4538 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op)) 4539 OTy = BI->getOperand(0)->getType(); 4540 4541 Op = Builder.CreateBitCast(Op, OTy); 4542 if (OTy->getScalarType()->isFloatingPointTy()) { 4543 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy)); 4544 } else { 4545 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy)); 4546 } 4547 return Builder.CreateSExt(Op, Ty, Name); 4548 } 4549 4550 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, 4551 Value *ExtOp, Value *IndexOp, 4552 llvm::Type *ResTy, unsigned IntID, 4553 const char *Name) { 4554 SmallVector<Value *, 2> TblOps; 4555 if (ExtOp) 4556 TblOps.push_back(ExtOp); 4557 4558 // Build a vector containing sequential number like (0, 1, 2, ..., 15) 4559 SmallVector<uint32_t, 16> Indices; 4560 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); 4561 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { 4562 Indices.push_back(2*i); 4563 Indices.push_back(2*i+1); 4564 } 4565 4566 int PairPos = 0, End = Ops.size() - 1; 4567 while (PairPos < End) { 4568 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4569 Ops[PairPos+1], Indices, 4570 Name)); 4571 PairPos += 2; 4572 } 4573 4574 // If there's an odd number of 64-bit lookup table, fill the high 64-bit 4575 // of the 128-bit lookup table with zero. 4576 if (PairPos == End) { 4577 Value *ZeroTbl = ConstantAggregateZero::get(TblTy); 4578 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4579 ZeroTbl, Indices, Name)); 4580 } 4581 4582 Function *TblF; 4583 TblOps.push_back(IndexOp); 4584 TblF = CGF.CGM.getIntrinsic(IntID, ResTy); 4585 4586 return CGF.EmitNeonCall(TblF, TblOps, Name); 4587 } 4588 4589 Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) { 4590 unsigned Value; 4591 switch (BuiltinID) { 4592 default: 4593 return nullptr; 4594 case ARM::BI__builtin_arm_nop: 4595 Value = 0; 4596 break; 4597 case ARM::BI__builtin_arm_yield: 4598 case ARM::BI__yield: 4599 Value = 1; 4600 break; 4601 case ARM::BI__builtin_arm_wfe: 4602 case ARM::BI__wfe: 4603 Value = 2; 4604 break; 4605 case ARM::BI__builtin_arm_wfi: 4606 case ARM::BI__wfi: 4607 Value = 3; 4608 break; 4609 case ARM::BI__builtin_arm_sev: 4610 case ARM::BI__sev: 4611 Value = 4; 4612 break; 4613 case ARM::BI__builtin_arm_sevl: 4614 case ARM::BI__sevl: 4615 Value = 5; 4616 break; 4617 } 4618 4619 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint), 4620 llvm::ConstantInt::get(Int32Ty, Value)); 4621 } 4622 4623 // Generates the IR for the read/write special register builtin, 4624 // ValueType is the type of the value that is to be written or read, 4625 // RegisterType is the type of the register being written to or read from. 4626 static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF, 4627 const CallExpr *E, 4628 llvm::Type *RegisterType, 4629 llvm::Type *ValueType, 4630 bool IsRead, 4631 StringRef SysReg = "") { 4632 // write and register intrinsics only support 32 and 64 bit operations. 4633 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64)) 4634 && "Unsupported size for register."); 4635 4636 CodeGen::CGBuilderTy &Builder = CGF.Builder; 4637 CodeGen::CodeGenModule &CGM = CGF.CGM; 4638 LLVMContext &Context = CGM.getLLVMContext(); 4639 4640 if (SysReg.empty()) { 4641 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts(); 4642 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString(); 4643 } 4644 4645 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) }; 4646 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops); 4647 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName); 4648 4649 llvm::Type *Types[] = { RegisterType }; 4650 4651 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32); 4652 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64)) 4653 && "Can't fit 64-bit value in 32-bit register"); 4654 4655 if (IsRead) { 4656 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types); 4657 llvm::Value *Call = Builder.CreateCall(F, Metadata); 4658 4659 if (MixedTypes) 4660 // Read into 64 bit register and then truncate result to 32 bit. 4661 return Builder.CreateTrunc(Call, ValueType); 4662 4663 if (ValueType->isPointerTy()) 4664 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*). 4665 return Builder.CreateIntToPtr(Call, ValueType); 4666 4667 return Call; 4668 } 4669 4670 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types); 4671 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1)); 4672 if (MixedTypes) { 4673 // Extend 32 bit write value to 64 bit to pass to write. 4674 ArgValue = Builder.CreateZExt(ArgValue, RegisterType); 4675 return Builder.CreateCall(F, { Metadata, ArgValue }); 4676 } 4677 4678 if (ValueType->isPointerTy()) { 4679 // Have VoidPtrTy ArgValue but want to return an i32/i64. 4680 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType); 4681 return Builder.CreateCall(F, { Metadata, ArgValue }); 4682 } 4683 4684 return Builder.CreateCall(F, { Metadata, ArgValue }); 4685 } 4686 4687 /// Return true if BuiltinID is an overloaded Neon intrinsic with an extra 4688 /// argument that specifies the vector type. 4689 static bool HasExtraNeonArgument(unsigned BuiltinID) { 4690 switch (BuiltinID) { 4691 default: break; 4692 case NEON::BI__builtin_neon_vget_lane_i8: 4693 case NEON::BI__builtin_neon_vget_lane_i16: 4694 case NEON::BI__builtin_neon_vget_lane_i32: 4695 case NEON::BI__builtin_neon_vget_lane_i64: 4696 case NEON::BI__builtin_neon_vget_lane_f32: 4697 case NEON::BI__builtin_neon_vgetq_lane_i8: 4698 case NEON::BI__builtin_neon_vgetq_lane_i16: 4699 case NEON::BI__builtin_neon_vgetq_lane_i32: 4700 case NEON::BI__builtin_neon_vgetq_lane_i64: 4701 case NEON::BI__builtin_neon_vgetq_lane_f32: 4702 case NEON::BI__builtin_neon_vset_lane_i8: 4703 case NEON::BI__builtin_neon_vset_lane_i16: 4704 case NEON::BI__builtin_neon_vset_lane_i32: 4705 case NEON::BI__builtin_neon_vset_lane_i64: 4706 case NEON::BI__builtin_neon_vset_lane_f32: 4707 case NEON::BI__builtin_neon_vsetq_lane_i8: 4708 case NEON::BI__builtin_neon_vsetq_lane_i16: 4709 case NEON::BI__builtin_neon_vsetq_lane_i32: 4710 case NEON::BI__builtin_neon_vsetq_lane_i64: 4711 case NEON::BI__builtin_neon_vsetq_lane_f32: 4712 case NEON::BI__builtin_neon_vsha1h_u32: 4713 case NEON::BI__builtin_neon_vsha1cq_u32: 4714 case NEON::BI__builtin_neon_vsha1pq_u32: 4715 case NEON::BI__builtin_neon_vsha1mq_u32: 4716 case clang::ARM::BI_MoveToCoprocessor: 4717 case clang::ARM::BI_MoveToCoprocessor2: 4718 return false; 4719 } 4720 return true; 4721 } 4722 4723 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 4724 const CallExpr *E) { 4725 if (auto Hint = GetValueForARMHint(BuiltinID)) 4726 return Hint; 4727 4728 if (BuiltinID == ARM::BI__emit) { 4729 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb; 4730 llvm::FunctionType *FTy = 4731 llvm::FunctionType::get(VoidTy, /*Variadic=*/false); 4732 4733 APSInt Value; 4734 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext())) 4735 llvm_unreachable("Sema will ensure that the parameter is constant"); 4736 4737 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue(); 4738 4739 llvm::InlineAsm *Emit = 4740 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "", 4741 /*SideEffects=*/true) 4742 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "", 4743 /*SideEffects=*/true); 4744 4745 return Builder.CreateCall(Emit); 4746 } 4747 4748 if (BuiltinID == ARM::BI__builtin_arm_dbg) { 4749 Value *Option = EmitScalarExpr(E->getArg(0)); 4750 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option); 4751 } 4752 4753 if (BuiltinID == ARM::BI__builtin_arm_prefetch) { 4754 Value *Address = EmitScalarExpr(E->getArg(0)); 4755 Value *RW = EmitScalarExpr(E->getArg(1)); 4756 Value *IsData = EmitScalarExpr(E->getArg(2)); 4757 4758 // Locality is not supported on ARM target 4759 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3); 4760 4761 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4762 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 4763 } 4764 4765 if (BuiltinID == ARM::BI__builtin_arm_rbit) { 4766 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 4767 return Builder.CreateCall( 4768 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 4769 } 4770 4771 if (BuiltinID == ARM::BI__clear_cache) { 4772 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 4773 const FunctionDecl *FD = E->getDirectCallee(); 4774 Value *Ops[2]; 4775 for (unsigned i = 0; i < 2; i++) 4776 Ops[i] = EmitScalarExpr(E->getArg(i)); 4777 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 4778 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 4779 StringRef Name = FD->getName(); 4780 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 4781 } 4782 4783 if (BuiltinID == ARM::BI__builtin_arm_mcrr || 4784 BuiltinID == ARM::BI__builtin_arm_mcrr2) { 4785 Function *F; 4786 4787 switch (BuiltinID) { 4788 default: llvm_unreachable("unexpected builtin"); 4789 case ARM::BI__builtin_arm_mcrr: 4790 F = CGM.getIntrinsic(Intrinsic::arm_mcrr); 4791 break; 4792 case ARM::BI__builtin_arm_mcrr2: 4793 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2); 4794 break; 4795 } 4796 4797 // MCRR{2} instruction has 5 operands but 4798 // the intrinsic has 4 because Rt and Rt2 4799 // are represented as a single unsigned 64 4800 // bit integer in the intrinsic definition 4801 // but internally it's represented as 2 32 4802 // bit integers. 4803 4804 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4805 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4806 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2)); 4807 Value *CRm = EmitScalarExpr(E->getArg(3)); 4808 4809 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4810 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty); 4811 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1); 4812 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty); 4813 4814 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm}); 4815 } 4816 4817 if (BuiltinID == ARM::BI__builtin_arm_mrrc || 4818 BuiltinID == ARM::BI__builtin_arm_mrrc2) { 4819 Function *F; 4820 4821 switch (BuiltinID) { 4822 default: llvm_unreachable("unexpected builtin"); 4823 case ARM::BI__builtin_arm_mrrc: 4824 F = CGM.getIntrinsic(Intrinsic::arm_mrrc); 4825 break; 4826 case ARM::BI__builtin_arm_mrrc2: 4827 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2); 4828 break; 4829 } 4830 4831 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4832 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4833 Value *CRm = EmitScalarExpr(E->getArg(2)); 4834 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm}); 4835 4836 // Returns an unsigned 64 bit integer, represented 4837 // as two 32 bit integers. 4838 4839 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1); 4840 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0); 4841 Rt = Builder.CreateZExt(Rt, Int64Ty); 4842 Rt1 = Builder.CreateZExt(Rt1, Int64Ty); 4843 4844 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32); 4845 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true); 4846 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1); 4847 4848 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType())); 4849 } 4850 4851 if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 4852 ((BuiltinID == ARM::BI__builtin_arm_ldrex || 4853 BuiltinID == ARM::BI__builtin_arm_ldaex) && 4854 getContext().getTypeSize(E->getType()) == 64) || 4855 BuiltinID == ARM::BI__ldrexd) { 4856 Function *F; 4857 4858 switch (BuiltinID) { 4859 default: llvm_unreachable("unexpected builtin"); 4860 case ARM::BI__builtin_arm_ldaex: 4861 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd); 4862 break; 4863 case ARM::BI__builtin_arm_ldrexd: 4864 case ARM::BI__builtin_arm_ldrex: 4865 case ARM::BI__ldrexd: 4866 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 4867 break; 4868 } 4869 4870 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 4871 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 4872 "ldrexd"); 4873 4874 Value *Val0 = Builder.CreateExtractValue(Val, 1); 4875 Value *Val1 = Builder.CreateExtractValue(Val, 0); 4876 Val0 = Builder.CreateZExt(Val0, Int64Ty); 4877 Val1 = Builder.CreateZExt(Val1, Int64Ty); 4878 4879 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 4880 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 4881 Val = Builder.CreateOr(Val, Val1); 4882 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 4883 } 4884 4885 if (BuiltinID == ARM::BI__builtin_arm_ldrex || 4886 BuiltinID == ARM::BI__builtin_arm_ldaex) { 4887 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 4888 4889 QualType Ty = E->getType(); 4890 llvm::Type *RealResTy = ConvertType(Ty); 4891 llvm::Type *PtrTy = llvm::IntegerType::get( 4892 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 4893 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 4894 4895 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex 4896 ? Intrinsic::arm_ldaex 4897 : Intrinsic::arm_ldrex, 4898 PtrTy); 4899 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 4900 4901 if (RealResTy->isPointerTy()) 4902 return Builder.CreateIntToPtr(Val, RealResTy); 4903 else { 4904 llvm::Type *IntResTy = llvm::IntegerType::get( 4905 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 4906 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 4907 return Builder.CreateBitCast(Val, RealResTy); 4908 } 4909 } 4910 4911 if (BuiltinID == ARM::BI__builtin_arm_strexd || 4912 ((BuiltinID == ARM::BI__builtin_arm_stlex || 4913 BuiltinID == ARM::BI__builtin_arm_strex) && 4914 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 4915 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4916 ? Intrinsic::arm_stlexd 4917 : Intrinsic::arm_strexd); 4918 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty); 4919 4920 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 4921 Value *Val = EmitScalarExpr(E->getArg(0)); 4922 Builder.CreateStore(Val, Tmp); 4923 4924 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 4925 Val = Builder.CreateLoad(LdPtr); 4926 4927 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 4928 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 4929 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 4930 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd"); 4931 } 4932 4933 if (BuiltinID == ARM::BI__builtin_arm_strex || 4934 BuiltinID == ARM::BI__builtin_arm_stlex) { 4935 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 4936 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 4937 4938 QualType Ty = E->getArg(0)->getType(); 4939 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 4940 getContext().getTypeSize(Ty)); 4941 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 4942 4943 if (StoreVal->getType()->isPointerTy()) 4944 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 4945 else { 4946 llvm::Type *IntTy = llvm::IntegerType::get( 4947 getLLVMContext(), 4948 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 4949 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 4950 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 4951 } 4952 4953 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4954 ? Intrinsic::arm_stlex 4955 : Intrinsic::arm_strex, 4956 StoreAddr->getType()); 4957 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex"); 4958 } 4959 4960 switch (BuiltinID) { 4961 case ARM::BI__iso_volatile_load8: 4962 case ARM::BI__iso_volatile_load16: 4963 case ARM::BI__iso_volatile_load32: 4964 case ARM::BI__iso_volatile_load64: { 4965 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4966 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4967 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); 4968 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4969 LoadSize.getQuantity() * 8); 4970 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4971 llvm::LoadInst *Load = 4972 Builder.CreateAlignedLoad(Ptr, LoadSize); 4973 Load->setVolatile(true); 4974 return Load; 4975 } 4976 case ARM::BI__iso_volatile_store8: 4977 case ARM::BI__iso_volatile_store16: 4978 case ARM::BI__iso_volatile_store32: 4979 case ARM::BI__iso_volatile_store64: { 4980 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4981 Value *Value = EmitScalarExpr(E->getArg(1)); 4982 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4983 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 4984 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4985 StoreSize.getQuantity() * 8); 4986 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4987 llvm::StoreInst *Store = 4988 Builder.CreateAlignedStore(Value, Ptr, 4989 StoreSize); 4990 Store->setVolatile(true); 4991 return Store; 4992 } 4993 } 4994 4995 if (BuiltinID == ARM::BI__builtin_arm_clrex) { 4996 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 4997 return Builder.CreateCall(F); 4998 } 4999 5000 // CRC32 5001 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 5002 switch (BuiltinID) { 5003 case ARM::BI__builtin_arm_crc32b: 5004 CRCIntrinsicID = Intrinsic::arm_crc32b; break; 5005 case ARM::BI__builtin_arm_crc32cb: 5006 CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 5007 case ARM::BI__builtin_arm_crc32h: 5008 CRCIntrinsicID = Intrinsic::arm_crc32h; break; 5009 case ARM::BI__builtin_arm_crc32ch: 5010 CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 5011 case ARM::BI__builtin_arm_crc32w: 5012 case ARM::BI__builtin_arm_crc32d: 5013 CRCIntrinsicID = Intrinsic::arm_crc32w; break; 5014 case ARM::BI__builtin_arm_crc32cw: 5015 case ARM::BI__builtin_arm_crc32cd: 5016 CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 5017 } 5018 5019 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 5020 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 5021 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 5022 5023 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 5024 // intrinsics, hence we need different codegen for these cases. 5025 if (BuiltinID == ARM::BI__builtin_arm_crc32d || 5026 BuiltinID == ARM::BI__builtin_arm_crc32cd) { 5027 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 5028 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 5029 Value *Arg1b = Builder.CreateLShr(Arg1, C1); 5030 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 5031 5032 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 5033 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a}); 5034 return Builder.CreateCall(F, {Res, Arg1b}); 5035 } else { 5036 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 5037 5038 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 5039 return Builder.CreateCall(F, {Arg0, Arg1}); 5040 } 5041 } 5042 5043 if (BuiltinID == ARM::BI__builtin_arm_rsr || 5044 BuiltinID == ARM::BI__builtin_arm_rsr64 || 5045 BuiltinID == ARM::BI__builtin_arm_rsrp || 5046 BuiltinID == ARM::BI__builtin_arm_wsr || 5047 BuiltinID == ARM::BI__builtin_arm_wsr64 || 5048 BuiltinID == ARM::BI__builtin_arm_wsrp) { 5049 5050 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr || 5051 BuiltinID == ARM::BI__builtin_arm_rsr64 || 5052 BuiltinID == ARM::BI__builtin_arm_rsrp; 5053 5054 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp || 5055 BuiltinID == ARM::BI__builtin_arm_wsrp; 5056 5057 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 || 5058 BuiltinID == ARM::BI__builtin_arm_wsr64; 5059 5060 llvm::Type *ValueType; 5061 llvm::Type *RegisterType; 5062 if (IsPointerBuiltin) { 5063 ValueType = VoidPtrTy; 5064 RegisterType = Int32Ty; 5065 } else if (Is64Bit) { 5066 ValueType = RegisterType = Int64Ty; 5067 } else { 5068 ValueType = RegisterType = Int32Ty; 5069 } 5070 5071 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 5072 } 5073 5074 // Find out if any arguments are required to be integer constant 5075 // expressions. 5076 unsigned ICEArguments = 0; 5077 ASTContext::GetBuiltinTypeError Error; 5078 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 5079 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 5080 5081 auto getAlignmentValue32 = [&](Address addr) -> Value* { 5082 return Builder.getInt32(addr.getAlignment().getQuantity()); 5083 }; 5084 5085 Address PtrOp0 = Address::invalid(); 5086 Address PtrOp1 = Address::invalid(); 5087 SmallVector<Value*, 4> Ops; 5088 bool HasExtraArg = HasExtraNeonArgument(BuiltinID); 5089 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0); 5090 for (unsigned i = 0, e = NumArgs; i != e; i++) { 5091 if (i == 0) { 5092 switch (BuiltinID) { 5093 case NEON::BI__builtin_neon_vld1_v: 5094 case NEON::BI__builtin_neon_vld1q_v: 5095 case NEON::BI__builtin_neon_vld1q_lane_v: 5096 case NEON::BI__builtin_neon_vld1_lane_v: 5097 case NEON::BI__builtin_neon_vld1_dup_v: 5098 case NEON::BI__builtin_neon_vld1q_dup_v: 5099 case NEON::BI__builtin_neon_vst1_v: 5100 case NEON::BI__builtin_neon_vst1q_v: 5101 case NEON::BI__builtin_neon_vst1q_lane_v: 5102 case NEON::BI__builtin_neon_vst1_lane_v: 5103 case NEON::BI__builtin_neon_vst2_v: 5104 case NEON::BI__builtin_neon_vst2q_v: 5105 case NEON::BI__builtin_neon_vst2_lane_v: 5106 case NEON::BI__builtin_neon_vst2q_lane_v: 5107 case NEON::BI__builtin_neon_vst3_v: 5108 case NEON::BI__builtin_neon_vst3q_v: 5109 case NEON::BI__builtin_neon_vst3_lane_v: 5110 case NEON::BI__builtin_neon_vst3q_lane_v: 5111 case NEON::BI__builtin_neon_vst4_v: 5112 case NEON::BI__builtin_neon_vst4q_v: 5113 case NEON::BI__builtin_neon_vst4_lane_v: 5114 case NEON::BI__builtin_neon_vst4q_lane_v: 5115 // Get the alignment for the argument in addition to the value; 5116 // we'll use it later. 5117 PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); 5118 Ops.push_back(PtrOp0.getPointer()); 5119 continue; 5120 } 5121 } 5122 if (i == 1) { 5123 switch (BuiltinID) { 5124 case NEON::BI__builtin_neon_vld2_v: 5125 case NEON::BI__builtin_neon_vld2q_v: 5126 case NEON::BI__builtin_neon_vld3_v: 5127 case NEON::BI__builtin_neon_vld3q_v: 5128 case NEON::BI__builtin_neon_vld4_v: 5129 case NEON::BI__builtin_neon_vld4q_v: 5130 case NEON::BI__builtin_neon_vld2_lane_v: 5131 case NEON::BI__builtin_neon_vld2q_lane_v: 5132 case NEON::BI__builtin_neon_vld3_lane_v: 5133 case NEON::BI__builtin_neon_vld3q_lane_v: 5134 case NEON::BI__builtin_neon_vld4_lane_v: 5135 case NEON::BI__builtin_neon_vld4q_lane_v: 5136 case NEON::BI__builtin_neon_vld2_dup_v: 5137 case NEON::BI__builtin_neon_vld3_dup_v: 5138 case NEON::BI__builtin_neon_vld4_dup_v: 5139 // Get the alignment for the argument in addition to the value; 5140 // we'll use it later. 5141 PtrOp1 = EmitPointerWithAlignment(E->getArg(1)); 5142 Ops.push_back(PtrOp1.getPointer()); 5143 continue; 5144 } 5145 } 5146 5147 if ((ICEArguments & (1 << i)) == 0) { 5148 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5149 } else { 5150 // If this is required to be a constant, constant fold it so that we know 5151 // that the generated intrinsic gets a ConstantInt. 5152 llvm::APSInt Result; 5153 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5154 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 5155 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5156 } 5157 } 5158 5159 switch (BuiltinID) { 5160 default: break; 5161 5162 case NEON::BI__builtin_neon_vget_lane_i8: 5163 case NEON::BI__builtin_neon_vget_lane_i16: 5164 case NEON::BI__builtin_neon_vget_lane_i32: 5165 case NEON::BI__builtin_neon_vget_lane_i64: 5166 case NEON::BI__builtin_neon_vget_lane_f32: 5167 case NEON::BI__builtin_neon_vgetq_lane_i8: 5168 case NEON::BI__builtin_neon_vgetq_lane_i16: 5169 case NEON::BI__builtin_neon_vgetq_lane_i32: 5170 case NEON::BI__builtin_neon_vgetq_lane_i64: 5171 case NEON::BI__builtin_neon_vgetq_lane_f32: 5172 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); 5173 5174 case NEON::BI__builtin_neon_vset_lane_i8: 5175 case NEON::BI__builtin_neon_vset_lane_i16: 5176 case NEON::BI__builtin_neon_vset_lane_i32: 5177 case NEON::BI__builtin_neon_vset_lane_i64: 5178 case NEON::BI__builtin_neon_vset_lane_f32: 5179 case NEON::BI__builtin_neon_vsetq_lane_i8: 5180 case NEON::BI__builtin_neon_vsetq_lane_i16: 5181 case NEON::BI__builtin_neon_vsetq_lane_i32: 5182 case NEON::BI__builtin_neon_vsetq_lane_i64: 5183 case NEON::BI__builtin_neon_vsetq_lane_f32: 5184 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 5185 5186 case NEON::BI__builtin_neon_vsha1h_u32: 5187 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, 5188 "vsha1h"); 5189 case NEON::BI__builtin_neon_vsha1cq_u32: 5190 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, 5191 "vsha1h"); 5192 case NEON::BI__builtin_neon_vsha1pq_u32: 5193 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, 5194 "vsha1h"); 5195 case NEON::BI__builtin_neon_vsha1mq_u32: 5196 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, 5197 "vsha1h"); 5198 5199 // The ARM _MoveToCoprocessor builtins put the input register value as 5200 // the first argument, but the LLVM intrinsic expects it as the third one. 5201 case ARM::BI_MoveToCoprocessor: 5202 case ARM::BI_MoveToCoprocessor2: { 5203 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ? 5204 Intrinsic::arm_mcr : Intrinsic::arm_mcr2); 5205 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], 5206 Ops[3], Ops[4], Ops[5]}); 5207 } 5208 case ARM::BI_BitScanForward: 5209 case ARM::BI_BitScanForward64: 5210 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 5211 case ARM::BI_BitScanReverse: 5212 case ARM::BI_BitScanReverse64: 5213 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 5214 5215 case ARM::BI_InterlockedAnd64: 5216 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 5217 case ARM::BI_InterlockedExchange64: 5218 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 5219 case ARM::BI_InterlockedExchangeAdd64: 5220 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 5221 case ARM::BI_InterlockedExchangeSub64: 5222 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 5223 case ARM::BI_InterlockedOr64: 5224 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 5225 case ARM::BI_InterlockedXor64: 5226 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 5227 case ARM::BI_InterlockedDecrement64: 5228 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 5229 case ARM::BI_InterlockedIncrement64: 5230 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 5231 } 5232 5233 // Get the last argument, which specifies the vector type. 5234 assert(HasExtraArg); 5235 llvm::APSInt Result; 5236 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5237 if (!Arg->isIntegerConstantExpr(Result, getContext())) 5238 return nullptr; 5239 5240 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 5241 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 5242 // Determine the overloaded type of this builtin. 5243 llvm::Type *Ty; 5244 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 5245 Ty = FloatTy; 5246 else 5247 Ty = DoubleTy; 5248 5249 // Determine whether this is an unsigned conversion or not. 5250 bool usgn = Result.getZExtValue() == 1; 5251 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 5252 5253 // Call the appropriate intrinsic. 5254 Function *F = CGM.getIntrinsic(Int, Ty); 5255 return Builder.CreateCall(F, Ops, "vcvtr"); 5256 } 5257 5258 // Determine the type of this overloaded NEON intrinsic. 5259 NeonTypeFlags Type(Result.getZExtValue()); 5260 bool usgn = Type.isUnsigned(); 5261 bool rightShift = false; 5262 5263 llvm::VectorType *VTy = GetNeonType(this, Type); 5264 llvm::Type *Ty = VTy; 5265 if (!Ty) 5266 return nullptr; 5267 5268 // Many NEON builtins have identical semantics and uses in ARM and 5269 // AArch64. Emit these in a single function. 5270 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap); 5271 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5272 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); 5273 if (Builtin) 5274 return EmitCommonNeonBuiltinExpr( 5275 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 5276 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1); 5277 5278 unsigned Int; 5279 switch (BuiltinID) { 5280 default: return nullptr; 5281 case NEON::BI__builtin_neon_vld1q_lane_v: 5282 // Handle 64-bit integer elements as a special case. Use shuffles of 5283 // one-element vectors to avoid poor code for i64 in the backend. 5284 if (VTy->getElementType()->isIntegerTy(64)) { 5285 // Extract the other lane. 5286 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5287 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 5288 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 5289 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5290 // Load the value as a one-element vector. 5291 Ty = llvm::VectorType::get(VTy->getElementType(), 1); 5292 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5293 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys); 5294 Value *Align = getAlignmentValue32(PtrOp0); 5295 Value *Ld = Builder.CreateCall(F, {Ops[0], Align}); 5296 // Combine them. 5297 uint32_t Indices[] = {1 - Lane, Lane}; 5298 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices); 5299 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 5300 } 5301 // fall through 5302 case NEON::BI__builtin_neon_vld1_lane_v: { 5303 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5304 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType()); 5305 Value *Ld = Builder.CreateLoad(PtrOp0); 5306 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 5307 } 5308 case NEON::BI__builtin_neon_vld2_dup_v: 5309 case NEON::BI__builtin_neon_vld3_dup_v: 5310 case NEON::BI__builtin_neon_vld4_dup_v: { 5311 // Handle 64-bit elements as a special-case. There is no "dup" needed. 5312 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 5313 switch (BuiltinID) { 5314 case NEON::BI__builtin_neon_vld2_dup_v: 5315 Int = Intrinsic::arm_neon_vld2; 5316 break; 5317 case NEON::BI__builtin_neon_vld3_dup_v: 5318 Int = Intrinsic::arm_neon_vld3; 5319 break; 5320 case NEON::BI__builtin_neon_vld4_dup_v: 5321 Int = Intrinsic::arm_neon_vld4; 5322 break; 5323 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5324 } 5325 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5326 Function *F = CGM.getIntrinsic(Int, Tys); 5327 llvm::Value *Align = getAlignmentValue32(PtrOp1); 5328 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup"); 5329 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5330 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5331 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5332 } 5333 switch (BuiltinID) { 5334 case NEON::BI__builtin_neon_vld2_dup_v: 5335 Int = Intrinsic::arm_neon_vld2lane; 5336 break; 5337 case NEON::BI__builtin_neon_vld3_dup_v: 5338 Int = Intrinsic::arm_neon_vld3lane; 5339 break; 5340 case NEON::BI__builtin_neon_vld4_dup_v: 5341 Int = Intrinsic::arm_neon_vld4lane; 5342 break; 5343 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5344 } 5345 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5346 Function *F = CGM.getIntrinsic(Int, Tys); 5347 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 5348 5349 SmallVector<Value*, 6> Args; 5350 Args.push_back(Ops[1]); 5351 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 5352 5353 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 5354 Args.push_back(CI); 5355 Args.push_back(getAlignmentValue32(PtrOp1)); 5356 5357 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 5358 // splat lane 0 to all elts in each vector of the result. 5359 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 5360 Value *Val = Builder.CreateExtractValue(Ops[1], i); 5361 Value *Elt = Builder.CreateBitCast(Val, Ty); 5362 Elt = EmitNeonSplat(Elt, CI); 5363 Elt = Builder.CreateBitCast(Elt, Val->getType()); 5364 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 5365 } 5366 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5367 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5368 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5369 } 5370 case NEON::BI__builtin_neon_vqrshrn_n_v: 5371 Int = 5372 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 5373 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 5374 1, true); 5375 case NEON::BI__builtin_neon_vqrshrun_n_v: 5376 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 5377 Ops, "vqrshrun_n", 1, true); 5378 case NEON::BI__builtin_neon_vqshrn_n_v: 5379 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 5380 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 5381 1, true); 5382 case NEON::BI__builtin_neon_vqshrun_n_v: 5383 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 5384 Ops, "vqshrun_n", 1, true); 5385 case NEON::BI__builtin_neon_vrecpe_v: 5386 case NEON::BI__builtin_neon_vrecpeq_v: 5387 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 5388 Ops, "vrecpe"); 5389 case NEON::BI__builtin_neon_vrshrn_n_v: 5390 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 5391 Ops, "vrshrn_n", 1, true); 5392 case NEON::BI__builtin_neon_vrsra_n_v: 5393 case NEON::BI__builtin_neon_vrsraq_n_v: 5394 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5395 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5396 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 5397 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 5398 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]}); 5399 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 5400 case NEON::BI__builtin_neon_vsri_n_v: 5401 case NEON::BI__builtin_neon_vsriq_n_v: 5402 rightShift = true; 5403 LLVM_FALLTHROUGH; 5404 case NEON::BI__builtin_neon_vsli_n_v: 5405 case NEON::BI__builtin_neon_vsliq_n_v: 5406 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 5407 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 5408 Ops, "vsli_n"); 5409 case NEON::BI__builtin_neon_vsra_n_v: 5410 case NEON::BI__builtin_neon_vsraq_n_v: 5411 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5412 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 5413 return Builder.CreateAdd(Ops[0], Ops[1]); 5414 case NEON::BI__builtin_neon_vst1q_lane_v: 5415 // Handle 64-bit integer elements as a special case. Use a shuffle to get 5416 // a one-element vector and avoid poor code for i64 in the backend. 5417 if (VTy->getElementType()->isIntegerTy(64)) { 5418 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5419 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 5420 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5421 Ops[2] = getAlignmentValue32(PtrOp0); 5422 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()}; 5423 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 5424 Tys), Ops); 5425 } 5426 // fall through 5427 case NEON::BI__builtin_neon_vst1_lane_v: { 5428 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5429 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 5430 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5431 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty)); 5432 return St; 5433 } 5434 case NEON::BI__builtin_neon_vtbl1_v: 5435 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 5436 Ops, "vtbl1"); 5437 case NEON::BI__builtin_neon_vtbl2_v: 5438 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 5439 Ops, "vtbl2"); 5440 case NEON::BI__builtin_neon_vtbl3_v: 5441 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 5442 Ops, "vtbl3"); 5443 case NEON::BI__builtin_neon_vtbl4_v: 5444 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 5445 Ops, "vtbl4"); 5446 case NEON::BI__builtin_neon_vtbx1_v: 5447 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 5448 Ops, "vtbx1"); 5449 case NEON::BI__builtin_neon_vtbx2_v: 5450 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 5451 Ops, "vtbx2"); 5452 case NEON::BI__builtin_neon_vtbx3_v: 5453 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 5454 Ops, "vtbx3"); 5455 case NEON::BI__builtin_neon_vtbx4_v: 5456 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 5457 Ops, "vtbx4"); 5458 } 5459 } 5460 5461 static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID, 5462 const CallExpr *E, 5463 SmallVectorImpl<Value *> &Ops) { 5464 unsigned int Int = 0; 5465 const char *s = nullptr; 5466 5467 switch (BuiltinID) { 5468 default: 5469 return nullptr; 5470 case NEON::BI__builtin_neon_vtbl1_v: 5471 case NEON::BI__builtin_neon_vqtbl1_v: 5472 case NEON::BI__builtin_neon_vqtbl1q_v: 5473 case NEON::BI__builtin_neon_vtbl2_v: 5474 case NEON::BI__builtin_neon_vqtbl2_v: 5475 case NEON::BI__builtin_neon_vqtbl2q_v: 5476 case NEON::BI__builtin_neon_vtbl3_v: 5477 case NEON::BI__builtin_neon_vqtbl3_v: 5478 case NEON::BI__builtin_neon_vqtbl3q_v: 5479 case NEON::BI__builtin_neon_vtbl4_v: 5480 case NEON::BI__builtin_neon_vqtbl4_v: 5481 case NEON::BI__builtin_neon_vqtbl4q_v: 5482 break; 5483 case NEON::BI__builtin_neon_vtbx1_v: 5484 case NEON::BI__builtin_neon_vqtbx1_v: 5485 case NEON::BI__builtin_neon_vqtbx1q_v: 5486 case NEON::BI__builtin_neon_vtbx2_v: 5487 case NEON::BI__builtin_neon_vqtbx2_v: 5488 case NEON::BI__builtin_neon_vqtbx2q_v: 5489 case NEON::BI__builtin_neon_vtbx3_v: 5490 case NEON::BI__builtin_neon_vqtbx3_v: 5491 case NEON::BI__builtin_neon_vqtbx3q_v: 5492 case NEON::BI__builtin_neon_vtbx4_v: 5493 case NEON::BI__builtin_neon_vqtbx4_v: 5494 case NEON::BI__builtin_neon_vqtbx4q_v: 5495 break; 5496 } 5497 5498 assert(E->getNumArgs() >= 3); 5499 5500 // Get the last argument, which specifies the vector type. 5501 llvm::APSInt Result; 5502 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 5503 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) 5504 return nullptr; 5505 5506 // Determine the type of this overloaded NEON intrinsic. 5507 NeonTypeFlags Type(Result.getZExtValue()); 5508 llvm::VectorType *Ty = GetNeonType(&CGF, Type); 5509 if (!Ty) 5510 return nullptr; 5511 5512 CodeGen::CGBuilderTy &Builder = CGF.Builder; 5513 5514 // AArch64 scalar builtins are not overloaded, they do not have an extra 5515 // argument that specifies the vector type, need to handle each case. 5516 switch (BuiltinID) { 5517 case NEON::BI__builtin_neon_vtbl1_v: { 5518 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr, 5519 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1, 5520 "vtbl1"); 5521 } 5522 case NEON::BI__builtin_neon_vtbl2_v: { 5523 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr, 5524 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1, 5525 "vtbl1"); 5526 } 5527 case NEON::BI__builtin_neon_vtbl3_v: { 5528 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr, 5529 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2, 5530 "vtbl2"); 5531 } 5532 case NEON::BI__builtin_neon_vtbl4_v: { 5533 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr, 5534 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2, 5535 "vtbl2"); 5536 } 5537 case NEON::BI__builtin_neon_vtbx1_v: { 5538 Value *TblRes = 5539 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2], 5540 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1"); 5541 5542 llvm::Constant *EightV = ConstantInt::get(Ty, 8); 5543 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); 5544 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5545 5546 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5547 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5548 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5549 } 5550 case NEON::BI__builtin_neon_vtbx2_v: { 5551 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0], 5552 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1, 5553 "vtbx1"); 5554 } 5555 case NEON::BI__builtin_neon_vtbx3_v: { 5556 Value *TblRes = 5557 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4], 5558 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2"); 5559 5560 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24); 5561 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], 5562 TwentyFourV); 5563 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5564 5565 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5566 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5567 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5568 } 5569 case NEON::BI__builtin_neon_vtbx4_v: { 5570 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0], 5571 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2, 5572 "vtbx2"); 5573 } 5574 case NEON::BI__builtin_neon_vqtbl1_v: 5575 case NEON::BI__builtin_neon_vqtbl1q_v: 5576 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break; 5577 case NEON::BI__builtin_neon_vqtbl2_v: 5578 case NEON::BI__builtin_neon_vqtbl2q_v: { 5579 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break; 5580 case NEON::BI__builtin_neon_vqtbl3_v: 5581 case NEON::BI__builtin_neon_vqtbl3q_v: 5582 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break; 5583 case NEON::BI__builtin_neon_vqtbl4_v: 5584 case NEON::BI__builtin_neon_vqtbl4q_v: 5585 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break; 5586 case NEON::BI__builtin_neon_vqtbx1_v: 5587 case NEON::BI__builtin_neon_vqtbx1q_v: 5588 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break; 5589 case NEON::BI__builtin_neon_vqtbx2_v: 5590 case NEON::BI__builtin_neon_vqtbx2q_v: 5591 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break; 5592 case NEON::BI__builtin_neon_vqtbx3_v: 5593 case NEON::BI__builtin_neon_vqtbx3q_v: 5594 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break; 5595 case NEON::BI__builtin_neon_vqtbx4_v: 5596 case NEON::BI__builtin_neon_vqtbx4q_v: 5597 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break; 5598 } 5599 } 5600 5601 if (!Int) 5602 return nullptr; 5603 5604 Function *F = CGF.CGM.getIntrinsic(Int, Ty); 5605 return CGF.EmitNeonCall(F, Ops, s); 5606 } 5607 5608 Value *CodeGenFunction::vectorWrapScalar16(Value *Op) { 5609 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4); 5610 Op = Builder.CreateBitCast(Op, Int16Ty); 5611 Value *V = UndefValue::get(VTy); 5612 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 5613 Op = Builder.CreateInsertElement(V, Op, CI); 5614 return Op; 5615 } 5616 5617 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 5618 const CallExpr *E) { 5619 unsigned HintID = static_cast<unsigned>(-1); 5620 switch (BuiltinID) { 5621 default: break; 5622 case AArch64::BI__builtin_arm_nop: 5623 HintID = 0; 5624 break; 5625 case AArch64::BI__builtin_arm_yield: 5626 HintID = 1; 5627 break; 5628 case AArch64::BI__builtin_arm_wfe: 5629 HintID = 2; 5630 break; 5631 case AArch64::BI__builtin_arm_wfi: 5632 HintID = 3; 5633 break; 5634 case AArch64::BI__builtin_arm_sev: 5635 HintID = 4; 5636 break; 5637 case AArch64::BI__builtin_arm_sevl: 5638 HintID = 5; 5639 break; 5640 } 5641 5642 if (HintID != static_cast<unsigned>(-1)) { 5643 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint); 5644 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); 5645 } 5646 5647 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { 5648 Value *Address = EmitScalarExpr(E->getArg(0)); 5649 Value *RW = EmitScalarExpr(E->getArg(1)); 5650 Value *CacheLevel = EmitScalarExpr(E->getArg(2)); 5651 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3)); 5652 Value *IsData = EmitScalarExpr(E->getArg(4)); 5653 5654 Value *Locality = nullptr; 5655 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) { 5656 // Temporal fetch, needs to convert cache level to locality. 5657 Locality = llvm::ConstantInt::get(Int32Ty, 5658 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3); 5659 } else { 5660 // Streaming fetch. 5661 Locality = llvm::ConstantInt::get(Int32Ty, 0); 5662 } 5663 5664 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify 5665 // PLDL3STRM or PLDL2STRM. 5666 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 5667 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 5668 } 5669 5670 if (BuiltinID == AArch64::BI__builtin_arm_rbit) { 5671 assert((getContext().getTypeSize(E->getType()) == 32) && 5672 "rbit of unusual size!"); 5673 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5674 return Builder.CreateCall( 5675 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5676 } 5677 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) { 5678 assert((getContext().getTypeSize(E->getType()) == 64) && 5679 "rbit of unusual size!"); 5680 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5681 return Builder.CreateCall( 5682 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5683 } 5684 5685 if (BuiltinID == AArch64::BI__clear_cache) { 5686 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 5687 const FunctionDecl *FD = E->getDirectCallee(); 5688 Value *Ops[2]; 5689 for (unsigned i = 0; i < 2; i++) 5690 Ops[i] = EmitScalarExpr(E->getArg(i)); 5691 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 5692 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 5693 StringRef Name = FD->getName(); 5694 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 5695 } 5696 5697 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex || 5698 BuiltinID == AArch64::BI__builtin_arm_ldaex) && 5699 getContext().getTypeSize(E->getType()) == 128) { 5700 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5701 ? Intrinsic::aarch64_ldaxp 5702 : Intrinsic::aarch64_ldxp); 5703 5704 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 5705 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 5706 "ldxp"); 5707 5708 Value *Val0 = Builder.CreateExtractValue(Val, 1); 5709 Value *Val1 = Builder.CreateExtractValue(Val, 0); 5710 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 5711 Val0 = Builder.CreateZExt(Val0, Int128Ty); 5712 Val1 = Builder.CreateZExt(Val1, Int128Ty); 5713 5714 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64); 5715 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 5716 Val = Builder.CreateOr(Val, Val1); 5717 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 5718 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex || 5719 BuiltinID == AArch64::BI__builtin_arm_ldaex) { 5720 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 5721 5722 QualType Ty = E->getType(); 5723 llvm::Type *RealResTy = ConvertType(Ty); 5724 llvm::Type *PtrTy = llvm::IntegerType::get( 5725 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 5726 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 5727 5728 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5729 ? Intrinsic::aarch64_ldaxr 5730 : Intrinsic::aarch64_ldxr, 5731 PtrTy); 5732 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr"); 5733 5734 if (RealResTy->isPointerTy()) 5735 return Builder.CreateIntToPtr(Val, RealResTy); 5736 5737 llvm::Type *IntResTy = llvm::IntegerType::get( 5738 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 5739 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 5740 return Builder.CreateBitCast(Val, RealResTy); 5741 } 5742 5743 if ((BuiltinID == AArch64::BI__builtin_arm_strex || 5744 BuiltinID == AArch64::BI__builtin_arm_stlex) && 5745 getContext().getTypeSize(E->getArg(0)->getType()) == 128) { 5746 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5747 ? Intrinsic::aarch64_stlxp 5748 : Intrinsic::aarch64_stxp); 5749 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty); 5750 5751 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 5752 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true); 5753 5754 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy)); 5755 llvm::Value *Val = Builder.CreateLoad(Tmp); 5756 5757 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 5758 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 5759 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), 5760 Int8PtrTy); 5761 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp"); 5762 } 5763 5764 if (BuiltinID == AArch64::BI__builtin_arm_strex || 5765 BuiltinID == AArch64::BI__builtin_arm_stlex) { 5766 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 5767 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 5768 5769 QualType Ty = E->getArg(0)->getType(); 5770 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 5771 getContext().getTypeSize(Ty)); 5772 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 5773 5774 if (StoreVal->getType()->isPointerTy()) 5775 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty); 5776 else { 5777 llvm::Type *IntTy = llvm::IntegerType::get( 5778 getLLVMContext(), 5779 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 5780 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 5781 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty); 5782 } 5783 5784 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5785 ? Intrinsic::aarch64_stlxr 5786 : Intrinsic::aarch64_stxr, 5787 StoreAddr->getType()); 5788 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr"); 5789 } 5790 5791 if (BuiltinID == AArch64::BI__builtin_arm_clrex) { 5792 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex); 5793 return Builder.CreateCall(F); 5794 } 5795 5796 // CRC32 5797 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 5798 switch (BuiltinID) { 5799 case AArch64::BI__builtin_arm_crc32b: 5800 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break; 5801 case AArch64::BI__builtin_arm_crc32cb: 5802 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break; 5803 case AArch64::BI__builtin_arm_crc32h: 5804 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break; 5805 case AArch64::BI__builtin_arm_crc32ch: 5806 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break; 5807 case AArch64::BI__builtin_arm_crc32w: 5808 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break; 5809 case AArch64::BI__builtin_arm_crc32cw: 5810 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break; 5811 case AArch64::BI__builtin_arm_crc32d: 5812 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break; 5813 case AArch64::BI__builtin_arm_crc32cd: 5814 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break; 5815 } 5816 5817 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 5818 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 5819 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 5820 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 5821 5822 llvm::Type *DataTy = F->getFunctionType()->getParamType(1); 5823 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy); 5824 5825 return Builder.CreateCall(F, {Arg0, Arg1}); 5826 } 5827 5828 if (BuiltinID == AArch64::BI__builtin_arm_rsr || 5829 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5830 BuiltinID == AArch64::BI__builtin_arm_rsrp || 5831 BuiltinID == AArch64::BI__builtin_arm_wsr || 5832 BuiltinID == AArch64::BI__builtin_arm_wsr64 || 5833 BuiltinID == AArch64::BI__builtin_arm_wsrp) { 5834 5835 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr || 5836 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5837 BuiltinID == AArch64::BI__builtin_arm_rsrp; 5838 5839 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp || 5840 BuiltinID == AArch64::BI__builtin_arm_wsrp; 5841 5842 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr && 5843 BuiltinID != AArch64::BI__builtin_arm_wsr; 5844 5845 llvm::Type *ValueType; 5846 llvm::Type *RegisterType = Int64Ty; 5847 if (IsPointerBuiltin) { 5848 ValueType = VoidPtrTy; 5849 } else if (Is64Bit) { 5850 ValueType = Int64Ty; 5851 } else { 5852 ValueType = Int32Ty; 5853 } 5854 5855 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 5856 } 5857 5858 // Find out if any arguments are required to be integer constant 5859 // expressions. 5860 unsigned ICEArguments = 0; 5861 ASTContext::GetBuiltinTypeError Error; 5862 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 5863 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 5864 5865 llvm::SmallVector<Value*, 4> Ops; 5866 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 5867 if ((ICEArguments & (1 << i)) == 0) { 5868 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5869 } else { 5870 // If this is required to be a constant, constant fold it so that we know 5871 // that the generated intrinsic gets a ConstantInt. 5872 llvm::APSInt Result; 5873 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5874 assert(IsConst && "Constant arg isn't actually constant?"); 5875 (void)IsConst; 5876 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5877 } 5878 } 5879 5880 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap); 5881 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5882 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted); 5883 5884 if (Builtin) { 5885 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1))); 5886 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E); 5887 assert(Result && "SISD intrinsic should have been handled"); 5888 return Result; 5889 } 5890 5891 llvm::APSInt Result; 5892 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5893 NeonTypeFlags Type(0); 5894 if (Arg->isIntegerConstantExpr(Result, getContext())) 5895 // Determine the type of this overloaded NEON intrinsic. 5896 Type = NeonTypeFlags(Result.getZExtValue()); 5897 5898 bool usgn = Type.isUnsigned(); 5899 bool quad = Type.isQuad(); 5900 5901 // Handle non-overloaded intrinsics first. 5902 switch (BuiltinID) { 5903 default: break; 5904 case NEON::BI__builtin_neon_vldrq_p128: { 5905 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128); 5906 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0); 5907 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy); 5908 return Builder.CreateAlignedLoad(Int128Ty, Ptr, 5909 CharUnits::fromQuantity(16)); 5910 } 5911 case NEON::BI__builtin_neon_vstrq_p128: { 5912 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128); 5913 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy); 5914 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr); 5915 } 5916 case NEON::BI__builtin_neon_vcvts_u32_f32: 5917 case NEON::BI__builtin_neon_vcvtd_u64_f64: 5918 usgn = true; 5919 // FALL THROUGH 5920 case NEON::BI__builtin_neon_vcvts_s32_f32: 5921 case NEON::BI__builtin_neon_vcvtd_s64_f64: { 5922 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5923 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5924 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5925 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5926 Ops[0] = Builder.CreateBitCast(Ops[0], FTy); 5927 if (usgn) 5928 return Builder.CreateFPToUI(Ops[0], InTy); 5929 return Builder.CreateFPToSI(Ops[0], InTy); 5930 } 5931 case NEON::BI__builtin_neon_vcvts_f32_u32: 5932 case NEON::BI__builtin_neon_vcvtd_f64_u64: 5933 usgn = true; 5934 // FALL THROUGH 5935 case NEON::BI__builtin_neon_vcvts_f32_s32: 5936 case NEON::BI__builtin_neon_vcvtd_f64_s64: { 5937 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5938 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5939 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5940 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5941 Ops[0] = Builder.CreateBitCast(Ops[0], InTy); 5942 if (usgn) 5943 return Builder.CreateUIToFP(Ops[0], FTy); 5944 return Builder.CreateSIToFP(Ops[0], FTy); 5945 } 5946 case NEON::BI__builtin_neon_vpaddd_s64: { 5947 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2); 5948 Value *Vec = EmitScalarExpr(E->getArg(0)); 5949 // The vector is v2f64, so make sure it's bitcast to that. 5950 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64"); 5951 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5952 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5953 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5954 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5955 // Pairwise addition of a v2f64 into a scalar f64. 5956 return Builder.CreateAdd(Op0, Op1, "vpaddd"); 5957 } 5958 case NEON::BI__builtin_neon_vpaddd_f64: { 5959 llvm::Type *Ty = 5960 llvm::VectorType::get(DoubleTy, 2); 5961 Value *Vec = EmitScalarExpr(E->getArg(0)); 5962 // The vector is v2f64, so make sure it's bitcast to that. 5963 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64"); 5964 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5965 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5966 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5967 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5968 // Pairwise addition of a v2f64 into a scalar f64. 5969 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5970 } 5971 case NEON::BI__builtin_neon_vpadds_f32: { 5972 llvm::Type *Ty = 5973 llvm::VectorType::get(FloatTy, 2); 5974 Value *Vec = EmitScalarExpr(E->getArg(0)); 5975 // The vector is v2f32, so make sure it's bitcast to that. 5976 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32"); 5977 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5978 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5979 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5980 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5981 // Pairwise addition of a v2f32 into a scalar f32. 5982 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5983 } 5984 case NEON::BI__builtin_neon_vceqzd_s64: 5985 case NEON::BI__builtin_neon_vceqzd_f64: 5986 case NEON::BI__builtin_neon_vceqzs_f32: 5987 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5988 return EmitAArch64CompareBuiltinExpr( 5989 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5990 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz"); 5991 case NEON::BI__builtin_neon_vcgezd_s64: 5992 case NEON::BI__builtin_neon_vcgezd_f64: 5993 case NEON::BI__builtin_neon_vcgezs_f32: 5994 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5995 return EmitAArch64CompareBuiltinExpr( 5996 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5997 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez"); 5998 case NEON::BI__builtin_neon_vclezd_s64: 5999 case NEON::BI__builtin_neon_vclezd_f64: 6000 case NEON::BI__builtin_neon_vclezs_f32: 6001 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6002 return EmitAArch64CompareBuiltinExpr( 6003 Ops[0], ConvertType(E->getCallReturnType(getContext())), 6004 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez"); 6005 case NEON::BI__builtin_neon_vcgtzd_s64: 6006 case NEON::BI__builtin_neon_vcgtzd_f64: 6007 case NEON::BI__builtin_neon_vcgtzs_f32: 6008 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6009 return EmitAArch64CompareBuiltinExpr( 6010 Ops[0], ConvertType(E->getCallReturnType(getContext())), 6011 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz"); 6012 case NEON::BI__builtin_neon_vcltzd_s64: 6013 case NEON::BI__builtin_neon_vcltzd_f64: 6014 case NEON::BI__builtin_neon_vcltzs_f32: 6015 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6016 return EmitAArch64CompareBuiltinExpr( 6017 Ops[0], ConvertType(E->getCallReturnType(getContext())), 6018 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz"); 6019 6020 case NEON::BI__builtin_neon_vceqzd_u64: { 6021 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6022 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6023 Ops[0] = 6024 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty)); 6025 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd"); 6026 } 6027 case NEON::BI__builtin_neon_vceqd_f64: 6028 case NEON::BI__builtin_neon_vcled_f64: 6029 case NEON::BI__builtin_neon_vcltd_f64: 6030 case NEON::BI__builtin_neon_vcged_f64: 6031 case NEON::BI__builtin_neon_vcgtd_f64: { 6032 llvm::CmpInst::Predicate P; 6033 switch (BuiltinID) { 6034 default: llvm_unreachable("missing builtin ID in switch!"); 6035 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break; 6036 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break; 6037 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break; 6038 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break; 6039 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break; 6040 } 6041 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6042 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6043 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 6044 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 6045 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd"); 6046 } 6047 case NEON::BI__builtin_neon_vceqs_f32: 6048 case NEON::BI__builtin_neon_vcles_f32: 6049 case NEON::BI__builtin_neon_vclts_f32: 6050 case NEON::BI__builtin_neon_vcges_f32: 6051 case NEON::BI__builtin_neon_vcgts_f32: { 6052 llvm::CmpInst::Predicate P; 6053 switch (BuiltinID) { 6054 default: llvm_unreachable("missing builtin ID in switch!"); 6055 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break; 6056 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break; 6057 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break; 6058 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break; 6059 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break; 6060 } 6061 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6062 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 6063 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy); 6064 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 6065 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd"); 6066 } 6067 case NEON::BI__builtin_neon_vceqd_s64: 6068 case NEON::BI__builtin_neon_vceqd_u64: 6069 case NEON::BI__builtin_neon_vcgtd_s64: 6070 case NEON::BI__builtin_neon_vcgtd_u64: 6071 case NEON::BI__builtin_neon_vcltd_s64: 6072 case NEON::BI__builtin_neon_vcltd_u64: 6073 case NEON::BI__builtin_neon_vcged_u64: 6074 case NEON::BI__builtin_neon_vcged_s64: 6075 case NEON::BI__builtin_neon_vcled_u64: 6076 case NEON::BI__builtin_neon_vcled_s64: { 6077 llvm::CmpInst::Predicate P; 6078 switch (BuiltinID) { 6079 default: llvm_unreachable("missing builtin ID in switch!"); 6080 case NEON::BI__builtin_neon_vceqd_s64: 6081 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break; 6082 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break; 6083 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break; 6084 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break; 6085 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break; 6086 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break; 6087 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break; 6088 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break; 6089 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break; 6090 } 6091 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6092 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6093 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6094 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]); 6095 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd"); 6096 } 6097 case NEON::BI__builtin_neon_vtstd_s64: 6098 case NEON::BI__builtin_neon_vtstd_u64: { 6099 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6100 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6101 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6102 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 6103 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 6104 llvm::Constant::getNullValue(Int64Ty)); 6105 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd"); 6106 } 6107 case NEON::BI__builtin_neon_vset_lane_i8: 6108 case NEON::BI__builtin_neon_vset_lane_i16: 6109 case NEON::BI__builtin_neon_vset_lane_i32: 6110 case NEON::BI__builtin_neon_vset_lane_i64: 6111 case NEON::BI__builtin_neon_vset_lane_f32: 6112 case NEON::BI__builtin_neon_vsetq_lane_i8: 6113 case NEON::BI__builtin_neon_vsetq_lane_i16: 6114 case NEON::BI__builtin_neon_vsetq_lane_i32: 6115 case NEON::BI__builtin_neon_vsetq_lane_i64: 6116 case NEON::BI__builtin_neon_vsetq_lane_f32: 6117 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6118 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6119 case NEON::BI__builtin_neon_vset_lane_f64: 6120 // The vector type needs a cast for the v1f64 variant. 6121 Ops[1] = Builder.CreateBitCast(Ops[1], 6122 llvm::VectorType::get(DoubleTy, 1)); 6123 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6124 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6125 case NEON::BI__builtin_neon_vsetq_lane_f64: 6126 // The vector type needs a cast for the v2f64 variant. 6127 Ops[1] = Builder.CreateBitCast(Ops[1], 6128 llvm::VectorType::get(DoubleTy, 2)); 6129 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6130 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6131 6132 case NEON::BI__builtin_neon_vget_lane_i8: 6133 case NEON::BI__builtin_neon_vdupb_lane_i8: 6134 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8)); 6135 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6136 "vget_lane"); 6137 case NEON::BI__builtin_neon_vgetq_lane_i8: 6138 case NEON::BI__builtin_neon_vdupb_laneq_i8: 6139 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16)); 6140 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6141 "vgetq_lane"); 6142 case NEON::BI__builtin_neon_vget_lane_i16: 6143 case NEON::BI__builtin_neon_vduph_lane_i16: 6144 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4)); 6145 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6146 "vget_lane"); 6147 case NEON::BI__builtin_neon_vgetq_lane_i16: 6148 case NEON::BI__builtin_neon_vduph_laneq_i16: 6149 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8)); 6150 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6151 "vgetq_lane"); 6152 case NEON::BI__builtin_neon_vget_lane_i32: 6153 case NEON::BI__builtin_neon_vdups_lane_i32: 6154 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2)); 6155 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6156 "vget_lane"); 6157 case NEON::BI__builtin_neon_vdups_lane_f32: 6158 Ops[0] = Builder.CreateBitCast(Ops[0], 6159 llvm::VectorType::get(FloatTy, 2)); 6160 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6161 "vdups_lane"); 6162 case NEON::BI__builtin_neon_vgetq_lane_i32: 6163 case NEON::BI__builtin_neon_vdups_laneq_i32: 6164 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 6165 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6166 "vgetq_lane"); 6167 case NEON::BI__builtin_neon_vget_lane_i64: 6168 case NEON::BI__builtin_neon_vdupd_lane_i64: 6169 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1)); 6170 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6171 "vget_lane"); 6172 case NEON::BI__builtin_neon_vdupd_lane_f64: 6173 Ops[0] = Builder.CreateBitCast(Ops[0], 6174 llvm::VectorType::get(DoubleTy, 1)); 6175 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6176 "vdupd_lane"); 6177 case NEON::BI__builtin_neon_vgetq_lane_i64: 6178 case NEON::BI__builtin_neon_vdupd_laneq_i64: 6179 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 6180 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6181 "vgetq_lane"); 6182 case NEON::BI__builtin_neon_vget_lane_f32: 6183 Ops[0] = Builder.CreateBitCast(Ops[0], 6184 llvm::VectorType::get(FloatTy, 2)); 6185 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6186 "vget_lane"); 6187 case NEON::BI__builtin_neon_vget_lane_f64: 6188 Ops[0] = Builder.CreateBitCast(Ops[0], 6189 llvm::VectorType::get(DoubleTy, 1)); 6190 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6191 "vget_lane"); 6192 case NEON::BI__builtin_neon_vgetq_lane_f32: 6193 case NEON::BI__builtin_neon_vdups_laneq_f32: 6194 Ops[0] = Builder.CreateBitCast(Ops[0], 6195 llvm::VectorType::get(FloatTy, 4)); 6196 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6197 "vgetq_lane"); 6198 case NEON::BI__builtin_neon_vgetq_lane_f64: 6199 case NEON::BI__builtin_neon_vdupd_laneq_f64: 6200 Ops[0] = Builder.CreateBitCast(Ops[0], 6201 llvm::VectorType::get(DoubleTy, 2)); 6202 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6203 "vgetq_lane"); 6204 case NEON::BI__builtin_neon_vaddd_s64: 6205 case NEON::BI__builtin_neon_vaddd_u64: 6206 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd"); 6207 case NEON::BI__builtin_neon_vsubd_s64: 6208 case NEON::BI__builtin_neon_vsubd_u64: 6209 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd"); 6210 case NEON::BI__builtin_neon_vqdmlalh_s16: 6211 case NEON::BI__builtin_neon_vqdmlslh_s16: { 6212 SmallVector<Value *, 2> ProductOps; 6213 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6214 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2)))); 6215 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6216 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6217 ProductOps, "vqdmlXl"); 6218 Constant *CI = ConstantInt::get(SizeTy, 0); 6219 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6220 6221 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16 6222 ? Intrinsic::aarch64_neon_sqadd 6223 : Intrinsic::aarch64_neon_sqsub; 6224 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl"); 6225 } 6226 case NEON::BI__builtin_neon_vqshlud_n_s64: { 6227 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6228 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6229 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty), 6230 Ops, "vqshlu_n"); 6231 } 6232 case NEON::BI__builtin_neon_vqshld_n_u64: 6233 case NEON::BI__builtin_neon_vqshld_n_s64: { 6234 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64 6235 ? Intrinsic::aarch64_neon_uqshl 6236 : Intrinsic::aarch64_neon_sqshl; 6237 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6238 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6239 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n"); 6240 } 6241 case NEON::BI__builtin_neon_vrshrd_n_u64: 6242 case NEON::BI__builtin_neon_vrshrd_n_s64: { 6243 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64 6244 ? Intrinsic::aarch64_neon_urshl 6245 : Intrinsic::aarch64_neon_srshl; 6246 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6247 int SV = cast<ConstantInt>(Ops[1])->getSExtValue(); 6248 Ops[1] = ConstantInt::get(Int64Ty, -SV); 6249 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n"); 6250 } 6251 case NEON::BI__builtin_neon_vrsrad_n_u64: 6252 case NEON::BI__builtin_neon_vrsrad_n_s64: { 6253 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64 6254 ? Intrinsic::aarch64_neon_urshl 6255 : Intrinsic::aarch64_neon_srshl; 6256 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6257 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2)))); 6258 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty), 6259 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)}); 6260 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty)); 6261 } 6262 case NEON::BI__builtin_neon_vshld_n_s64: 6263 case NEON::BI__builtin_neon_vshld_n_u64: { 6264 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6265 return Builder.CreateShl( 6266 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n"); 6267 } 6268 case NEON::BI__builtin_neon_vshrd_n_s64: { 6269 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6270 return Builder.CreateAShr( 6271 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6272 Amt->getZExtValue())), 6273 "shrd_n"); 6274 } 6275 case NEON::BI__builtin_neon_vshrd_n_u64: { 6276 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6277 uint64_t ShiftAmt = Amt->getZExtValue(); 6278 // Right-shifting an unsigned value by its size yields 0. 6279 if (ShiftAmt == 64) 6280 return ConstantInt::get(Int64Ty, 0); 6281 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt), 6282 "shrd_n"); 6283 } 6284 case NEON::BI__builtin_neon_vsrad_n_s64: { 6285 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6286 Ops[1] = Builder.CreateAShr( 6287 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6288 Amt->getZExtValue())), 6289 "shrd_n"); 6290 return Builder.CreateAdd(Ops[0], Ops[1]); 6291 } 6292 case NEON::BI__builtin_neon_vsrad_n_u64: { 6293 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6294 uint64_t ShiftAmt = Amt->getZExtValue(); 6295 // Right-shifting an unsigned value by its size yields 0. 6296 // As Op + 0 = Op, return Ops[0] directly. 6297 if (ShiftAmt == 64) 6298 return Ops[0]; 6299 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt), 6300 "shrd_n"); 6301 return Builder.CreateAdd(Ops[0], Ops[1]); 6302 } 6303 case NEON::BI__builtin_neon_vqdmlalh_lane_s16: 6304 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16: 6305 case NEON::BI__builtin_neon_vqdmlslh_lane_s16: 6306 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: { 6307 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6308 "lane"); 6309 SmallVector<Value *, 2> ProductOps; 6310 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6311 ProductOps.push_back(vectorWrapScalar16(Ops[2])); 6312 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6313 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6314 ProductOps, "vqdmlXl"); 6315 Constant *CI = ConstantInt::get(SizeTy, 0); 6316 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6317 Ops.pop_back(); 6318 6319 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 || 6320 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16) 6321 ? Intrinsic::aarch64_neon_sqadd 6322 : Intrinsic::aarch64_neon_sqsub; 6323 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl"); 6324 } 6325 case NEON::BI__builtin_neon_vqdmlals_s32: 6326 case NEON::BI__builtin_neon_vqdmlsls_s32: { 6327 SmallVector<Value *, 2> ProductOps; 6328 ProductOps.push_back(Ops[1]); 6329 ProductOps.push_back(EmitScalarExpr(E->getArg(2))); 6330 Ops[1] = 6331 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6332 ProductOps, "vqdmlXl"); 6333 6334 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32 6335 ? Intrinsic::aarch64_neon_sqadd 6336 : Intrinsic::aarch64_neon_sqsub; 6337 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl"); 6338 } 6339 case NEON::BI__builtin_neon_vqdmlals_lane_s32: 6340 case NEON::BI__builtin_neon_vqdmlals_laneq_s32: 6341 case NEON::BI__builtin_neon_vqdmlsls_lane_s32: 6342 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: { 6343 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6344 "lane"); 6345 SmallVector<Value *, 2> ProductOps; 6346 ProductOps.push_back(Ops[1]); 6347 ProductOps.push_back(Ops[2]); 6348 Ops[1] = 6349 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6350 ProductOps, "vqdmlXl"); 6351 Ops.pop_back(); 6352 6353 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 || 6354 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32) 6355 ? Intrinsic::aarch64_neon_sqadd 6356 : Intrinsic::aarch64_neon_sqsub; 6357 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl"); 6358 } 6359 } 6360 6361 llvm::VectorType *VTy = GetNeonType(this, Type); 6362 llvm::Type *Ty = VTy; 6363 if (!Ty) 6364 return nullptr; 6365 6366 // Not all intrinsics handled by the common case work for AArch64 yet, so only 6367 // defer to common code if it's been added to our special map. 6368 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID, 6369 AArch64SIMDIntrinsicsProvenSorted); 6370 6371 if (Builtin) 6372 return EmitCommonNeonBuiltinExpr( 6373 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 6374 Builtin->NameHint, Builtin->TypeModifier, E, Ops, 6375 /*never use addresses*/ Address::invalid(), Address::invalid()); 6376 6377 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops)) 6378 return V; 6379 6380 unsigned Int; 6381 switch (BuiltinID) { 6382 default: return nullptr; 6383 case NEON::BI__builtin_neon_vbsl_v: 6384 case NEON::BI__builtin_neon_vbslq_v: { 6385 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy); 6386 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl"); 6387 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl"); 6388 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl"); 6389 6390 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl"); 6391 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl"); 6392 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl"); 6393 return Builder.CreateBitCast(Ops[0], Ty); 6394 } 6395 case NEON::BI__builtin_neon_vfma_lane_v: 6396 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types 6397 // The ARM builtins (and instructions) have the addend as the first 6398 // operand, but the 'fma' intrinsics have it last. Swap it around here. 6399 Value *Addend = Ops[0]; 6400 Value *Multiplicand = Ops[1]; 6401 Value *LaneSource = Ops[2]; 6402 Ops[0] = Multiplicand; 6403 Ops[1] = LaneSource; 6404 Ops[2] = Addend; 6405 6406 // Now adjust things to handle the lane access. 6407 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ? 6408 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) : 6409 VTy; 6410 llvm::Constant *cst = cast<Constant>(Ops[3]); 6411 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst); 6412 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy); 6413 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane"); 6414 6415 Ops.pop_back(); 6416 Int = Intrinsic::fma; 6417 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla"); 6418 } 6419 case NEON::BI__builtin_neon_vfma_laneq_v: { 6420 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 6421 // v1f64 fma should be mapped to Neon scalar f64 fma 6422 if (VTy && VTy->getElementType() == DoubleTy) { 6423 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6424 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 6425 llvm::Type *VTy = GetNeonType(this, 6426 NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 6427 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 6428 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6429 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 6430 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6431 return Builder.CreateBitCast(Result, Ty); 6432 } 6433 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6434 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6435 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6436 6437 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 6438 VTy->getNumElements() * 2); 6439 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 6440 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 6441 cast<ConstantInt>(Ops[3])); 6442 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 6443 6444 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6445 } 6446 case NEON::BI__builtin_neon_vfmaq_laneq_v: { 6447 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6448 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6449 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6450 6451 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6452 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 6453 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6454 } 6455 case NEON::BI__builtin_neon_vfmas_lane_f32: 6456 case NEON::BI__builtin_neon_vfmas_laneq_f32: 6457 case NEON::BI__builtin_neon_vfmad_lane_f64: 6458 case NEON::BI__builtin_neon_vfmad_laneq_f64: { 6459 Ops.push_back(EmitScalarExpr(E->getArg(3))); 6460 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 6461 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6462 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6463 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6464 } 6465 case NEON::BI__builtin_neon_vmull_v: 6466 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6467 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull; 6468 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull; 6469 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 6470 case NEON::BI__builtin_neon_vmax_v: 6471 case NEON::BI__builtin_neon_vmaxq_v: 6472 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6473 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax; 6474 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax; 6475 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 6476 case NEON::BI__builtin_neon_vmin_v: 6477 case NEON::BI__builtin_neon_vminq_v: 6478 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6479 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin; 6480 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin; 6481 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 6482 case NEON::BI__builtin_neon_vabd_v: 6483 case NEON::BI__builtin_neon_vabdq_v: 6484 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6485 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd; 6486 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd; 6487 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 6488 case NEON::BI__builtin_neon_vpadal_v: 6489 case NEON::BI__builtin_neon_vpadalq_v: { 6490 unsigned ArgElts = VTy->getNumElements(); 6491 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType()); 6492 unsigned BitWidth = EltTy->getBitWidth(); 6493 llvm::Type *ArgTy = llvm::VectorType::get( 6494 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts); 6495 llvm::Type* Tys[2] = { VTy, ArgTy }; 6496 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp; 6497 SmallVector<llvm::Value*, 1> TmpOps; 6498 TmpOps.push_back(Ops[1]); 6499 Function *F = CGM.getIntrinsic(Int, Tys); 6500 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal"); 6501 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType()); 6502 return Builder.CreateAdd(tmp, addend); 6503 } 6504 case NEON::BI__builtin_neon_vpmin_v: 6505 case NEON::BI__builtin_neon_vpminq_v: 6506 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6507 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp; 6508 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp; 6509 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 6510 case NEON::BI__builtin_neon_vpmax_v: 6511 case NEON::BI__builtin_neon_vpmaxq_v: 6512 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6513 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp; 6514 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp; 6515 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 6516 case NEON::BI__builtin_neon_vminnm_v: 6517 case NEON::BI__builtin_neon_vminnmq_v: 6518 Int = Intrinsic::aarch64_neon_fminnm; 6519 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 6520 case NEON::BI__builtin_neon_vmaxnm_v: 6521 case NEON::BI__builtin_neon_vmaxnmq_v: 6522 Int = Intrinsic::aarch64_neon_fmaxnm; 6523 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 6524 case NEON::BI__builtin_neon_vrecpss_f32: { 6525 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6526 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy), 6527 Ops, "vrecps"); 6528 } 6529 case NEON::BI__builtin_neon_vrecpsd_f64: { 6530 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6531 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy), 6532 Ops, "vrecps"); 6533 } 6534 case NEON::BI__builtin_neon_vqshrun_n_v: 6535 Int = Intrinsic::aarch64_neon_sqshrun; 6536 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 6537 case NEON::BI__builtin_neon_vqrshrun_n_v: 6538 Int = Intrinsic::aarch64_neon_sqrshrun; 6539 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 6540 case NEON::BI__builtin_neon_vqshrn_n_v: 6541 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn; 6542 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 6543 case NEON::BI__builtin_neon_vrshrn_n_v: 6544 Int = Intrinsic::aarch64_neon_rshrn; 6545 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 6546 case NEON::BI__builtin_neon_vqrshrn_n_v: 6547 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn; 6548 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 6549 case NEON::BI__builtin_neon_vrnda_v: 6550 case NEON::BI__builtin_neon_vrndaq_v: { 6551 Int = Intrinsic::round; 6552 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); 6553 } 6554 case NEON::BI__builtin_neon_vrndi_v: 6555 case NEON::BI__builtin_neon_vrndiq_v: { 6556 Int = Intrinsic::nearbyint; 6557 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); 6558 } 6559 case NEON::BI__builtin_neon_vrndm_v: 6560 case NEON::BI__builtin_neon_vrndmq_v: { 6561 Int = Intrinsic::floor; 6562 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); 6563 } 6564 case NEON::BI__builtin_neon_vrndn_v: 6565 case NEON::BI__builtin_neon_vrndnq_v: { 6566 Int = Intrinsic::aarch64_neon_frintn; 6567 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); 6568 } 6569 case NEON::BI__builtin_neon_vrndp_v: 6570 case NEON::BI__builtin_neon_vrndpq_v: { 6571 Int = Intrinsic::ceil; 6572 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); 6573 } 6574 case NEON::BI__builtin_neon_vrndx_v: 6575 case NEON::BI__builtin_neon_vrndxq_v: { 6576 Int = Intrinsic::rint; 6577 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); 6578 } 6579 case NEON::BI__builtin_neon_vrnd_v: 6580 case NEON::BI__builtin_neon_vrndq_v: { 6581 Int = Intrinsic::trunc; 6582 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz"); 6583 } 6584 case NEON::BI__builtin_neon_vceqz_v: 6585 case NEON::BI__builtin_neon_vceqzq_v: 6586 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, 6587 ICmpInst::ICMP_EQ, "vceqz"); 6588 case NEON::BI__builtin_neon_vcgez_v: 6589 case NEON::BI__builtin_neon_vcgezq_v: 6590 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, 6591 ICmpInst::ICMP_SGE, "vcgez"); 6592 case NEON::BI__builtin_neon_vclez_v: 6593 case NEON::BI__builtin_neon_vclezq_v: 6594 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, 6595 ICmpInst::ICMP_SLE, "vclez"); 6596 case NEON::BI__builtin_neon_vcgtz_v: 6597 case NEON::BI__builtin_neon_vcgtzq_v: 6598 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, 6599 ICmpInst::ICMP_SGT, "vcgtz"); 6600 case NEON::BI__builtin_neon_vcltz_v: 6601 case NEON::BI__builtin_neon_vcltzq_v: 6602 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, 6603 ICmpInst::ICMP_SLT, "vcltz"); 6604 case NEON::BI__builtin_neon_vcvt_f64_v: 6605 case NEON::BI__builtin_neon_vcvtq_f64_v: 6606 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6607 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 6608 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 6609 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 6610 case NEON::BI__builtin_neon_vcvt_f64_f32: { 6611 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad && 6612 "unexpected vcvt_f64_f32 builtin"); 6613 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false); 6614 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6615 6616 return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); 6617 } 6618 case NEON::BI__builtin_neon_vcvt_f32_f64: { 6619 assert(Type.getEltType() == NeonTypeFlags::Float32 && 6620 "unexpected vcvt_f32_f64 builtin"); 6621 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); 6622 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6623 6624 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); 6625 } 6626 case NEON::BI__builtin_neon_vcvt_s32_v: 6627 case NEON::BI__builtin_neon_vcvt_u32_v: 6628 case NEON::BI__builtin_neon_vcvt_s64_v: 6629 case NEON::BI__builtin_neon_vcvt_u64_v: 6630 case NEON::BI__builtin_neon_vcvtq_s32_v: 6631 case NEON::BI__builtin_neon_vcvtq_u32_v: 6632 case NEON::BI__builtin_neon_vcvtq_s64_v: 6633 case NEON::BI__builtin_neon_vcvtq_u64_v: { 6634 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 6635 if (usgn) 6636 return Builder.CreateFPToUI(Ops[0], Ty); 6637 return Builder.CreateFPToSI(Ops[0], Ty); 6638 } 6639 case NEON::BI__builtin_neon_vcvta_s32_v: 6640 case NEON::BI__builtin_neon_vcvtaq_s32_v: 6641 case NEON::BI__builtin_neon_vcvta_u32_v: 6642 case NEON::BI__builtin_neon_vcvtaq_u32_v: 6643 case NEON::BI__builtin_neon_vcvta_s64_v: 6644 case NEON::BI__builtin_neon_vcvtaq_s64_v: 6645 case NEON::BI__builtin_neon_vcvta_u64_v: 6646 case NEON::BI__builtin_neon_vcvtaq_u64_v: { 6647 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas; 6648 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6649 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta"); 6650 } 6651 case NEON::BI__builtin_neon_vcvtm_s32_v: 6652 case NEON::BI__builtin_neon_vcvtmq_s32_v: 6653 case NEON::BI__builtin_neon_vcvtm_u32_v: 6654 case NEON::BI__builtin_neon_vcvtmq_u32_v: 6655 case NEON::BI__builtin_neon_vcvtm_s64_v: 6656 case NEON::BI__builtin_neon_vcvtmq_s64_v: 6657 case NEON::BI__builtin_neon_vcvtm_u64_v: 6658 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 6659 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms; 6660 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6661 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm"); 6662 } 6663 case NEON::BI__builtin_neon_vcvtn_s32_v: 6664 case NEON::BI__builtin_neon_vcvtnq_s32_v: 6665 case NEON::BI__builtin_neon_vcvtn_u32_v: 6666 case NEON::BI__builtin_neon_vcvtnq_u32_v: 6667 case NEON::BI__builtin_neon_vcvtn_s64_v: 6668 case NEON::BI__builtin_neon_vcvtnq_s64_v: 6669 case NEON::BI__builtin_neon_vcvtn_u64_v: 6670 case NEON::BI__builtin_neon_vcvtnq_u64_v: { 6671 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns; 6672 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6673 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn"); 6674 } 6675 case NEON::BI__builtin_neon_vcvtp_s32_v: 6676 case NEON::BI__builtin_neon_vcvtpq_s32_v: 6677 case NEON::BI__builtin_neon_vcvtp_u32_v: 6678 case NEON::BI__builtin_neon_vcvtpq_u32_v: 6679 case NEON::BI__builtin_neon_vcvtp_s64_v: 6680 case NEON::BI__builtin_neon_vcvtpq_s64_v: 6681 case NEON::BI__builtin_neon_vcvtp_u64_v: 6682 case NEON::BI__builtin_neon_vcvtpq_u64_v: { 6683 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps; 6684 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6685 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp"); 6686 } 6687 case NEON::BI__builtin_neon_vmulx_v: 6688 case NEON::BI__builtin_neon_vmulxq_v: { 6689 Int = Intrinsic::aarch64_neon_fmulx; 6690 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 6691 } 6692 case NEON::BI__builtin_neon_vmul_lane_v: 6693 case NEON::BI__builtin_neon_vmul_laneq_v: { 6694 // v1f64 vmul_lane should be mapped to Neon scalar mul lane 6695 bool Quad = false; 6696 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v) 6697 Quad = true; 6698 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6699 llvm::Type *VTy = GetNeonType(this, 6700 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); 6701 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 6702 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); 6703 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); 6704 return Builder.CreateBitCast(Result, Ty); 6705 } 6706 case NEON::BI__builtin_neon_vnegd_s64: 6707 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd"); 6708 case NEON::BI__builtin_neon_vpmaxnm_v: 6709 case NEON::BI__builtin_neon_vpmaxnmq_v: { 6710 Int = Intrinsic::aarch64_neon_fmaxnmp; 6711 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 6712 } 6713 case NEON::BI__builtin_neon_vpminnm_v: 6714 case NEON::BI__builtin_neon_vpminnmq_v: { 6715 Int = Intrinsic::aarch64_neon_fminnmp; 6716 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 6717 } 6718 case NEON::BI__builtin_neon_vsqrt_v: 6719 case NEON::BI__builtin_neon_vsqrtq_v: { 6720 Int = Intrinsic::sqrt; 6721 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6722 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); 6723 } 6724 case NEON::BI__builtin_neon_vrbit_v: 6725 case NEON::BI__builtin_neon_vrbitq_v: { 6726 Int = Intrinsic::aarch64_neon_rbit; 6727 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); 6728 } 6729 case NEON::BI__builtin_neon_vaddv_u8: 6730 // FIXME: These are handled by the AArch64 scalar code. 6731 usgn = true; 6732 // FALLTHROUGH 6733 case NEON::BI__builtin_neon_vaddv_s8: { 6734 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6735 Ty = Int32Ty; 6736 VTy = llvm::VectorType::get(Int8Ty, 8); 6737 llvm::Type *Tys[2] = { Ty, VTy }; 6738 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6739 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6740 return Builder.CreateTrunc(Ops[0], Int8Ty); 6741 } 6742 case NEON::BI__builtin_neon_vaddv_u16: 6743 usgn = true; 6744 // FALLTHROUGH 6745 case NEON::BI__builtin_neon_vaddv_s16: { 6746 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6747 Ty = Int32Ty; 6748 VTy = llvm::VectorType::get(Int16Ty, 4); 6749 llvm::Type *Tys[2] = { Ty, VTy }; 6750 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6751 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6752 return Builder.CreateTrunc(Ops[0], Int16Ty); 6753 } 6754 case NEON::BI__builtin_neon_vaddvq_u8: 6755 usgn = true; 6756 // FALLTHROUGH 6757 case NEON::BI__builtin_neon_vaddvq_s8: { 6758 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6759 Ty = Int32Ty; 6760 VTy = llvm::VectorType::get(Int8Ty, 16); 6761 llvm::Type *Tys[2] = { Ty, VTy }; 6762 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6763 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6764 return Builder.CreateTrunc(Ops[0], Int8Ty); 6765 } 6766 case NEON::BI__builtin_neon_vaddvq_u16: 6767 usgn = true; 6768 // FALLTHROUGH 6769 case NEON::BI__builtin_neon_vaddvq_s16: { 6770 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6771 Ty = Int32Ty; 6772 VTy = llvm::VectorType::get(Int16Ty, 8); 6773 llvm::Type *Tys[2] = { Ty, VTy }; 6774 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6775 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6776 return Builder.CreateTrunc(Ops[0], Int16Ty); 6777 } 6778 case NEON::BI__builtin_neon_vmaxv_u8: { 6779 Int = Intrinsic::aarch64_neon_umaxv; 6780 Ty = Int32Ty; 6781 VTy = llvm::VectorType::get(Int8Ty, 8); 6782 llvm::Type *Tys[2] = { Ty, VTy }; 6783 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6784 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6785 return Builder.CreateTrunc(Ops[0], Int8Ty); 6786 } 6787 case NEON::BI__builtin_neon_vmaxv_u16: { 6788 Int = Intrinsic::aarch64_neon_umaxv; 6789 Ty = Int32Ty; 6790 VTy = llvm::VectorType::get(Int16Ty, 4); 6791 llvm::Type *Tys[2] = { Ty, VTy }; 6792 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6793 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6794 return Builder.CreateTrunc(Ops[0], Int16Ty); 6795 } 6796 case NEON::BI__builtin_neon_vmaxvq_u8: { 6797 Int = Intrinsic::aarch64_neon_umaxv; 6798 Ty = Int32Ty; 6799 VTy = llvm::VectorType::get(Int8Ty, 16); 6800 llvm::Type *Tys[2] = { Ty, VTy }; 6801 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6802 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6803 return Builder.CreateTrunc(Ops[0], Int8Ty); 6804 } 6805 case NEON::BI__builtin_neon_vmaxvq_u16: { 6806 Int = Intrinsic::aarch64_neon_umaxv; 6807 Ty = Int32Ty; 6808 VTy = llvm::VectorType::get(Int16Ty, 8); 6809 llvm::Type *Tys[2] = { Ty, VTy }; 6810 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6811 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6812 return Builder.CreateTrunc(Ops[0], Int16Ty); 6813 } 6814 case NEON::BI__builtin_neon_vmaxv_s8: { 6815 Int = Intrinsic::aarch64_neon_smaxv; 6816 Ty = Int32Ty; 6817 VTy = llvm::VectorType::get(Int8Ty, 8); 6818 llvm::Type *Tys[2] = { Ty, VTy }; 6819 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6820 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6821 return Builder.CreateTrunc(Ops[0], Int8Ty); 6822 } 6823 case NEON::BI__builtin_neon_vmaxv_s16: { 6824 Int = Intrinsic::aarch64_neon_smaxv; 6825 Ty = Int32Ty; 6826 VTy = llvm::VectorType::get(Int16Ty, 4); 6827 llvm::Type *Tys[2] = { Ty, VTy }; 6828 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6829 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6830 return Builder.CreateTrunc(Ops[0], Int16Ty); 6831 } 6832 case NEON::BI__builtin_neon_vmaxvq_s8: { 6833 Int = Intrinsic::aarch64_neon_smaxv; 6834 Ty = Int32Ty; 6835 VTy = llvm::VectorType::get(Int8Ty, 16); 6836 llvm::Type *Tys[2] = { Ty, VTy }; 6837 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6838 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6839 return Builder.CreateTrunc(Ops[0], Int8Ty); 6840 } 6841 case NEON::BI__builtin_neon_vmaxvq_s16: { 6842 Int = Intrinsic::aarch64_neon_smaxv; 6843 Ty = Int32Ty; 6844 VTy = llvm::VectorType::get(Int16Ty, 8); 6845 llvm::Type *Tys[2] = { Ty, VTy }; 6846 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6847 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6848 return Builder.CreateTrunc(Ops[0], Int16Ty); 6849 } 6850 case NEON::BI__builtin_neon_vminv_u8: { 6851 Int = Intrinsic::aarch64_neon_uminv; 6852 Ty = Int32Ty; 6853 VTy = llvm::VectorType::get(Int8Ty, 8); 6854 llvm::Type *Tys[2] = { Ty, VTy }; 6855 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6856 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6857 return Builder.CreateTrunc(Ops[0], Int8Ty); 6858 } 6859 case NEON::BI__builtin_neon_vminv_u16: { 6860 Int = Intrinsic::aarch64_neon_uminv; 6861 Ty = Int32Ty; 6862 VTy = llvm::VectorType::get(Int16Ty, 4); 6863 llvm::Type *Tys[2] = { Ty, VTy }; 6864 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6865 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6866 return Builder.CreateTrunc(Ops[0], Int16Ty); 6867 } 6868 case NEON::BI__builtin_neon_vminvq_u8: { 6869 Int = Intrinsic::aarch64_neon_uminv; 6870 Ty = Int32Ty; 6871 VTy = llvm::VectorType::get(Int8Ty, 16); 6872 llvm::Type *Tys[2] = { Ty, VTy }; 6873 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6874 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6875 return Builder.CreateTrunc(Ops[0], Int8Ty); 6876 } 6877 case NEON::BI__builtin_neon_vminvq_u16: { 6878 Int = Intrinsic::aarch64_neon_uminv; 6879 Ty = Int32Ty; 6880 VTy = llvm::VectorType::get(Int16Ty, 8); 6881 llvm::Type *Tys[2] = { Ty, VTy }; 6882 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6883 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6884 return Builder.CreateTrunc(Ops[0], Int16Ty); 6885 } 6886 case NEON::BI__builtin_neon_vminv_s8: { 6887 Int = Intrinsic::aarch64_neon_sminv; 6888 Ty = Int32Ty; 6889 VTy = llvm::VectorType::get(Int8Ty, 8); 6890 llvm::Type *Tys[2] = { Ty, VTy }; 6891 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6892 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6893 return Builder.CreateTrunc(Ops[0], Int8Ty); 6894 } 6895 case NEON::BI__builtin_neon_vminv_s16: { 6896 Int = Intrinsic::aarch64_neon_sminv; 6897 Ty = Int32Ty; 6898 VTy = llvm::VectorType::get(Int16Ty, 4); 6899 llvm::Type *Tys[2] = { Ty, VTy }; 6900 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6901 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6902 return Builder.CreateTrunc(Ops[0], Int16Ty); 6903 } 6904 case NEON::BI__builtin_neon_vminvq_s8: { 6905 Int = Intrinsic::aarch64_neon_sminv; 6906 Ty = Int32Ty; 6907 VTy = llvm::VectorType::get(Int8Ty, 16); 6908 llvm::Type *Tys[2] = { Ty, VTy }; 6909 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6910 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6911 return Builder.CreateTrunc(Ops[0], Int8Ty); 6912 } 6913 case NEON::BI__builtin_neon_vminvq_s16: { 6914 Int = Intrinsic::aarch64_neon_sminv; 6915 Ty = Int32Ty; 6916 VTy = llvm::VectorType::get(Int16Ty, 8); 6917 llvm::Type *Tys[2] = { Ty, VTy }; 6918 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6919 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6920 return Builder.CreateTrunc(Ops[0], Int16Ty); 6921 } 6922 case NEON::BI__builtin_neon_vmul_n_f64: { 6923 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6924 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy); 6925 return Builder.CreateFMul(Ops[0], RHS); 6926 } 6927 case NEON::BI__builtin_neon_vaddlv_u8: { 6928 Int = Intrinsic::aarch64_neon_uaddlv; 6929 Ty = Int32Ty; 6930 VTy = llvm::VectorType::get(Int8Ty, 8); 6931 llvm::Type *Tys[2] = { Ty, VTy }; 6932 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6933 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6934 return Builder.CreateTrunc(Ops[0], Int16Ty); 6935 } 6936 case NEON::BI__builtin_neon_vaddlv_u16: { 6937 Int = Intrinsic::aarch64_neon_uaddlv; 6938 Ty = Int32Ty; 6939 VTy = llvm::VectorType::get(Int16Ty, 4); 6940 llvm::Type *Tys[2] = { Ty, VTy }; 6941 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6942 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6943 } 6944 case NEON::BI__builtin_neon_vaddlvq_u8: { 6945 Int = Intrinsic::aarch64_neon_uaddlv; 6946 Ty = Int32Ty; 6947 VTy = llvm::VectorType::get(Int8Ty, 16); 6948 llvm::Type *Tys[2] = { Ty, VTy }; 6949 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6950 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6951 return Builder.CreateTrunc(Ops[0], Int16Ty); 6952 } 6953 case NEON::BI__builtin_neon_vaddlvq_u16: { 6954 Int = Intrinsic::aarch64_neon_uaddlv; 6955 Ty = Int32Ty; 6956 VTy = llvm::VectorType::get(Int16Ty, 8); 6957 llvm::Type *Tys[2] = { Ty, VTy }; 6958 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6959 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6960 } 6961 case NEON::BI__builtin_neon_vaddlv_s8: { 6962 Int = Intrinsic::aarch64_neon_saddlv; 6963 Ty = Int32Ty; 6964 VTy = llvm::VectorType::get(Int8Ty, 8); 6965 llvm::Type *Tys[2] = { Ty, VTy }; 6966 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6967 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6968 return Builder.CreateTrunc(Ops[0], Int16Ty); 6969 } 6970 case NEON::BI__builtin_neon_vaddlv_s16: { 6971 Int = Intrinsic::aarch64_neon_saddlv; 6972 Ty = Int32Ty; 6973 VTy = llvm::VectorType::get(Int16Ty, 4); 6974 llvm::Type *Tys[2] = { Ty, VTy }; 6975 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6976 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6977 } 6978 case NEON::BI__builtin_neon_vaddlvq_s8: { 6979 Int = Intrinsic::aarch64_neon_saddlv; 6980 Ty = Int32Ty; 6981 VTy = llvm::VectorType::get(Int8Ty, 16); 6982 llvm::Type *Tys[2] = { Ty, VTy }; 6983 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6984 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6985 return Builder.CreateTrunc(Ops[0], Int16Ty); 6986 } 6987 case NEON::BI__builtin_neon_vaddlvq_s16: { 6988 Int = Intrinsic::aarch64_neon_saddlv; 6989 Ty = Int32Ty; 6990 VTy = llvm::VectorType::get(Int16Ty, 8); 6991 llvm::Type *Tys[2] = { Ty, VTy }; 6992 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6993 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6994 } 6995 case NEON::BI__builtin_neon_vsri_n_v: 6996 case NEON::BI__builtin_neon_vsriq_n_v: { 6997 Int = Intrinsic::aarch64_neon_vsri; 6998 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6999 return EmitNeonCall(Intrin, Ops, "vsri_n"); 7000 } 7001 case NEON::BI__builtin_neon_vsli_n_v: 7002 case NEON::BI__builtin_neon_vsliq_n_v: { 7003 Int = Intrinsic::aarch64_neon_vsli; 7004 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 7005 return EmitNeonCall(Intrin, Ops, "vsli_n"); 7006 } 7007 case NEON::BI__builtin_neon_vsra_n_v: 7008 case NEON::BI__builtin_neon_vsraq_n_v: 7009 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7010 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 7011 return Builder.CreateAdd(Ops[0], Ops[1]); 7012 case NEON::BI__builtin_neon_vrsra_n_v: 7013 case NEON::BI__builtin_neon_vrsraq_n_v: { 7014 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl; 7015 SmallVector<llvm::Value*,2> TmpOps; 7016 TmpOps.push_back(Ops[1]); 7017 TmpOps.push_back(Ops[2]); 7018 Function* F = CGM.getIntrinsic(Int, Ty); 7019 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true); 7020 Ops[0] = Builder.CreateBitCast(Ops[0], VTy); 7021 return Builder.CreateAdd(Ops[0], tmp); 7022 } 7023 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence 7024 // of an Align parameter here. 7025 case NEON::BI__builtin_neon_vld1_x2_v: 7026 case NEON::BI__builtin_neon_vld1q_x2_v: 7027 case NEON::BI__builtin_neon_vld1_x3_v: 7028 case NEON::BI__builtin_neon_vld1q_x3_v: 7029 case NEON::BI__builtin_neon_vld1_x4_v: 7030 case NEON::BI__builtin_neon_vld1q_x4_v: { 7031 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 7032 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7033 llvm::Type *Tys[2] = { VTy, PTy }; 7034 unsigned Int; 7035 switch (BuiltinID) { 7036 case NEON::BI__builtin_neon_vld1_x2_v: 7037 case NEON::BI__builtin_neon_vld1q_x2_v: 7038 Int = Intrinsic::aarch64_neon_ld1x2; 7039 break; 7040 case NEON::BI__builtin_neon_vld1_x3_v: 7041 case NEON::BI__builtin_neon_vld1q_x3_v: 7042 Int = Intrinsic::aarch64_neon_ld1x3; 7043 break; 7044 case NEON::BI__builtin_neon_vld1_x4_v: 7045 case NEON::BI__builtin_neon_vld1q_x4_v: 7046 Int = Intrinsic::aarch64_neon_ld1x4; 7047 break; 7048 } 7049 Function *F = CGM.getIntrinsic(Int, Tys); 7050 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN"); 7051 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7052 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7053 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7054 } 7055 case NEON::BI__builtin_neon_vst1_x2_v: 7056 case NEON::BI__builtin_neon_vst1q_x2_v: 7057 case NEON::BI__builtin_neon_vst1_x3_v: 7058 case NEON::BI__builtin_neon_vst1q_x3_v: 7059 case NEON::BI__builtin_neon_vst1_x4_v: 7060 case NEON::BI__builtin_neon_vst1q_x4_v: { 7061 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 7062 llvm::Type *Tys[2] = { VTy, PTy }; 7063 unsigned Int; 7064 switch (BuiltinID) { 7065 case NEON::BI__builtin_neon_vst1_x2_v: 7066 case NEON::BI__builtin_neon_vst1q_x2_v: 7067 Int = Intrinsic::aarch64_neon_st1x2; 7068 break; 7069 case NEON::BI__builtin_neon_vst1_x3_v: 7070 case NEON::BI__builtin_neon_vst1q_x3_v: 7071 Int = Intrinsic::aarch64_neon_st1x3; 7072 break; 7073 case NEON::BI__builtin_neon_vst1_x4_v: 7074 case NEON::BI__builtin_neon_vst1q_x4_v: 7075 Int = Intrinsic::aarch64_neon_st1x4; 7076 break; 7077 } 7078 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end()); 7079 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 7080 } 7081 case NEON::BI__builtin_neon_vld1_v: 7082 case NEON::BI__builtin_neon_vld1q_v: { 7083 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 7084 auto Alignment = CharUnits::fromQuantity( 7085 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16); 7086 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment); 7087 } 7088 case NEON::BI__builtin_neon_vst1_v: 7089 case NEON::BI__builtin_neon_vst1q_v: 7090 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 7091 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 7092 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7093 case NEON::BI__builtin_neon_vld1_lane_v: 7094 case NEON::BI__builtin_neon_vld1q_lane_v: { 7095 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7096 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7097 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7098 auto Alignment = CharUnits::fromQuantity( 7099 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16); 7100 Ops[0] = 7101 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7102 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane"); 7103 } 7104 case NEON::BI__builtin_neon_vld1_dup_v: 7105 case NEON::BI__builtin_neon_vld1q_dup_v: { 7106 Value *V = UndefValue::get(Ty); 7107 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7108 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7109 auto Alignment = CharUnits::fromQuantity( 7110 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16); 7111 Ops[0] = 7112 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7113 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 7114 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI); 7115 return EmitNeonSplat(Ops[0], CI); 7116 } 7117 case NEON::BI__builtin_neon_vst1_lane_v: 7118 case NEON::BI__builtin_neon_vst1q_lane_v: 7119 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7120 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 7121 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7122 return Builder.CreateDefaultAlignedStore(Ops[1], 7123 Builder.CreateBitCast(Ops[0], Ty)); 7124 case NEON::BI__builtin_neon_vld2_v: 7125 case NEON::BI__builtin_neon_vld2q_v: { 7126 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7127 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7128 llvm::Type *Tys[2] = { VTy, PTy }; 7129 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys); 7130 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7131 Ops[0] = Builder.CreateBitCast(Ops[0], 7132 llvm::PointerType::getUnqual(Ops[1]->getType())); 7133 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7134 } 7135 case NEON::BI__builtin_neon_vld3_v: 7136 case NEON::BI__builtin_neon_vld3q_v: { 7137 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7138 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7139 llvm::Type *Tys[2] = { VTy, PTy }; 7140 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys); 7141 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7142 Ops[0] = Builder.CreateBitCast(Ops[0], 7143 llvm::PointerType::getUnqual(Ops[1]->getType())); 7144 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7145 } 7146 case NEON::BI__builtin_neon_vld4_v: 7147 case NEON::BI__builtin_neon_vld4q_v: { 7148 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7149 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7150 llvm::Type *Tys[2] = { VTy, PTy }; 7151 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys); 7152 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7153 Ops[0] = Builder.CreateBitCast(Ops[0], 7154 llvm::PointerType::getUnqual(Ops[1]->getType())); 7155 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7156 } 7157 case NEON::BI__builtin_neon_vld2_dup_v: 7158 case NEON::BI__builtin_neon_vld2q_dup_v: { 7159 llvm::Type *PTy = 7160 llvm::PointerType::getUnqual(VTy->getElementType()); 7161 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7162 llvm::Type *Tys[2] = { VTy, PTy }; 7163 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys); 7164 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7165 Ops[0] = Builder.CreateBitCast(Ops[0], 7166 llvm::PointerType::getUnqual(Ops[1]->getType())); 7167 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7168 } 7169 case NEON::BI__builtin_neon_vld3_dup_v: 7170 case NEON::BI__builtin_neon_vld3q_dup_v: { 7171 llvm::Type *PTy = 7172 llvm::PointerType::getUnqual(VTy->getElementType()); 7173 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7174 llvm::Type *Tys[2] = { VTy, PTy }; 7175 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys); 7176 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7177 Ops[0] = Builder.CreateBitCast(Ops[0], 7178 llvm::PointerType::getUnqual(Ops[1]->getType())); 7179 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7180 } 7181 case NEON::BI__builtin_neon_vld4_dup_v: 7182 case NEON::BI__builtin_neon_vld4q_dup_v: { 7183 llvm::Type *PTy = 7184 llvm::PointerType::getUnqual(VTy->getElementType()); 7185 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7186 llvm::Type *Tys[2] = { VTy, PTy }; 7187 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys); 7188 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7189 Ops[0] = Builder.CreateBitCast(Ops[0], 7190 llvm::PointerType::getUnqual(Ops[1]->getType())); 7191 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7192 } 7193 case NEON::BI__builtin_neon_vld2_lane_v: 7194 case NEON::BI__builtin_neon_vld2q_lane_v: { 7195 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7196 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys); 7197 Ops.push_back(Ops[1]); 7198 Ops.erase(Ops.begin()+1); 7199 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7200 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7201 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7202 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 7203 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7204 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7205 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7206 } 7207 case NEON::BI__builtin_neon_vld3_lane_v: 7208 case NEON::BI__builtin_neon_vld3q_lane_v: { 7209 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7210 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys); 7211 Ops.push_back(Ops[1]); 7212 Ops.erase(Ops.begin()+1); 7213 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7214 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7215 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7216 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7217 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 7218 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7219 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7220 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7221 } 7222 case NEON::BI__builtin_neon_vld4_lane_v: 7223 case NEON::BI__builtin_neon_vld4q_lane_v: { 7224 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7225 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys); 7226 Ops.push_back(Ops[1]); 7227 Ops.erase(Ops.begin()+1); 7228 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7229 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7230 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7231 Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 7232 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty); 7233 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane"); 7234 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7235 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7236 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7237 } 7238 case NEON::BI__builtin_neon_vst2_v: 7239 case NEON::BI__builtin_neon_vst2q_v: { 7240 Ops.push_back(Ops[0]); 7241 Ops.erase(Ops.begin()); 7242 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() }; 7243 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys), 7244 Ops, ""); 7245 } 7246 case NEON::BI__builtin_neon_vst2_lane_v: 7247 case NEON::BI__builtin_neon_vst2q_lane_v: { 7248 Ops.push_back(Ops[0]); 7249 Ops.erase(Ops.begin()); 7250 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty); 7251 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7252 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys), 7253 Ops, ""); 7254 } 7255 case NEON::BI__builtin_neon_vst3_v: 7256 case NEON::BI__builtin_neon_vst3q_v: { 7257 Ops.push_back(Ops[0]); 7258 Ops.erase(Ops.begin()); 7259 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7260 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys), 7261 Ops, ""); 7262 } 7263 case NEON::BI__builtin_neon_vst3_lane_v: 7264 case NEON::BI__builtin_neon_vst3q_lane_v: { 7265 Ops.push_back(Ops[0]); 7266 Ops.erase(Ops.begin()); 7267 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7268 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7269 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys), 7270 Ops, ""); 7271 } 7272 case NEON::BI__builtin_neon_vst4_v: 7273 case NEON::BI__builtin_neon_vst4q_v: { 7274 Ops.push_back(Ops[0]); 7275 Ops.erase(Ops.begin()); 7276 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7277 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys), 7278 Ops, ""); 7279 } 7280 case NEON::BI__builtin_neon_vst4_lane_v: 7281 case NEON::BI__builtin_neon_vst4q_lane_v: { 7282 Ops.push_back(Ops[0]); 7283 Ops.erase(Ops.begin()); 7284 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7285 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() }; 7286 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys), 7287 Ops, ""); 7288 } 7289 case NEON::BI__builtin_neon_vtrn_v: 7290 case NEON::BI__builtin_neon_vtrnq_v: { 7291 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7292 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7293 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7294 Value *SV = nullptr; 7295 7296 for (unsigned vi = 0; vi != 2; ++vi) { 7297 SmallVector<uint32_t, 16> Indices; 7298 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7299 Indices.push_back(i+vi); 7300 Indices.push_back(i+e+vi); 7301 } 7302 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7303 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 7304 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7305 } 7306 return SV; 7307 } 7308 case NEON::BI__builtin_neon_vuzp_v: 7309 case NEON::BI__builtin_neon_vuzpq_v: { 7310 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7311 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7312 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7313 Value *SV = nullptr; 7314 7315 for (unsigned vi = 0; vi != 2; ++vi) { 7316 SmallVector<uint32_t, 16> Indices; 7317 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 7318 Indices.push_back(2*i+vi); 7319 7320 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7321 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 7322 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7323 } 7324 return SV; 7325 } 7326 case NEON::BI__builtin_neon_vzip_v: 7327 case NEON::BI__builtin_neon_vzipq_v: { 7328 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7329 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7330 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7331 Value *SV = nullptr; 7332 7333 for (unsigned vi = 0; vi != 2; ++vi) { 7334 SmallVector<uint32_t, 16> Indices; 7335 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7336 Indices.push_back((i + vi*e) >> 1); 7337 Indices.push_back(((i + vi*e) >> 1)+e); 7338 } 7339 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7340 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 7341 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7342 } 7343 return SV; 7344 } 7345 case NEON::BI__builtin_neon_vqtbl1q_v: { 7346 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty), 7347 Ops, "vtbl1"); 7348 } 7349 case NEON::BI__builtin_neon_vqtbl2q_v: { 7350 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty), 7351 Ops, "vtbl2"); 7352 } 7353 case NEON::BI__builtin_neon_vqtbl3q_v: { 7354 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty), 7355 Ops, "vtbl3"); 7356 } 7357 case NEON::BI__builtin_neon_vqtbl4q_v: { 7358 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty), 7359 Ops, "vtbl4"); 7360 } 7361 case NEON::BI__builtin_neon_vqtbx1q_v: { 7362 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty), 7363 Ops, "vtbx1"); 7364 } 7365 case NEON::BI__builtin_neon_vqtbx2q_v: { 7366 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty), 7367 Ops, "vtbx2"); 7368 } 7369 case NEON::BI__builtin_neon_vqtbx3q_v: { 7370 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty), 7371 Ops, "vtbx3"); 7372 } 7373 case NEON::BI__builtin_neon_vqtbx4q_v: { 7374 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty), 7375 Ops, "vtbx4"); 7376 } 7377 case NEON::BI__builtin_neon_vsqadd_v: 7378 case NEON::BI__builtin_neon_vsqaddq_v: { 7379 Int = Intrinsic::aarch64_neon_usqadd; 7380 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); 7381 } 7382 case NEON::BI__builtin_neon_vuqadd_v: 7383 case NEON::BI__builtin_neon_vuqaddq_v: { 7384 Int = Intrinsic::aarch64_neon_suqadd; 7385 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); 7386 } 7387 } 7388 } 7389 7390 llvm::Value *CodeGenFunction:: 7391 BuildVector(ArrayRef<llvm::Value*> Ops) { 7392 assert((Ops.size() & (Ops.size() - 1)) == 0 && 7393 "Not a power-of-two sized vector!"); 7394 bool AllConstants = true; 7395 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 7396 AllConstants &= isa<Constant>(Ops[i]); 7397 7398 // If this is a constant vector, create a ConstantVector. 7399 if (AllConstants) { 7400 SmallVector<llvm::Constant*, 16> CstOps; 7401 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7402 CstOps.push_back(cast<Constant>(Ops[i])); 7403 return llvm::ConstantVector::get(CstOps); 7404 } 7405 7406 // Otherwise, insertelement the values to build the vector. 7407 Value *Result = 7408 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 7409 7410 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7411 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 7412 7413 return Result; 7414 } 7415 7416 // Convert the mask from an integer type to a vector of i1. 7417 static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask, 7418 unsigned NumElts) { 7419 7420 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(), 7421 cast<IntegerType>(Mask->getType())->getBitWidth()); 7422 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy); 7423 7424 // If we have less than 8 elements, then the starting mask was an i8 and 7425 // we need to extract down to the right number of elements. 7426 if (NumElts < 8) { 7427 uint32_t Indices[4]; 7428 for (unsigned i = 0; i != NumElts; ++i) 7429 Indices[i] = i; 7430 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec, 7431 makeArrayRef(Indices, NumElts), 7432 "extract"); 7433 } 7434 return MaskVec; 7435 } 7436 7437 static Value *EmitX86MaskedStore(CodeGenFunction &CGF, 7438 SmallVectorImpl<Value *> &Ops, 7439 unsigned Align) { 7440 // Cast the pointer to right type. 7441 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7442 llvm::PointerType::getUnqual(Ops[1]->getType())); 7443 7444 // If the mask is all ones just emit a regular store. 7445 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7446 if (C->isAllOnesValue()) 7447 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align); 7448 7449 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7450 Ops[1]->getType()->getVectorNumElements()); 7451 7452 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec); 7453 } 7454 7455 static Value *EmitX86MaskedLoad(CodeGenFunction &CGF, 7456 SmallVectorImpl<Value *> &Ops, unsigned Align) { 7457 // Cast the pointer to right type. 7458 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7459 llvm::PointerType::getUnqual(Ops[1]->getType())); 7460 7461 // If the mask is all ones just emit a regular store. 7462 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7463 if (C->isAllOnesValue()) 7464 return CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7465 7466 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7467 Ops[1]->getType()->getVectorNumElements()); 7468 7469 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]); 7470 } 7471 7472 static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF, 7473 SmallVectorImpl<Value *> &Ops, 7474 llvm::Type *DstTy, 7475 unsigned SrcSizeInBits, 7476 unsigned Align) { 7477 // Load the subvector. 7478 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7479 7480 // Create broadcast mask. 7481 unsigned NumDstElts = DstTy->getVectorNumElements(); 7482 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits(); 7483 7484 SmallVector<uint32_t, 8> Mask; 7485 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts) 7486 for (unsigned j = 0; j != NumSrcElts; ++j) 7487 Mask.push_back(j); 7488 7489 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst"); 7490 } 7491 7492 static Value *EmitX86Select(CodeGenFunction &CGF, 7493 Value *Mask, Value *Op0, Value *Op1) { 7494 7495 // If the mask is all ones just return first argument. 7496 if (const auto *C = dyn_cast<Constant>(Mask)) 7497 if (C->isAllOnesValue()) 7498 return Op0; 7499 7500 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements()); 7501 7502 return CGF.Builder.CreateSelect(Mask, Op0, Op1); 7503 } 7504 7505 static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC, 7506 bool Signed, SmallVectorImpl<Value *> &Ops) { 7507 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 7508 Value *Cmp; 7509 7510 if (CC == 3) { 7511 Cmp = Constant::getNullValue( 7512 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7513 } else if (CC == 7) { 7514 Cmp = Constant::getAllOnesValue( 7515 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7516 } else { 7517 ICmpInst::Predicate Pred; 7518 switch (CC) { 7519 default: llvm_unreachable("Unknown condition code"); 7520 case 0: Pred = ICmpInst::ICMP_EQ; break; 7521 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; 7522 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; 7523 case 4: Pred = ICmpInst::ICMP_NE; break; 7524 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; 7525 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; 7526 } 7527 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7528 } 7529 7530 const auto *C = dyn_cast<Constant>(Ops.back()); 7531 if (!C || !C->isAllOnesValue()) 7532 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts)); 7533 7534 if (NumElts < 8) { 7535 uint32_t Indices[8]; 7536 for (unsigned i = 0; i != NumElts; ++i) 7537 Indices[i] = i; 7538 for (unsigned i = NumElts; i != 8; ++i) 7539 Indices[i] = i % NumElts + NumElts; 7540 Cmp = CGF.Builder.CreateShuffleVector( 7541 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices); 7542 } 7543 return CGF.Builder.CreateBitCast(Cmp, 7544 IntegerType::get(CGF.getLLVMContext(), 7545 std::max(NumElts, 8U))); 7546 } 7547 7548 static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef<Value *> Ops) { 7549 7550 llvm::Type *Ty = Ops[0]->getType(); 7551 Value *Zero = llvm::Constant::getNullValue(Ty); 7552 Value *Sub = CGF.Builder.CreateSub(Zero, Ops[0]); 7553 Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Zero); 7554 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Sub); 7555 if (Ops.size() == 1) 7556 return Res; 7557 return EmitX86Select(CGF, Ops[2], Res, Ops[1]); 7558 } 7559 7560 static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred, 7561 ArrayRef<Value *> Ops) { 7562 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7563 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]); 7564 7565 if (Ops.size() == 2) 7566 return Res; 7567 7568 assert(Ops.size() == 4); 7569 return EmitX86Select(CGF, Ops[3], Res, Ops[2]); 7570 } 7571 7572 static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, 7573 llvm::Type *DstTy) { 7574 unsigned NumberOfElements = DstTy->getVectorNumElements(); 7575 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements); 7576 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); 7577 } 7578 7579 Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { 7580 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); 7581 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString(); 7582 return EmitX86CpuIs(CPUStr); 7583 } 7584 7585 Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { 7586 7587 llvm::Type *Int32Ty = Builder.getInt32Ty(); 7588 7589 // Matching the struct layout from the compiler-rt/libgcc structure that is 7590 // filled in: 7591 // unsigned int __cpu_vendor; 7592 // unsigned int __cpu_type; 7593 // unsigned int __cpu_subtype; 7594 // unsigned int __cpu_features[1]; 7595 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7596 llvm::ArrayType::get(Int32Ty, 1)); 7597 7598 // Grab the global __cpu_model. 7599 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7600 7601 // Calculate the index needed to access the correct field based on the 7602 // range. Also adjust the expected value. 7603 unsigned Index; 7604 unsigned Value; 7605 std::tie(Index, Value) = StringSwitch<std::pair<unsigned, unsigned>>(CPUStr) 7606 #define X86_VENDOR(ENUM, STRING) \ 7607 .Case(STRING, {0u, static_cast<unsigned>(llvm::X86::ENUM)}) 7608 #define X86_CPU_TYPE_COMPAT_WITH_ALIAS(ARCHNAME, ENUM, STR, ALIAS) \ 7609 .Cases(STR, ALIAS, {1u, static_cast<unsigned>(llvm::X86::ENUM)}) 7610 #define X86_CPU_TYPE_COMPAT(ARCHNAME, ENUM, STR) \ 7611 .Case(STR, {1u, static_cast<unsigned>(llvm::X86::ENUM)}) 7612 #define X86_CPU_SUBTYPE_COMPAT(ARCHNAME, ENUM, STR) \ 7613 .Case(STR, {2u, static_cast<unsigned>(llvm::X86::ENUM)}) 7614 #include "llvm/Support/X86TargetParser.def" 7615 .Default({0, 0}); 7616 assert(Value != 0 && "Invalid CPUStr passed to CpuIs"); 7617 7618 // Grab the appropriate field from __cpu_model. 7619 llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), 7620 ConstantInt::get(Int32Ty, Index)}; 7621 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); 7622 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); 7623 7624 // Check the value of the field against the requested value. 7625 return Builder.CreateICmpEQ(CpuValue, 7626 llvm::ConstantInt::get(Int32Ty, Value)); 7627 } 7628 7629 Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { 7630 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); 7631 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString(); 7632 return EmitX86CpuSupports(FeatureStr); 7633 } 7634 7635 Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) { 7636 // Processor features and mapping to processor feature value. 7637 7638 uint32_t FeaturesMask = 0; 7639 7640 for (const StringRef &FeatureStr : FeatureStrs) { 7641 unsigned Feature = 7642 StringSwitch<unsigned>(FeatureStr) 7643 #define X86_FEATURE_COMPAT(VAL, ENUM, STR) .Case(STR, VAL) 7644 #include "llvm/Support/X86TargetParser.def" 7645 ; 7646 FeaturesMask |= (1U << Feature); 7647 } 7648 7649 // Matching the struct layout from the compiler-rt/libgcc structure that is 7650 // filled in: 7651 // unsigned int __cpu_vendor; 7652 // unsigned int __cpu_type; 7653 // unsigned int __cpu_subtype; 7654 // unsigned int __cpu_features[1]; 7655 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7656 llvm::ArrayType::get(Int32Ty, 1)); 7657 7658 // Grab the global __cpu_model. 7659 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7660 7661 // Grab the first (0th) element from the field __cpu_features off of the 7662 // global in the struct STy. 7663 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3), 7664 ConstantInt::get(Int32Ty, 0)}; 7665 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs); 7666 Value *Features = 7667 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4)); 7668 7669 // Check the value of the bit corresponding to the feature requested. 7670 Value *Bitset = Builder.CreateAnd( 7671 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask)); 7672 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0)); 7673 } 7674 7675 Value *CodeGenFunction::EmitX86CpuInit() { 7676 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, 7677 /*Variadic*/ false); 7678 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init"); 7679 return Builder.CreateCall(Func); 7680 } 7681 7682 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 7683 const CallExpr *E) { 7684 if (BuiltinID == X86::BI__builtin_cpu_is) 7685 return EmitX86CpuIs(E); 7686 if (BuiltinID == X86::BI__builtin_cpu_supports) 7687 return EmitX86CpuSupports(E); 7688 if (BuiltinID == X86::BI__builtin_cpu_init) 7689 return EmitX86CpuInit(); 7690 7691 SmallVector<Value*, 4> Ops; 7692 7693 // Find out if any arguments are required to be integer constant expressions. 7694 unsigned ICEArguments = 0; 7695 ASTContext::GetBuiltinTypeError Error; 7696 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 7697 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 7698 7699 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 7700 // If this is a normal argument, just emit it as a scalar. 7701 if ((ICEArguments & (1 << i)) == 0) { 7702 Ops.push_back(EmitScalarExpr(E->getArg(i))); 7703 continue; 7704 } 7705 7706 // If this is required to be a constant, constant fold it so that we know 7707 // that the generated intrinsic gets a ConstantInt. 7708 llvm::APSInt Result; 7709 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 7710 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 7711 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 7712 } 7713 7714 // These exist so that the builtin that takes an immediate can be bounds 7715 // checked by clang to avoid passing bad immediates to the backend. Since 7716 // AVX has a larger immediate than SSE we would need separate builtins to 7717 // do the different bounds checking. Rather than create a clang specific 7718 // SSE only builtin, this implements eight separate builtins to match gcc 7719 // implementation. 7720 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) { 7721 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm)); 7722 llvm::Function *F = CGM.getIntrinsic(ID); 7723 return Builder.CreateCall(F, Ops); 7724 }; 7725 7726 // For the vector forms of FP comparisons, translate the builtins directly to 7727 // IR. 7728 // TODO: The builtins could be removed if the SSE header files used vector 7729 // extension comparisons directly (vector ordered/unordered may need 7730 // additional support via __builtin_isnan()). 7731 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) { 7732 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]); 7733 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType()); 7734 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy); 7735 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy); 7736 return Builder.CreateBitCast(Sext, FPVecTy); 7737 }; 7738 7739 switch (BuiltinID) { 7740 default: return nullptr; 7741 case X86::BI_mm_prefetch: { 7742 Value *Address = Ops[0]; 7743 Value *RW = ConstantInt::get(Int32Ty, 0); 7744 Value *Locality = Ops[1]; 7745 Value *Data = ConstantInt::get(Int32Ty, 1); 7746 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 7747 return Builder.CreateCall(F, {Address, RW, Locality, Data}); 7748 } 7749 case X86::BI_mm_clflush: { 7750 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush), 7751 Ops[0]); 7752 } 7753 case X86::BI_mm_lfence: { 7754 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence)); 7755 } 7756 case X86::BI_mm_mfence: { 7757 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence)); 7758 } 7759 case X86::BI_mm_sfence: { 7760 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence)); 7761 } 7762 case X86::BI_mm_pause: { 7763 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause)); 7764 } 7765 case X86::BI__rdtsc: { 7766 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc)); 7767 } 7768 case X86::BI__builtin_ia32_undef128: 7769 case X86::BI__builtin_ia32_undef256: 7770 case X86::BI__builtin_ia32_undef512: 7771 // The x86 definition of "undef" is not the same as the LLVM definition 7772 // (PR32176). We leave optimizing away an unnecessary zero constant to the 7773 // IR optimizer and backend. 7774 // TODO: If we had a "freeze" IR instruction to generate a fixed undef 7775 // value, we should use that here instead of a zero. 7776 return llvm::Constant::getNullValue(ConvertType(E->getType())); 7777 case X86::BI__builtin_ia32_vec_init_v8qi: 7778 case X86::BI__builtin_ia32_vec_init_v4hi: 7779 case X86::BI__builtin_ia32_vec_init_v2si: 7780 return Builder.CreateBitCast(BuildVector(Ops), 7781 llvm::Type::getX86_MMXTy(getLLVMContext())); 7782 case X86::BI__builtin_ia32_vec_ext_v2si: 7783 return Builder.CreateExtractElement(Ops[0], 7784 llvm::ConstantInt::get(Ops[1]->getType(), 0)); 7785 case X86::BI_mm_setcsr: 7786 case X86::BI__builtin_ia32_ldmxcsr: { 7787 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 7788 Builder.CreateStore(Ops[0], Tmp); 7789 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 7790 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7791 } 7792 case X86::BI_mm_getcsr: 7793 case X86::BI__builtin_ia32_stmxcsr: { 7794 Address Tmp = CreateMemTemp(E->getType()); 7795 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 7796 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7797 return Builder.CreateLoad(Tmp, "stmxcsr"); 7798 } 7799 case X86::BI__builtin_ia32_xsave: 7800 case X86::BI__builtin_ia32_xsave64: 7801 case X86::BI__builtin_ia32_xrstor: 7802 case X86::BI__builtin_ia32_xrstor64: 7803 case X86::BI__builtin_ia32_xsaveopt: 7804 case X86::BI__builtin_ia32_xsaveopt64: 7805 case X86::BI__builtin_ia32_xrstors: 7806 case X86::BI__builtin_ia32_xrstors64: 7807 case X86::BI__builtin_ia32_xsavec: 7808 case X86::BI__builtin_ia32_xsavec64: 7809 case X86::BI__builtin_ia32_xsaves: 7810 case X86::BI__builtin_ia32_xsaves64: { 7811 Intrinsic::ID ID; 7812 #define INTRINSIC_X86_XSAVE_ID(NAME) \ 7813 case X86::BI__builtin_ia32_##NAME: \ 7814 ID = Intrinsic::x86_##NAME; \ 7815 break 7816 switch (BuiltinID) { 7817 default: llvm_unreachable("Unsupported intrinsic!"); 7818 INTRINSIC_X86_XSAVE_ID(xsave); 7819 INTRINSIC_X86_XSAVE_ID(xsave64); 7820 INTRINSIC_X86_XSAVE_ID(xrstor); 7821 INTRINSIC_X86_XSAVE_ID(xrstor64); 7822 INTRINSIC_X86_XSAVE_ID(xsaveopt); 7823 INTRINSIC_X86_XSAVE_ID(xsaveopt64); 7824 INTRINSIC_X86_XSAVE_ID(xrstors); 7825 INTRINSIC_X86_XSAVE_ID(xrstors64); 7826 INTRINSIC_X86_XSAVE_ID(xsavec); 7827 INTRINSIC_X86_XSAVE_ID(xsavec64); 7828 INTRINSIC_X86_XSAVE_ID(xsaves); 7829 INTRINSIC_X86_XSAVE_ID(xsaves64); 7830 } 7831 #undef INTRINSIC_X86_XSAVE_ID 7832 Value *Mhi = Builder.CreateTrunc( 7833 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty); 7834 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty); 7835 Ops[1] = Mhi; 7836 Ops.push_back(Mlo); 7837 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 7838 } 7839 case X86::BI__builtin_ia32_storedqudi128_mask: 7840 case X86::BI__builtin_ia32_storedqusi128_mask: 7841 case X86::BI__builtin_ia32_storedquhi128_mask: 7842 case X86::BI__builtin_ia32_storedquqi128_mask: 7843 case X86::BI__builtin_ia32_storeupd128_mask: 7844 case X86::BI__builtin_ia32_storeups128_mask: 7845 case X86::BI__builtin_ia32_storedqudi256_mask: 7846 case X86::BI__builtin_ia32_storedqusi256_mask: 7847 case X86::BI__builtin_ia32_storedquhi256_mask: 7848 case X86::BI__builtin_ia32_storedquqi256_mask: 7849 case X86::BI__builtin_ia32_storeupd256_mask: 7850 case X86::BI__builtin_ia32_storeups256_mask: 7851 case X86::BI__builtin_ia32_storedqudi512_mask: 7852 case X86::BI__builtin_ia32_storedqusi512_mask: 7853 case X86::BI__builtin_ia32_storedquhi512_mask: 7854 case X86::BI__builtin_ia32_storedquqi512_mask: 7855 case X86::BI__builtin_ia32_storeupd512_mask: 7856 case X86::BI__builtin_ia32_storeups512_mask: 7857 return EmitX86MaskedStore(*this, Ops, 1); 7858 7859 case X86::BI__builtin_ia32_storess128_mask: 7860 case X86::BI__builtin_ia32_storesd128_mask: { 7861 return EmitX86MaskedStore(*this, Ops, 16); 7862 } 7863 case X86::BI__builtin_ia32_vpopcntd_512: 7864 case X86::BI__builtin_ia32_vpopcntq_512: { 7865 llvm::Type *ResultType = ConvertType(E->getType()); 7866 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 7867 return Builder.CreateCall(F, Ops); 7868 } 7869 case X86::BI__builtin_ia32_cvtmask2b128: 7870 case X86::BI__builtin_ia32_cvtmask2b256: 7871 case X86::BI__builtin_ia32_cvtmask2b512: 7872 case X86::BI__builtin_ia32_cvtmask2w128: 7873 case X86::BI__builtin_ia32_cvtmask2w256: 7874 case X86::BI__builtin_ia32_cvtmask2w512: 7875 case X86::BI__builtin_ia32_cvtmask2d128: 7876 case X86::BI__builtin_ia32_cvtmask2d256: 7877 case X86::BI__builtin_ia32_cvtmask2d512: 7878 case X86::BI__builtin_ia32_cvtmask2q128: 7879 case X86::BI__builtin_ia32_cvtmask2q256: 7880 case X86::BI__builtin_ia32_cvtmask2q512: 7881 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType())); 7882 7883 case X86::BI__builtin_ia32_movdqa32store128_mask: 7884 case X86::BI__builtin_ia32_movdqa64store128_mask: 7885 case X86::BI__builtin_ia32_storeaps128_mask: 7886 case X86::BI__builtin_ia32_storeapd128_mask: 7887 case X86::BI__builtin_ia32_movdqa32store256_mask: 7888 case X86::BI__builtin_ia32_movdqa64store256_mask: 7889 case X86::BI__builtin_ia32_storeaps256_mask: 7890 case X86::BI__builtin_ia32_storeapd256_mask: 7891 case X86::BI__builtin_ia32_movdqa32store512_mask: 7892 case X86::BI__builtin_ia32_movdqa64store512_mask: 7893 case X86::BI__builtin_ia32_storeaps512_mask: 7894 case X86::BI__builtin_ia32_storeapd512_mask: { 7895 unsigned Align = 7896 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7897 return EmitX86MaskedStore(*this, Ops, Align); 7898 } 7899 case X86::BI__builtin_ia32_loadups128_mask: 7900 case X86::BI__builtin_ia32_loadups256_mask: 7901 case X86::BI__builtin_ia32_loadups512_mask: 7902 case X86::BI__builtin_ia32_loadupd128_mask: 7903 case X86::BI__builtin_ia32_loadupd256_mask: 7904 case X86::BI__builtin_ia32_loadupd512_mask: 7905 case X86::BI__builtin_ia32_loaddquqi128_mask: 7906 case X86::BI__builtin_ia32_loaddquqi256_mask: 7907 case X86::BI__builtin_ia32_loaddquqi512_mask: 7908 case X86::BI__builtin_ia32_loaddquhi128_mask: 7909 case X86::BI__builtin_ia32_loaddquhi256_mask: 7910 case X86::BI__builtin_ia32_loaddquhi512_mask: 7911 case X86::BI__builtin_ia32_loaddqusi128_mask: 7912 case X86::BI__builtin_ia32_loaddqusi256_mask: 7913 case X86::BI__builtin_ia32_loaddqusi512_mask: 7914 case X86::BI__builtin_ia32_loaddqudi128_mask: 7915 case X86::BI__builtin_ia32_loaddqudi256_mask: 7916 case X86::BI__builtin_ia32_loaddqudi512_mask: 7917 return EmitX86MaskedLoad(*this, Ops, 1); 7918 7919 case X86::BI__builtin_ia32_loadss128_mask: 7920 case X86::BI__builtin_ia32_loadsd128_mask: 7921 return EmitX86MaskedLoad(*this, Ops, 16); 7922 7923 case X86::BI__builtin_ia32_loadaps128_mask: 7924 case X86::BI__builtin_ia32_loadaps256_mask: 7925 case X86::BI__builtin_ia32_loadaps512_mask: 7926 case X86::BI__builtin_ia32_loadapd128_mask: 7927 case X86::BI__builtin_ia32_loadapd256_mask: 7928 case X86::BI__builtin_ia32_loadapd512_mask: 7929 case X86::BI__builtin_ia32_movdqa32load128_mask: 7930 case X86::BI__builtin_ia32_movdqa32load256_mask: 7931 case X86::BI__builtin_ia32_movdqa32load512_mask: 7932 case X86::BI__builtin_ia32_movdqa64load128_mask: 7933 case X86::BI__builtin_ia32_movdqa64load256_mask: 7934 case X86::BI__builtin_ia32_movdqa64load512_mask: { 7935 unsigned Align = 7936 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7937 return EmitX86MaskedLoad(*this, Ops, Align); 7938 } 7939 7940 case X86::BI__builtin_ia32_vbroadcastf128_pd256: 7941 case X86::BI__builtin_ia32_vbroadcastf128_ps256: { 7942 llvm::Type *DstTy = ConvertType(E->getType()); 7943 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1); 7944 } 7945 7946 case X86::BI__builtin_ia32_storehps: 7947 case X86::BI__builtin_ia32_storelps: { 7948 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 7949 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 7950 7951 // cast val v2i64 7952 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 7953 7954 // extract (0, 1) 7955 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 7956 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index); 7957 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 7958 7959 // cast pointer to i64 & store 7960 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 7961 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7962 } 7963 case X86::BI__builtin_ia32_palignr128: 7964 case X86::BI__builtin_ia32_palignr256: 7965 case X86::BI__builtin_ia32_palignr512_mask: { 7966 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 7967 7968 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 7969 assert(NumElts % 16 == 0); 7970 7971 // If palignr is shifting the pair of vectors more than the size of two 7972 // lanes, emit zero. 7973 if (ShiftVal >= 32) 7974 return llvm::Constant::getNullValue(ConvertType(E->getType())); 7975 7976 // If palignr is shifting the pair of input vectors more than one lane, 7977 // but less than two lanes, convert to shifting in zeroes. 7978 if (ShiftVal > 16) { 7979 ShiftVal -= 16; 7980 Ops[1] = Ops[0]; 7981 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType()); 7982 } 7983 7984 uint32_t Indices[64]; 7985 // 256-bit palignr operates on 128-bit lanes so we need to handle that 7986 for (unsigned l = 0; l != NumElts; l += 16) { 7987 for (unsigned i = 0; i != 16; ++i) { 7988 unsigned Idx = ShiftVal + i; 7989 if (Idx >= 16) 7990 Idx += NumElts - 16; // End of lane, switch operand. 7991 Indices[l + i] = Idx + l; 7992 } 7993 } 7994 7995 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0], 7996 makeArrayRef(Indices, NumElts), 7997 "palignr"); 7998 7999 // If this isn't a masked builtin, just return the align operation. 8000 if (Ops.size() == 3) 8001 return Align; 8002 8003 return EmitX86Select(*this, Ops[4], Align, Ops[3]); 8004 } 8005 8006 case X86::BI__builtin_ia32_vperm2f128_pd256: 8007 case X86::BI__builtin_ia32_vperm2f128_ps256: 8008 case X86::BI__builtin_ia32_vperm2f128_si256: 8009 case X86::BI__builtin_ia32_permti256: { 8010 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8011 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 8012 8013 // This takes a very simple approach since there are two lanes and a 8014 // shuffle can have 2 inputs. So we reserve the first input for the first 8015 // lane and the second input for the second lane. This may result in 8016 // duplicate sources, but this can be dealt with in the backend. 8017 8018 Value *OutOps[2]; 8019 uint32_t Indices[8]; 8020 for (unsigned l = 0; l != 2; ++l) { 8021 // Determine the source for this lane. 8022 if (Imm & (1 << ((l * 4) + 3))) 8023 OutOps[l] = llvm::ConstantAggregateZero::get(Ops[0]->getType()); 8024 else if (Imm & (1 << ((l * 4) + 1))) 8025 OutOps[l] = Ops[1]; 8026 else 8027 OutOps[l] = Ops[0]; 8028 8029 for (unsigned i = 0; i != NumElts/2; ++i) { 8030 // Start with ith element of the source for this lane. 8031 unsigned Idx = (l * NumElts) + i; 8032 // If bit 0 of the immediate half is set, switch to the high half of 8033 // the source. 8034 if (Imm & (1 << (l * 4))) 8035 Idx += NumElts/2; 8036 Indices[(l * (NumElts/2)) + i] = Idx; 8037 } 8038 } 8039 8040 return Builder.CreateShuffleVector(OutOps[0], OutOps[1], 8041 makeArrayRef(Indices, NumElts), 8042 "vperm"); 8043 } 8044 8045 case X86::BI__builtin_ia32_movnti: 8046 case X86::BI__builtin_ia32_movnti64: 8047 case X86::BI__builtin_ia32_movntsd: 8048 case X86::BI__builtin_ia32_movntss: { 8049 llvm::MDNode *Node = llvm::MDNode::get( 8050 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); 8051 8052 Value *Ptr = Ops[0]; 8053 Value *Src = Ops[1]; 8054 8055 // Extract the 0'th element of the source vector. 8056 if (BuiltinID == X86::BI__builtin_ia32_movntsd || 8057 BuiltinID == X86::BI__builtin_ia32_movntss) 8058 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract"); 8059 8060 // Convert the type of the pointer to a pointer to the stored type. 8061 Value *BC = Builder.CreateBitCast( 8062 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast"); 8063 8064 // Unaligned nontemporal store of the scalar value. 8065 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC); 8066 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 8067 SI->setAlignment(1); 8068 return SI; 8069 } 8070 8071 case X86::BI__builtin_ia32_selectb_128: 8072 case X86::BI__builtin_ia32_selectb_256: 8073 case X86::BI__builtin_ia32_selectb_512: 8074 case X86::BI__builtin_ia32_selectw_128: 8075 case X86::BI__builtin_ia32_selectw_256: 8076 case X86::BI__builtin_ia32_selectw_512: 8077 case X86::BI__builtin_ia32_selectd_128: 8078 case X86::BI__builtin_ia32_selectd_256: 8079 case X86::BI__builtin_ia32_selectd_512: 8080 case X86::BI__builtin_ia32_selectq_128: 8081 case X86::BI__builtin_ia32_selectq_256: 8082 case X86::BI__builtin_ia32_selectq_512: 8083 case X86::BI__builtin_ia32_selectps_128: 8084 case X86::BI__builtin_ia32_selectps_256: 8085 case X86::BI__builtin_ia32_selectps_512: 8086 case X86::BI__builtin_ia32_selectpd_128: 8087 case X86::BI__builtin_ia32_selectpd_256: 8088 case X86::BI__builtin_ia32_selectpd_512: 8089 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]); 8090 case X86::BI__builtin_ia32_cmpb128_mask: 8091 case X86::BI__builtin_ia32_cmpb256_mask: 8092 case X86::BI__builtin_ia32_cmpb512_mask: 8093 case X86::BI__builtin_ia32_cmpw128_mask: 8094 case X86::BI__builtin_ia32_cmpw256_mask: 8095 case X86::BI__builtin_ia32_cmpw512_mask: 8096 case X86::BI__builtin_ia32_cmpd128_mask: 8097 case X86::BI__builtin_ia32_cmpd256_mask: 8098 case X86::BI__builtin_ia32_cmpd512_mask: 8099 case X86::BI__builtin_ia32_cmpq128_mask: 8100 case X86::BI__builtin_ia32_cmpq256_mask: 8101 case X86::BI__builtin_ia32_cmpq512_mask: { 8102 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8103 return EmitX86MaskedCompare(*this, CC, true, Ops); 8104 } 8105 case X86::BI__builtin_ia32_ucmpb128_mask: 8106 case X86::BI__builtin_ia32_ucmpb256_mask: 8107 case X86::BI__builtin_ia32_ucmpb512_mask: 8108 case X86::BI__builtin_ia32_ucmpw128_mask: 8109 case X86::BI__builtin_ia32_ucmpw256_mask: 8110 case X86::BI__builtin_ia32_ucmpw512_mask: 8111 case X86::BI__builtin_ia32_ucmpd128_mask: 8112 case X86::BI__builtin_ia32_ucmpd256_mask: 8113 case X86::BI__builtin_ia32_ucmpd512_mask: 8114 case X86::BI__builtin_ia32_ucmpq128_mask: 8115 case X86::BI__builtin_ia32_ucmpq256_mask: 8116 case X86::BI__builtin_ia32_ucmpq512_mask: { 8117 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8118 return EmitX86MaskedCompare(*this, CC, false, Ops); 8119 } 8120 8121 case X86::BI__builtin_ia32_vplzcntd_128_mask: 8122 case X86::BI__builtin_ia32_vplzcntd_256_mask: 8123 case X86::BI__builtin_ia32_vplzcntd_512_mask: 8124 case X86::BI__builtin_ia32_vplzcntq_128_mask: 8125 case X86::BI__builtin_ia32_vplzcntq_256_mask: 8126 case X86::BI__builtin_ia32_vplzcntq_512_mask: { 8127 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType()); 8128 return EmitX86Select(*this, Ops[2], 8129 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}), 8130 Ops[1]); 8131 } 8132 8133 case X86::BI__builtin_ia32_pabsb128: 8134 case X86::BI__builtin_ia32_pabsw128: 8135 case X86::BI__builtin_ia32_pabsd128: 8136 case X86::BI__builtin_ia32_pabsb256: 8137 case X86::BI__builtin_ia32_pabsw256: 8138 case X86::BI__builtin_ia32_pabsd256: 8139 case X86::BI__builtin_ia32_pabsq128_mask: 8140 case X86::BI__builtin_ia32_pabsq256_mask: 8141 case X86::BI__builtin_ia32_pabsb512_mask: 8142 case X86::BI__builtin_ia32_pabsw512_mask: 8143 case X86::BI__builtin_ia32_pabsd512_mask: 8144 case X86::BI__builtin_ia32_pabsq512_mask: 8145 return EmitX86Abs(*this, Ops); 8146 8147 case X86::BI__builtin_ia32_pmaxsb128: 8148 case X86::BI__builtin_ia32_pmaxsw128: 8149 case X86::BI__builtin_ia32_pmaxsd128: 8150 case X86::BI__builtin_ia32_pmaxsq128_mask: 8151 case X86::BI__builtin_ia32_pmaxsb256: 8152 case X86::BI__builtin_ia32_pmaxsw256: 8153 case X86::BI__builtin_ia32_pmaxsd256: 8154 case X86::BI__builtin_ia32_pmaxsq256_mask: 8155 case X86::BI__builtin_ia32_pmaxsb512_mask: 8156 case X86::BI__builtin_ia32_pmaxsw512_mask: 8157 case X86::BI__builtin_ia32_pmaxsd512_mask: 8158 case X86::BI__builtin_ia32_pmaxsq512_mask: 8159 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops); 8160 case X86::BI__builtin_ia32_pmaxub128: 8161 case X86::BI__builtin_ia32_pmaxuw128: 8162 case X86::BI__builtin_ia32_pmaxud128: 8163 case X86::BI__builtin_ia32_pmaxuq128_mask: 8164 case X86::BI__builtin_ia32_pmaxub256: 8165 case X86::BI__builtin_ia32_pmaxuw256: 8166 case X86::BI__builtin_ia32_pmaxud256: 8167 case X86::BI__builtin_ia32_pmaxuq256_mask: 8168 case X86::BI__builtin_ia32_pmaxub512_mask: 8169 case X86::BI__builtin_ia32_pmaxuw512_mask: 8170 case X86::BI__builtin_ia32_pmaxud512_mask: 8171 case X86::BI__builtin_ia32_pmaxuq512_mask: 8172 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops); 8173 case X86::BI__builtin_ia32_pminsb128: 8174 case X86::BI__builtin_ia32_pminsw128: 8175 case X86::BI__builtin_ia32_pminsd128: 8176 case X86::BI__builtin_ia32_pminsq128_mask: 8177 case X86::BI__builtin_ia32_pminsb256: 8178 case X86::BI__builtin_ia32_pminsw256: 8179 case X86::BI__builtin_ia32_pminsd256: 8180 case X86::BI__builtin_ia32_pminsq256_mask: 8181 case X86::BI__builtin_ia32_pminsb512_mask: 8182 case X86::BI__builtin_ia32_pminsw512_mask: 8183 case X86::BI__builtin_ia32_pminsd512_mask: 8184 case X86::BI__builtin_ia32_pminsq512_mask: 8185 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops); 8186 case X86::BI__builtin_ia32_pminub128: 8187 case X86::BI__builtin_ia32_pminuw128: 8188 case X86::BI__builtin_ia32_pminud128: 8189 case X86::BI__builtin_ia32_pminuq128_mask: 8190 case X86::BI__builtin_ia32_pminub256: 8191 case X86::BI__builtin_ia32_pminuw256: 8192 case X86::BI__builtin_ia32_pminud256: 8193 case X86::BI__builtin_ia32_pminuq256_mask: 8194 case X86::BI__builtin_ia32_pminub512_mask: 8195 case X86::BI__builtin_ia32_pminuw512_mask: 8196 case X86::BI__builtin_ia32_pminud512_mask: 8197 case X86::BI__builtin_ia32_pminuq512_mask: 8198 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops); 8199 8200 // 3DNow! 8201 case X86::BI__builtin_ia32_pswapdsf: 8202 case X86::BI__builtin_ia32_pswapdsi: { 8203 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 8204 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 8205 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd); 8206 return Builder.CreateCall(F, Ops, "pswapd"); 8207 } 8208 case X86::BI__builtin_ia32_rdrand16_step: 8209 case X86::BI__builtin_ia32_rdrand32_step: 8210 case X86::BI__builtin_ia32_rdrand64_step: 8211 case X86::BI__builtin_ia32_rdseed16_step: 8212 case X86::BI__builtin_ia32_rdseed32_step: 8213 case X86::BI__builtin_ia32_rdseed64_step: { 8214 Intrinsic::ID ID; 8215 switch (BuiltinID) { 8216 default: llvm_unreachable("Unsupported intrinsic!"); 8217 case X86::BI__builtin_ia32_rdrand16_step: 8218 ID = Intrinsic::x86_rdrand_16; 8219 break; 8220 case X86::BI__builtin_ia32_rdrand32_step: 8221 ID = Intrinsic::x86_rdrand_32; 8222 break; 8223 case X86::BI__builtin_ia32_rdrand64_step: 8224 ID = Intrinsic::x86_rdrand_64; 8225 break; 8226 case X86::BI__builtin_ia32_rdseed16_step: 8227 ID = Intrinsic::x86_rdseed_16; 8228 break; 8229 case X86::BI__builtin_ia32_rdseed32_step: 8230 ID = Intrinsic::x86_rdseed_32; 8231 break; 8232 case X86::BI__builtin_ia32_rdseed64_step: 8233 ID = Intrinsic::x86_rdseed_64; 8234 break; 8235 } 8236 8237 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 8238 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0), 8239 Ops[0]); 8240 return Builder.CreateExtractValue(Call, 1); 8241 } 8242 8243 // SSE packed comparison intrinsics 8244 case X86::BI__builtin_ia32_cmpeqps: 8245 case X86::BI__builtin_ia32_cmpeqpd: 8246 return getVectorFCmpIR(CmpInst::FCMP_OEQ); 8247 case X86::BI__builtin_ia32_cmpltps: 8248 case X86::BI__builtin_ia32_cmpltpd: 8249 return getVectorFCmpIR(CmpInst::FCMP_OLT); 8250 case X86::BI__builtin_ia32_cmpleps: 8251 case X86::BI__builtin_ia32_cmplepd: 8252 return getVectorFCmpIR(CmpInst::FCMP_OLE); 8253 case X86::BI__builtin_ia32_cmpunordps: 8254 case X86::BI__builtin_ia32_cmpunordpd: 8255 return getVectorFCmpIR(CmpInst::FCMP_UNO); 8256 case X86::BI__builtin_ia32_cmpneqps: 8257 case X86::BI__builtin_ia32_cmpneqpd: 8258 return getVectorFCmpIR(CmpInst::FCMP_UNE); 8259 case X86::BI__builtin_ia32_cmpnltps: 8260 case X86::BI__builtin_ia32_cmpnltpd: 8261 return getVectorFCmpIR(CmpInst::FCMP_UGE); 8262 case X86::BI__builtin_ia32_cmpnleps: 8263 case X86::BI__builtin_ia32_cmpnlepd: 8264 return getVectorFCmpIR(CmpInst::FCMP_UGT); 8265 case X86::BI__builtin_ia32_cmpordps: 8266 case X86::BI__builtin_ia32_cmpordpd: 8267 return getVectorFCmpIR(CmpInst::FCMP_ORD); 8268 case X86::BI__builtin_ia32_cmpps: 8269 case X86::BI__builtin_ia32_cmpps256: 8270 case X86::BI__builtin_ia32_cmppd: 8271 case X86::BI__builtin_ia32_cmppd256: { 8272 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8273 // If this one of the SSE immediates, we can use native IR. 8274 if (CC < 8) { 8275 FCmpInst::Predicate Pred; 8276 switch (CC) { 8277 case 0: Pred = FCmpInst::FCMP_OEQ; break; 8278 case 1: Pred = FCmpInst::FCMP_OLT; break; 8279 case 2: Pred = FCmpInst::FCMP_OLE; break; 8280 case 3: Pred = FCmpInst::FCMP_UNO; break; 8281 case 4: Pred = FCmpInst::FCMP_UNE; break; 8282 case 5: Pred = FCmpInst::FCMP_UGE; break; 8283 case 6: Pred = FCmpInst::FCMP_UGT; break; 8284 case 7: Pred = FCmpInst::FCMP_ORD; break; 8285 } 8286 return getVectorFCmpIR(Pred); 8287 } 8288 8289 // We can't handle 8-31 immediates with native IR, use the intrinsic. 8290 // Except for predicates that create constants. 8291 Intrinsic::ID ID; 8292 switch (BuiltinID) { 8293 default: llvm_unreachable("Unsupported intrinsic!"); 8294 case X86::BI__builtin_ia32_cmpps: 8295 ID = Intrinsic::x86_sse_cmp_ps; 8296 break; 8297 case X86::BI__builtin_ia32_cmpps256: 8298 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8299 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8300 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8301 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8302 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) : 8303 llvm::Constant::getNullValue(Builder.getInt32Ty()); 8304 Value *Vec = Builder.CreateVectorSplat( 8305 Ops[0]->getType()->getVectorNumElements(), Constant); 8306 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8307 } 8308 ID = Intrinsic::x86_avx_cmp_ps_256; 8309 break; 8310 case X86::BI__builtin_ia32_cmppd: 8311 ID = Intrinsic::x86_sse2_cmp_pd; 8312 break; 8313 case X86::BI__builtin_ia32_cmppd256: 8314 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8315 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8316 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8317 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8318 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) : 8319 llvm::Constant::getNullValue(Builder.getInt64Ty()); 8320 Value *Vec = Builder.CreateVectorSplat( 8321 Ops[0]->getType()->getVectorNumElements(), Constant); 8322 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8323 } 8324 ID = Intrinsic::x86_avx_cmp_pd_256; 8325 break; 8326 } 8327 8328 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 8329 } 8330 8331 // SSE scalar comparison intrinsics 8332 case X86::BI__builtin_ia32_cmpeqss: 8333 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0); 8334 case X86::BI__builtin_ia32_cmpltss: 8335 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1); 8336 case X86::BI__builtin_ia32_cmpless: 8337 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2); 8338 case X86::BI__builtin_ia32_cmpunordss: 8339 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3); 8340 case X86::BI__builtin_ia32_cmpneqss: 8341 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4); 8342 case X86::BI__builtin_ia32_cmpnltss: 8343 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5); 8344 case X86::BI__builtin_ia32_cmpnless: 8345 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6); 8346 case X86::BI__builtin_ia32_cmpordss: 8347 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7); 8348 case X86::BI__builtin_ia32_cmpeqsd: 8349 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0); 8350 case X86::BI__builtin_ia32_cmpltsd: 8351 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1); 8352 case X86::BI__builtin_ia32_cmplesd: 8353 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2); 8354 case X86::BI__builtin_ia32_cmpunordsd: 8355 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3); 8356 case X86::BI__builtin_ia32_cmpneqsd: 8357 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4); 8358 case X86::BI__builtin_ia32_cmpnltsd: 8359 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5); 8360 case X86::BI__builtin_ia32_cmpnlesd: 8361 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); 8362 case X86::BI__builtin_ia32_cmpordsd: 8363 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); 8364 8365 case X86::BI__emul: 8366 case X86::BI__emulu: { 8367 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64); 8368 bool isSigned = (BuiltinID == X86::BI__emul); 8369 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned); 8370 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned); 8371 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned); 8372 } 8373 case X86::BI__mulh: 8374 case X86::BI__umulh: 8375 case X86::BI_mul128: 8376 case X86::BI_umul128: { 8377 llvm::Type *ResType = ConvertType(E->getType()); 8378 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 8379 8380 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128); 8381 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned); 8382 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned); 8383 8384 Value *MulResult, *HigherBits; 8385 if (IsSigned) { 8386 MulResult = Builder.CreateNSWMul(LHS, RHS); 8387 HigherBits = Builder.CreateAShr(MulResult, 64); 8388 } else { 8389 MulResult = Builder.CreateNUWMul(LHS, RHS); 8390 HigherBits = Builder.CreateLShr(MulResult, 64); 8391 } 8392 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); 8393 8394 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh) 8395 return HigherBits; 8396 8397 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2)); 8398 Builder.CreateStore(HigherBits, HighBitsAddress); 8399 return Builder.CreateIntCast(MulResult, ResType, IsSigned); 8400 } 8401 8402 case X86::BI__faststorefence: { 8403 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8404 llvm::SyncScope::System); 8405 } 8406 case X86::BI_ReadWriteBarrier: 8407 case X86::BI_ReadBarrier: 8408 case X86::BI_WriteBarrier: { 8409 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8410 llvm::SyncScope::SingleThread); 8411 } 8412 case X86::BI_BitScanForward: 8413 case X86::BI_BitScanForward64: 8414 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 8415 case X86::BI_BitScanReverse: 8416 case X86::BI_BitScanReverse64: 8417 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 8418 8419 case X86::BI_InterlockedAnd64: 8420 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 8421 case X86::BI_InterlockedExchange64: 8422 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 8423 case X86::BI_InterlockedExchangeAdd64: 8424 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 8425 case X86::BI_InterlockedExchangeSub64: 8426 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 8427 case X86::BI_InterlockedOr64: 8428 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 8429 case X86::BI_InterlockedXor64: 8430 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 8431 case X86::BI_InterlockedDecrement64: 8432 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 8433 case X86::BI_InterlockedIncrement64: 8434 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 8435 8436 case X86::BI_AddressOfReturnAddress: { 8437 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); 8438 return Builder.CreateCall(F); 8439 } 8440 case X86::BI__stosb: { 8441 // We treat __stosb as a volatile memset - it may not generate "rep stosb" 8442 // instruction, but it will create a memset that won't be optimized away. 8443 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); 8444 } 8445 case X86::BI__ud2: 8446 // llvm.trap makes a ud2a instruction on x86. 8447 return EmitTrapCall(Intrinsic::trap); 8448 case X86::BI__int2c: { 8449 // This syscall signals a driver assertion failure in x86 NT kernels. 8450 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 8451 llvm::InlineAsm *IA = 8452 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true); 8453 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get( 8454 getLLVMContext(), llvm::AttributeList::FunctionIndex, 8455 llvm::Attribute::NoReturn); 8456 CallSite CS = Builder.CreateCall(IA); 8457 CS.setAttributes(NoReturnAttr); 8458 return CS.getInstruction(); 8459 } 8460 case X86::BI__readfsbyte: 8461 case X86::BI__readfsword: 8462 case X86::BI__readfsdword: 8463 case X86::BI__readfsqword: { 8464 llvm::Type *IntTy = ConvertType(E->getType()); 8465 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8466 llvm::PointerType::get(IntTy, 257)); 8467 LoadInst *Load = Builder.CreateAlignedLoad( 8468 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8469 Load->setVolatile(true); 8470 return Load; 8471 } 8472 case X86::BI__readgsbyte: 8473 case X86::BI__readgsword: 8474 case X86::BI__readgsdword: 8475 case X86::BI__readgsqword: { 8476 llvm::Type *IntTy = ConvertType(E->getType()); 8477 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8478 llvm::PointerType::get(IntTy, 256)); 8479 LoadInst *Load = Builder.CreateAlignedLoad( 8480 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8481 Load->setVolatile(true); 8482 return Load; 8483 } 8484 } 8485 } 8486 8487 8488 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 8489 const CallExpr *E) { 8490 SmallVector<Value*, 4> Ops; 8491 8492 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 8493 Ops.push_back(EmitScalarExpr(E->getArg(i))); 8494 8495 Intrinsic::ID ID = Intrinsic::not_intrinsic; 8496 8497 switch (BuiltinID) { 8498 default: return nullptr; 8499 8500 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we 8501 // call __builtin_readcyclecounter. 8502 case PPC::BI__builtin_ppc_get_timebase: 8503 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter)); 8504 8505 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr 8506 case PPC::BI__builtin_altivec_lvx: 8507 case PPC::BI__builtin_altivec_lvxl: 8508 case PPC::BI__builtin_altivec_lvebx: 8509 case PPC::BI__builtin_altivec_lvehx: 8510 case PPC::BI__builtin_altivec_lvewx: 8511 case PPC::BI__builtin_altivec_lvsl: 8512 case PPC::BI__builtin_altivec_lvsr: 8513 case PPC::BI__builtin_vsx_lxvd2x: 8514 case PPC::BI__builtin_vsx_lxvw4x: 8515 case PPC::BI__builtin_vsx_lxvd2x_be: 8516 case PPC::BI__builtin_vsx_lxvw4x_be: 8517 case PPC::BI__builtin_vsx_lxvl: 8518 case PPC::BI__builtin_vsx_lxvll: 8519 { 8520 if(BuiltinID == PPC::BI__builtin_vsx_lxvl || 8521 BuiltinID == PPC::BI__builtin_vsx_lxvll){ 8522 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy); 8523 }else { 8524 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8525 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 8526 Ops.pop_back(); 8527 } 8528 8529 switch (BuiltinID) { 8530 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 8531 case PPC::BI__builtin_altivec_lvx: 8532 ID = Intrinsic::ppc_altivec_lvx; 8533 break; 8534 case PPC::BI__builtin_altivec_lvxl: 8535 ID = Intrinsic::ppc_altivec_lvxl; 8536 break; 8537 case PPC::BI__builtin_altivec_lvebx: 8538 ID = Intrinsic::ppc_altivec_lvebx; 8539 break; 8540 case PPC::BI__builtin_altivec_lvehx: 8541 ID = Intrinsic::ppc_altivec_lvehx; 8542 break; 8543 case PPC::BI__builtin_altivec_lvewx: 8544 ID = Intrinsic::ppc_altivec_lvewx; 8545 break; 8546 case PPC::BI__builtin_altivec_lvsl: 8547 ID = Intrinsic::ppc_altivec_lvsl; 8548 break; 8549 case PPC::BI__builtin_altivec_lvsr: 8550 ID = Intrinsic::ppc_altivec_lvsr; 8551 break; 8552 case PPC::BI__builtin_vsx_lxvd2x: 8553 ID = Intrinsic::ppc_vsx_lxvd2x; 8554 break; 8555 case PPC::BI__builtin_vsx_lxvw4x: 8556 ID = Intrinsic::ppc_vsx_lxvw4x; 8557 break; 8558 case PPC::BI__builtin_vsx_lxvd2x_be: 8559 ID = Intrinsic::ppc_vsx_lxvd2x_be; 8560 break; 8561 case PPC::BI__builtin_vsx_lxvw4x_be: 8562 ID = Intrinsic::ppc_vsx_lxvw4x_be; 8563 break; 8564 case PPC::BI__builtin_vsx_lxvl: 8565 ID = Intrinsic::ppc_vsx_lxvl; 8566 break; 8567 case PPC::BI__builtin_vsx_lxvll: 8568 ID = Intrinsic::ppc_vsx_lxvll; 8569 break; 8570 } 8571 llvm::Function *F = CGM.getIntrinsic(ID); 8572 return Builder.CreateCall(F, Ops, ""); 8573 } 8574 8575 // vec_st, vec_xst_be 8576 case PPC::BI__builtin_altivec_stvx: 8577 case PPC::BI__builtin_altivec_stvxl: 8578 case PPC::BI__builtin_altivec_stvebx: 8579 case PPC::BI__builtin_altivec_stvehx: 8580 case PPC::BI__builtin_altivec_stvewx: 8581 case PPC::BI__builtin_vsx_stxvd2x: 8582 case PPC::BI__builtin_vsx_stxvw4x: 8583 case PPC::BI__builtin_vsx_stxvd2x_be: 8584 case PPC::BI__builtin_vsx_stxvw4x_be: 8585 case PPC::BI__builtin_vsx_stxvl: 8586 case PPC::BI__builtin_vsx_stxvll: 8587 { 8588 if(BuiltinID == PPC::BI__builtin_vsx_stxvl || 8589 BuiltinID == PPC::BI__builtin_vsx_stxvll ){ 8590 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8591 }else { 8592 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 8593 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 8594 Ops.pop_back(); 8595 } 8596 8597 switch (BuiltinID) { 8598 default: llvm_unreachable("Unsupported st intrinsic!"); 8599 case PPC::BI__builtin_altivec_stvx: 8600 ID = Intrinsic::ppc_altivec_stvx; 8601 break; 8602 case PPC::BI__builtin_altivec_stvxl: 8603 ID = Intrinsic::ppc_altivec_stvxl; 8604 break; 8605 case PPC::BI__builtin_altivec_stvebx: 8606 ID = Intrinsic::ppc_altivec_stvebx; 8607 break; 8608 case PPC::BI__builtin_altivec_stvehx: 8609 ID = Intrinsic::ppc_altivec_stvehx; 8610 break; 8611 case PPC::BI__builtin_altivec_stvewx: 8612 ID = Intrinsic::ppc_altivec_stvewx; 8613 break; 8614 case PPC::BI__builtin_vsx_stxvd2x: 8615 ID = Intrinsic::ppc_vsx_stxvd2x; 8616 break; 8617 case PPC::BI__builtin_vsx_stxvw4x: 8618 ID = Intrinsic::ppc_vsx_stxvw4x; 8619 break; 8620 case PPC::BI__builtin_vsx_stxvd2x_be: 8621 ID = Intrinsic::ppc_vsx_stxvd2x_be; 8622 break; 8623 case PPC::BI__builtin_vsx_stxvw4x_be: 8624 ID = Intrinsic::ppc_vsx_stxvw4x_be; 8625 break; 8626 case PPC::BI__builtin_vsx_stxvl: 8627 ID = Intrinsic::ppc_vsx_stxvl; 8628 break; 8629 case PPC::BI__builtin_vsx_stxvll: 8630 ID = Intrinsic::ppc_vsx_stxvll; 8631 break; 8632 } 8633 llvm::Function *F = CGM.getIntrinsic(ID); 8634 return Builder.CreateCall(F, Ops, ""); 8635 } 8636 // Square root 8637 case PPC::BI__builtin_vsx_xvsqrtsp: 8638 case PPC::BI__builtin_vsx_xvsqrtdp: { 8639 llvm::Type *ResultType = ConvertType(E->getType()); 8640 Value *X = EmitScalarExpr(E->getArg(0)); 8641 ID = Intrinsic::sqrt; 8642 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8643 return Builder.CreateCall(F, X); 8644 } 8645 // Count leading zeros 8646 case PPC::BI__builtin_altivec_vclzb: 8647 case PPC::BI__builtin_altivec_vclzh: 8648 case PPC::BI__builtin_altivec_vclzw: 8649 case PPC::BI__builtin_altivec_vclzd: { 8650 llvm::Type *ResultType = ConvertType(E->getType()); 8651 Value *X = EmitScalarExpr(E->getArg(0)); 8652 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8653 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 8654 return Builder.CreateCall(F, {X, Undef}); 8655 } 8656 case PPC::BI__builtin_altivec_vctzb: 8657 case PPC::BI__builtin_altivec_vctzh: 8658 case PPC::BI__builtin_altivec_vctzw: 8659 case PPC::BI__builtin_altivec_vctzd: { 8660 llvm::Type *ResultType = ConvertType(E->getType()); 8661 Value *X = EmitScalarExpr(E->getArg(0)); 8662 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8663 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 8664 return Builder.CreateCall(F, {X, Undef}); 8665 } 8666 case PPC::BI__builtin_altivec_vpopcntb: 8667 case PPC::BI__builtin_altivec_vpopcnth: 8668 case PPC::BI__builtin_altivec_vpopcntw: 8669 case PPC::BI__builtin_altivec_vpopcntd: { 8670 llvm::Type *ResultType = ConvertType(E->getType()); 8671 Value *X = EmitScalarExpr(E->getArg(0)); 8672 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 8673 return Builder.CreateCall(F, X); 8674 } 8675 // Copy sign 8676 case PPC::BI__builtin_vsx_xvcpsgnsp: 8677 case PPC::BI__builtin_vsx_xvcpsgndp: { 8678 llvm::Type *ResultType = ConvertType(E->getType()); 8679 Value *X = EmitScalarExpr(E->getArg(0)); 8680 Value *Y = EmitScalarExpr(E->getArg(1)); 8681 ID = Intrinsic::copysign; 8682 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8683 return Builder.CreateCall(F, {X, Y}); 8684 } 8685 // Rounding/truncation 8686 case PPC::BI__builtin_vsx_xvrspip: 8687 case PPC::BI__builtin_vsx_xvrdpip: 8688 case PPC::BI__builtin_vsx_xvrdpim: 8689 case PPC::BI__builtin_vsx_xvrspim: 8690 case PPC::BI__builtin_vsx_xvrdpi: 8691 case PPC::BI__builtin_vsx_xvrspi: 8692 case PPC::BI__builtin_vsx_xvrdpic: 8693 case PPC::BI__builtin_vsx_xvrspic: 8694 case PPC::BI__builtin_vsx_xvrdpiz: 8695 case PPC::BI__builtin_vsx_xvrspiz: { 8696 llvm::Type *ResultType = ConvertType(E->getType()); 8697 Value *X = EmitScalarExpr(E->getArg(0)); 8698 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim || 8699 BuiltinID == PPC::BI__builtin_vsx_xvrspim) 8700 ID = Intrinsic::floor; 8701 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi || 8702 BuiltinID == PPC::BI__builtin_vsx_xvrspi) 8703 ID = Intrinsic::round; 8704 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic || 8705 BuiltinID == PPC::BI__builtin_vsx_xvrspic) 8706 ID = Intrinsic::nearbyint; 8707 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip || 8708 BuiltinID == PPC::BI__builtin_vsx_xvrspip) 8709 ID = Intrinsic::ceil; 8710 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz || 8711 BuiltinID == PPC::BI__builtin_vsx_xvrspiz) 8712 ID = Intrinsic::trunc; 8713 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8714 return Builder.CreateCall(F, X); 8715 } 8716 8717 // Absolute value 8718 case PPC::BI__builtin_vsx_xvabsdp: 8719 case PPC::BI__builtin_vsx_xvabssp: { 8720 llvm::Type *ResultType = ConvertType(E->getType()); 8721 Value *X = EmitScalarExpr(E->getArg(0)); 8722 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 8723 return Builder.CreateCall(F, X); 8724 } 8725 8726 // FMA variations 8727 case PPC::BI__builtin_vsx_xvmaddadp: 8728 case PPC::BI__builtin_vsx_xvmaddasp: 8729 case PPC::BI__builtin_vsx_xvnmaddadp: 8730 case PPC::BI__builtin_vsx_xvnmaddasp: 8731 case PPC::BI__builtin_vsx_xvmsubadp: 8732 case PPC::BI__builtin_vsx_xvmsubasp: 8733 case PPC::BI__builtin_vsx_xvnmsubadp: 8734 case PPC::BI__builtin_vsx_xvnmsubasp: { 8735 llvm::Type *ResultType = ConvertType(E->getType()); 8736 Value *X = EmitScalarExpr(E->getArg(0)); 8737 Value *Y = EmitScalarExpr(E->getArg(1)); 8738 Value *Z = EmitScalarExpr(E->getArg(2)); 8739 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 8740 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 8741 switch (BuiltinID) { 8742 case PPC::BI__builtin_vsx_xvmaddadp: 8743 case PPC::BI__builtin_vsx_xvmaddasp: 8744 return Builder.CreateCall(F, {X, Y, Z}); 8745 case PPC::BI__builtin_vsx_xvnmaddadp: 8746 case PPC::BI__builtin_vsx_xvnmaddasp: 8747 return Builder.CreateFSub(Zero, 8748 Builder.CreateCall(F, {X, Y, Z}), "sub"); 8749 case PPC::BI__builtin_vsx_xvmsubadp: 8750 case PPC::BI__builtin_vsx_xvmsubasp: 8751 return Builder.CreateCall(F, 8752 {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8753 case PPC::BI__builtin_vsx_xvnmsubadp: 8754 case PPC::BI__builtin_vsx_xvnmsubasp: 8755 Value *FsubRes = 8756 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8757 return Builder.CreateFSub(Zero, FsubRes, "sub"); 8758 } 8759 llvm_unreachable("Unknown FMA operation"); 8760 return nullptr; // Suppress no-return warning 8761 } 8762 8763 case PPC::BI__builtin_vsx_insertword: { 8764 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw); 8765 8766 // Third argument is a compile time constant int. It must be clamped to 8767 // to the range [0, 12]. 8768 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8769 assert(ArgCI && 8770 "Third arg to xxinsertw intrinsic must be constant integer"); 8771 const int64_t MaxIndex = 12; 8772 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8773 8774 // The builtin semantics don't exactly match the xxinsertw instructions 8775 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the 8776 // word from the first argument, and inserts it in the second argument. The 8777 // instruction extracts the word from its second input register and inserts 8778 // it into its first input register, so swap the first and second arguments. 8779 std::swap(Ops[0], Ops[1]); 8780 8781 // Need to cast the second argument from a vector of unsigned int to a 8782 // vector of long long. 8783 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8784 8785 if (getTarget().isLittleEndian()) { 8786 // Create a shuffle mask of (1, 0) 8787 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8788 ConstantInt::get(Int32Ty, 0) 8789 }; 8790 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8791 8792 // Reverse the double words in the vector we will extract from. 8793 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8794 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask); 8795 8796 // Reverse the index. 8797 Index = MaxIndex - Index; 8798 } 8799 8800 // Intrinsic expects the first arg to be a vector of int. 8801 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8802 Ops[2] = ConstantInt::getSigned(Int32Ty, Index); 8803 return Builder.CreateCall(F, Ops); 8804 } 8805 8806 case PPC::BI__builtin_vsx_extractuword: { 8807 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw); 8808 8809 // Intrinsic expects the first argument to be a vector of doublewords. 8810 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8811 8812 // The second argument is a compile time constant int that needs to 8813 // be clamped to the range [0, 12]. 8814 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]); 8815 assert(ArgCI && 8816 "Second Arg to xxextractuw intrinsic must be a constant integer!"); 8817 const int64_t MaxIndex = 12; 8818 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8819 8820 if (getTarget().isLittleEndian()) { 8821 // Reverse the index. 8822 Index = MaxIndex - Index; 8823 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8824 8825 // Emit the call, then reverse the double words of the results vector. 8826 Value *Call = Builder.CreateCall(F, Ops); 8827 8828 // Create a shuffle mask of (1, 0) 8829 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8830 ConstantInt::get(Int32Ty, 0) 8831 }; 8832 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8833 8834 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask); 8835 return ShuffleCall; 8836 } else { 8837 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8838 return Builder.CreateCall(F, Ops); 8839 } 8840 } 8841 8842 case PPC::BI__builtin_vsx_xxpermdi: { 8843 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8844 assert(ArgCI && "Third arg must be constant integer!"); 8845 8846 unsigned Index = ArgCI->getZExtValue(); 8847 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8848 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8849 8850 // Element zero comes from the first input vector and element one comes from 8851 // the second. The element indices within each vector are numbered in big 8852 // endian order so the shuffle mask must be adjusted for this on little 8853 // endian platforms (i.e. index is complemented and source vector reversed). 8854 unsigned ElemIdx0; 8855 unsigned ElemIdx1; 8856 if (getTarget().isLittleEndian()) { 8857 ElemIdx0 = (~Index & 1) + 2; 8858 ElemIdx1 = (~Index & 2) >> 1; 8859 } else { // BigEndian 8860 ElemIdx0 = (Index & 2) >> 1; 8861 ElemIdx1 = 2 + (Index & 1); 8862 } 8863 8864 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0), 8865 ConstantInt::get(Int32Ty, ElemIdx1)}; 8866 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8867 8868 Value *ShuffleCall = 8869 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8870 QualType BIRetType = E->getType(); 8871 auto RetTy = ConvertType(BIRetType); 8872 return Builder.CreateBitCast(ShuffleCall, RetTy); 8873 } 8874 8875 case PPC::BI__builtin_vsx_xxsldwi: { 8876 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8877 assert(ArgCI && "Third argument must be a compile time constant"); 8878 unsigned Index = ArgCI->getZExtValue() & 0x3; 8879 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8880 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4)); 8881 8882 // Create a shuffle mask 8883 unsigned ElemIdx0; 8884 unsigned ElemIdx1; 8885 unsigned ElemIdx2; 8886 unsigned ElemIdx3; 8887 if (getTarget().isLittleEndian()) { 8888 // Little endian element N comes from element 8+N-Index of the 8889 // concatenated wide vector (of course, using modulo arithmetic on 8890 // the total number of elements). 8891 ElemIdx0 = (8 - Index) % 8; 8892 ElemIdx1 = (9 - Index) % 8; 8893 ElemIdx2 = (10 - Index) % 8; 8894 ElemIdx3 = (11 - Index) % 8; 8895 } else { 8896 // Big endian ElemIdx<N> = Index + N 8897 ElemIdx0 = Index; 8898 ElemIdx1 = Index + 1; 8899 ElemIdx2 = Index + 2; 8900 ElemIdx3 = Index + 3; 8901 } 8902 8903 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0), 8904 ConstantInt::get(Int32Ty, ElemIdx1), 8905 ConstantInt::get(Int32Ty, ElemIdx2), 8906 ConstantInt::get(Int32Ty, ElemIdx3)}; 8907 8908 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8909 Value *ShuffleCall = 8910 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8911 QualType BIRetType = E->getType(); 8912 auto RetTy = ConvertType(BIRetType); 8913 return Builder.CreateBitCast(ShuffleCall, RetTy); 8914 } 8915 } 8916 } 8917 8918 Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, 8919 const CallExpr *E) { 8920 switch (BuiltinID) { 8921 case AMDGPU::BI__builtin_amdgcn_div_scale: 8922 case AMDGPU::BI__builtin_amdgcn_div_scalef: { 8923 // Translate from the intrinsics's struct return to the builtin's out 8924 // argument. 8925 8926 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3)); 8927 8928 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 8929 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 8930 llvm::Value *Z = EmitScalarExpr(E->getArg(2)); 8931 8932 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale, 8933 X->getType()); 8934 8935 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z}); 8936 8937 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0); 8938 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1); 8939 8940 llvm::Type *RealFlagType 8941 = FlagOutPtr.getPointer()->getType()->getPointerElementType(); 8942 8943 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType); 8944 Builder.CreateStore(FlagExt, FlagOutPtr); 8945 return Result; 8946 } 8947 case AMDGPU::BI__builtin_amdgcn_div_fmas: 8948 case AMDGPU::BI__builtin_amdgcn_div_fmasf: { 8949 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0)); 8950 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1)); 8951 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2)); 8952 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3)); 8953 8954 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas, 8955 Src0->getType()); 8956 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3); 8957 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool}); 8958 } 8959 8960 case AMDGPU::BI__builtin_amdgcn_ds_swizzle: 8961 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle); 8962 case AMDGPU::BI__builtin_amdgcn_mov_dpp: { 8963 llvm::SmallVector<llvm::Value *, 5> Args; 8964 for (unsigned I = 0; I != 5; ++I) 8965 Args.push_back(EmitScalarExpr(E->getArg(I))); 8966 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp, 8967 Args[0]->getType()); 8968 return Builder.CreateCall(F, Args); 8969 } 8970 case AMDGPU::BI__builtin_amdgcn_div_fixup: 8971 case AMDGPU::BI__builtin_amdgcn_div_fixupf: 8972 case AMDGPU::BI__builtin_amdgcn_div_fixuph: 8973 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup); 8974 case AMDGPU::BI__builtin_amdgcn_trig_preop: 8975 case AMDGPU::BI__builtin_amdgcn_trig_preopf: 8976 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop); 8977 case AMDGPU::BI__builtin_amdgcn_rcp: 8978 case AMDGPU::BI__builtin_amdgcn_rcpf: 8979 case AMDGPU::BI__builtin_amdgcn_rcph: 8980 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp); 8981 case AMDGPU::BI__builtin_amdgcn_rsq: 8982 case AMDGPU::BI__builtin_amdgcn_rsqf: 8983 case AMDGPU::BI__builtin_amdgcn_rsqh: 8984 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq); 8985 case AMDGPU::BI__builtin_amdgcn_rsq_clamp: 8986 case AMDGPU::BI__builtin_amdgcn_rsq_clampf: 8987 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp); 8988 case AMDGPU::BI__builtin_amdgcn_sinf: 8989 case AMDGPU::BI__builtin_amdgcn_sinh: 8990 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin); 8991 case AMDGPU::BI__builtin_amdgcn_cosf: 8992 case AMDGPU::BI__builtin_amdgcn_cosh: 8993 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos); 8994 case AMDGPU::BI__builtin_amdgcn_log_clampf: 8995 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp); 8996 case AMDGPU::BI__builtin_amdgcn_ldexp: 8997 case AMDGPU::BI__builtin_amdgcn_ldexpf: 8998 case AMDGPU::BI__builtin_amdgcn_ldexph: 8999 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp); 9000 case AMDGPU::BI__builtin_amdgcn_frexp_mant: 9001 case AMDGPU::BI__builtin_amdgcn_frexp_mantf: 9002 case AMDGPU::BI__builtin_amdgcn_frexp_manth: 9003 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant); 9004 case AMDGPU::BI__builtin_amdgcn_frexp_exp: 9005 case AMDGPU::BI__builtin_amdgcn_frexp_expf: { 9006 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9007 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9008 { Builder.getInt32Ty(), Src0->getType() }); 9009 return Builder.CreateCall(F, Src0); 9010 } 9011 case AMDGPU::BI__builtin_amdgcn_frexp_exph: { 9012 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9013 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9014 { Builder.getInt16Ty(), Src0->getType() }); 9015 return Builder.CreateCall(F, Src0); 9016 } 9017 case AMDGPU::BI__builtin_amdgcn_fract: 9018 case AMDGPU::BI__builtin_amdgcn_fractf: 9019 case AMDGPU::BI__builtin_amdgcn_fracth: 9020 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract); 9021 case AMDGPU::BI__builtin_amdgcn_lerp: 9022 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp); 9023 case AMDGPU::BI__builtin_amdgcn_uicmp: 9024 case AMDGPU::BI__builtin_amdgcn_uicmpl: 9025 case AMDGPU::BI__builtin_amdgcn_sicmp: 9026 case AMDGPU::BI__builtin_amdgcn_sicmpl: 9027 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp); 9028 case AMDGPU::BI__builtin_amdgcn_fcmp: 9029 case AMDGPU::BI__builtin_amdgcn_fcmpf: 9030 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp); 9031 case AMDGPU::BI__builtin_amdgcn_class: 9032 case AMDGPU::BI__builtin_amdgcn_classf: 9033 case AMDGPU::BI__builtin_amdgcn_classh: 9034 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class); 9035 case AMDGPU::BI__builtin_amdgcn_fmed3f: 9036 case AMDGPU::BI__builtin_amdgcn_fmed3h: 9037 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3); 9038 case AMDGPU::BI__builtin_amdgcn_read_exec: { 9039 CallInst *CI = cast<CallInst>( 9040 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec")); 9041 CI->setConvergent(); 9042 return CI; 9043 } 9044 case AMDGPU::BI__builtin_amdgcn_read_exec_lo: 9045 case AMDGPU::BI__builtin_amdgcn_read_exec_hi: { 9046 StringRef RegName = BuiltinID == AMDGPU::BI__builtin_amdgcn_read_exec_lo ? 9047 "exec_lo" : "exec_hi"; 9048 CallInst *CI = cast<CallInst>( 9049 EmitSpecialRegisterBuiltin(*this, E, Int32Ty, Int32Ty, true, RegName)); 9050 CI->setConvergent(); 9051 return CI; 9052 } 9053 9054 // amdgcn workitem 9055 case AMDGPU::BI__builtin_amdgcn_workitem_id_x: 9056 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024); 9057 case AMDGPU::BI__builtin_amdgcn_workitem_id_y: 9058 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024); 9059 case AMDGPU::BI__builtin_amdgcn_workitem_id_z: 9060 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024); 9061 9062 // r600 intrinsics 9063 case AMDGPU::BI__builtin_r600_recipsqrt_ieee: 9064 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef: 9065 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee); 9066 case AMDGPU::BI__builtin_r600_read_tidig_x: 9067 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024); 9068 case AMDGPU::BI__builtin_r600_read_tidig_y: 9069 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024); 9070 case AMDGPU::BI__builtin_r600_read_tidig_z: 9071 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024); 9072 default: 9073 return nullptr; 9074 } 9075 } 9076 9077 /// Handle a SystemZ function in which the final argument is a pointer 9078 /// to an int that receives the post-instruction CC value. At the LLVM level 9079 /// this is represented as a function that returns a {result, cc} pair. 9080 static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF, 9081 unsigned IntrinsicID, 9082 const CallExpr *E) { 9083 unsigned NumArgs = E->getNumArgs() - 1; 9084 SmallVector<Value *, 8> Args(NumArgs); 9085 for (unsigned I = 0; I < NumArgs; ++I) 9086 Args[I] = CGF.EmitScalarExpr(E->getArg(I)); 9087 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs)); 9088 Value *F = CGF.CGM.getIntrinsic(IntrinsicID); 9089 Value *Call = CGF.Builder.CreateCall(F, Args); 9090 Value *CC = CGF.Builder.CreateExtractValue(Call, 1); 9091 CGF.Builder.CreateStore(CC, CCPtr); 9092 return CGF.Builder.CreateExtractValue(Call, 0); 9093 } 9094 9095 Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, 9096 const CallExpr *E) { 9097 switch (BuiltinID) { 9098 case SystemZ::BI__builtin_tbegin: { 9099 Value *TDB = EmitScalarExpr(E->getArg(0)); 9100 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9101 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin); 9102 return Builder.CreateCall(F, {TDB, Control}); 9103 } 9104 case SystemZ::BI__builtin_tbegin_nofloat: { 9105 Value *TDB = EmitScalarExpr(E->getArg(0)); 9106 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9107 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat); 9108 return Builder.CreateCall(F, {TDB, Control}); 9109 } 9110 case SystemZ::BI__builtin_tbeginc: { 9111 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy); 9112 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08); 9113 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc); 9114 return Builder.CreateCall(F, {TDB, Control}); 9115 } 9116 case SystemZ::BI__builtin_tabort: { 9117 Value *Data = EmitScalarExpr(E->getArg(0)); 9118 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort); 9119 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort")); 9120 } 9121 case SystemZ::BI__builtin_non_tx_store: { 9122 Value *Address = EmitScalarExpr(E->getArg(0)); 9123 Value *Data = EmitScalarExpr(E->getArg(1)); 9124 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); 9125 return Builder.CreateCall(F, {Data, Address}); 9126 } 9127 9128 // Vector builtins. Note that most vector builtins are mapped automatically 9129 // to target-specific LLVM intrinsics. The ones handled specially here can 9130 // be represented via standard LLVM IR, which is preferable to enable common 9131 // LLVM optimizations. 9132 9133 case SystemZ::BI__builtin_s390_vpopctb: 9134 case SystemZ::BI__builtin_s390_vpopcth: 9135 case SystemZ::BI__builtin_s390_vpopctf: 9136 case SystemZ::BI__builtin_s390_vpopctg: { 9137 llvm::Type *ResultType = ConvertType(E->getType()); 9138 Value *X = EmitScalarExpr(E->getArg(0)); 9139 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 9140 return Builder.CreateCall(F, X); 9141 } 9142 9143 case SystemZ::BI__builtin_s390_vclzb: 9144 case SystemZ::BI__builtin_s390_vclzh: 9145 case SystemZ::BI__builtin_s390_vclzf: 9146 case SystemZ::BI__builtin_s390_vclzg: { 9147 llvm::Type *ResultType = ConvertType(E->getType()); 9148 Value *X = EmitScalarExpr(E->getArg(0)); 9149 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9150 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 9151 return Builder.CreateCall(F, {X, Undef}); 9152 } 9153 9154 case SystemZ::BI__builtin_s390_vctzb: 9155 case SystemZ::BI__builtin_s390_vctzh: 9156 case SystemZ::BI__builtin_s390_vctzf: 9157 case SystemZ::BI__builtin_s390_vctzg: { 9158 llvm::Type *ResultType = ConvertType(E->getType()); 9159 Value *X = EmitScalarExpr(E->getArg(0)); 9160 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9161 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 9162 return Builder.CreateCall(F, {X, Undef}); 9163 } 9164 9165 case SystemZ::BI__builtin_s390_vfsqsb: 9166 case SystemZ::BI__builtin_s390_vfsqdb: { 9167 llvm::Type *ResultType = ConvertType(E->getType()); 9168 Value *X = EmitScalarExpr(E->getArg(0)); 9169 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType); 9170 return Builder.CreateCall(F, X); 9171 } 9172 case SystemZ::BI__builtin_s390_vfmasb: 9173 case SystemZ::BI__builtin_s390_vfmadb: { 9174 llvm::Type *ResultType = ConvertType(E->getType()); 9175 Value *X = EmitScalarExpr(E->getArg(0)); 9176 Value *Y = EmitScalarExpr(E->getArg(1)); 9177 Value *Z = EmitScalarExpr(E->getArg(2)); 9178 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9179 return Builder.CreateCall(F, {X, Y, Z}); 9180 } 9181 case SystemZ::BI__builtin_s390_vfmssb: 9182 case SystemZ::BI__builtin_s390_vfmsdb: { 9183 llvm::Type *ResultType = ConvertType(E->getType()); 9184 Value *X = EmitScalarExpr(E->getArg(0)); 9185 Value *Y = EmitScalarExpr(E->getArg(1)); 9186 Value *Z = EmitScalarExpr(E->getArg(2)); 9187 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9188 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9189 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 9190 } 9191 case SystemZ::BI__builtin_s390_vfnmasb: 9192 case SystemZ::BI__builtin_s390_vfnmadb: { 9193 llvm::Type *ResultType = ConvertType(E->getType()); 9194 Value *X = EmitScalarExpr(E->getArg(0)); 9195 Value *Y = EmitScalarExpr(E->getArg(1)); 9196 Value *Z = EmitScalarExpr(E->getArg(2)); 9197 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9198 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9199 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub"); 9200 } 9201 case SystemZ::BI__builtin_s390_vfnmssb: 9202 case SystemZ::BI__builtin_s390_vfnmsdb: { 9203 llvm::Type *ResultType = ConvertType(E->getType()); 9204 Value *X = EmitScalarExpr(E->getArg(0)); 9205 Value *Y = EmitScalarExpr(E->getArg(1)); 9206 Value *Z = EmitScalarExpr(E->getArg(2)); 9207 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9208 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9209 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub"); 9210 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ})); 9211 } 9212 case SystemZ::BI__builtin_s390_vflpsb: 9213 case SystemZ::BI__builtin_s390_vflpdb: { 9214 llvm::Type *ResultType = ConvertType(E->getType()); 9215 Value *X = EmitScalarExpr(E->getArg(0)); 9216 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9217 return Builder.CreateCall(F, X); 9218 } 9219 case SystemZ::BI__builtin_s390_vflnsb: 9220 case SystemZ::BI__builtin_s390_vflndb: { 9221 llvm::Type *ResultType = ConvertType(E->getType()); 9222 Value *X = EmitScalarExpr(E->getArg(0)); 9223 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9224 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9225 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub"); 9226 } 9227 case SystemZ::BI__builtin_s390_vfisb: 9228 case SystemZ::BI__builtin_s390_vfidb: { 9229 llvm::Type *ResultType = ConvertType(E->getType()); 9230 Value *X = EmitScalarExpr(E->getArg(0)); 9231 // Constant-fold the M4 and M5 mask arguments. 9232 llvm::APSInt M4, M5; 9233 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext()); 9234 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext()); 9235 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?"); 9236 (void)IsConstM4; (void)IsConstM5; 9237 // Check whether this instance can be represented via a LLVM standard 9238 // intrinsic. We only support some combinations of M4 and M5. 9239 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9240 switch (M4.getZExtValue()) { 9241 default: break; 9242 case 0: // IEEE-inexact exception allowed 9243 switch (M5.getZExtValue()) { 9244 default: break; 9245 case 0: ID = Intrinsic::rint; break; 9246 } 9247 break; 9248 case 4: // IEEE-inexact exception suppressed 9249 switch (M5.getZExtValue()) { 9250 default: break; 9251 case 0: ID = Intrinsic::nearbyint; break; 9252 case 1: ID = Intrinsic::round; break; 9253 case 5: ID = Intrinsic::trunc; break; 9254 case 6: ID = Intrinsic::ceil; break; 9255 case 7: ID = Intrinsic::floor; break; 9256 } 9257 break; 9258 } 9259 if (ID != Intrinsic::not_intrinsic) { 9260 Function *F = CGM.getIntrinsic(ID, ResultType); 9261 return Builder.CreateCall(F, X); 9262 } 9263 switch (BuiltinID) { 9264 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break; 9265 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break; 9266 default: llvm_unreachable("Unknown BuiltinID"); 9267 } 9268 Function *F = CGM.getIntrinsic(ID); 9269 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9270 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5); 9271 return Builder.CreateCall(F, {X, M4Value, M5Value}); 9272 } 9273 case SystemZ::BI__builtin_s390_vfmaxsb: 9274 case SystemZ::BI__builtin_s390_vfmaxdb: { 9275 llvm::Type *ResultType = ConvertType(E->getType()); 9276 Value *X = EmitScalarExpr(E->getArg(0)); 9277 Value *Y = EmitScalarExpr(E->getArg(1)); 9278 // Constant-fold the M4 mask argument. 9279 llvm::APSInt M4; 9280 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9281 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9282 (void)IsConstM4; 9283 // Check whether this instance can be represented via a LLVM standard 9284 // intrinsic. We only support some values of M4. 9285 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9286 switch (M4.getZExtValue()) { 9287 default: break; 9288 case 4: ID = Intrinsic::maxnum; break; 9289 } 9290 if (ID != Intrinsic::not_intrinsic) { 9291 Function *F = CGM.getIntrinsic(ID, ResultType); 9292 return Builder.CreateCall(F, {X, Y}); 9293 } 9294 switch (BuiltinID) { 9295 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break; 9296 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break; 9297 default: llvm_unreachable("Unknown BuiltinID"); 9298 } 9299 Function *F = CGM.getIntrinsic(ID); 9300 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9301 return Builder.CreateCall(F, {X, Y, M4Value}); 9302 } 9303 case SystemZ::BI__builtin_s390_vfminsb: 9304 case SystemZ::BI__builtin_s390_vfmindb: { 9305 llvm::Type *ResultType = ConvertType(E->getType()); 9306 Value *X = EmitScalarExpr(E->getArg(0)); 9307 Value *Y = EmitScalarExpr(E->getArg(1)); 9308 // Constant-fold the M4 mask argument. 9309 llvm::APSInt M4; 9310 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9311 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9312 (void)IsConstM4; 9313 // Check whether this instance can be represented via a LLVM standard 9314 // intrinsic. We only support some values of M4. 9315 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9316 switch (M4.getZExtValue()) { 9317 default: break; 9318 case 4: ID = Intrinsic::minnum; break; 9319 } 9320 if (ID != Intrinsic::not_intrinsic) { 9321 Function *F = CGM.getIntrinsic(ID, ResultType); 9322 return Builder.CreateCall(F, {X, Y}); 9323 } 9324 switch (BuiltinID) { 9325 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break; 9326 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break; 9327 default: llvm_unreachable("Unknown BuiltinID"); 9328 } 9329 Function *F = CGM.getIntrinsic(ID); 9330 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9331 return Builder.CreateCall(F, {X, Y, M4Value}); 9332 } 9333 9334 // Vector intrisincs that output the post-instruction CC value. 9335 9336 #define INTRINSIC_WITH_CC(NAME) \ 9337 case SystemZ::BI__builtin_##NAME: \ 9338 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E) 9339 9340 INTRINSIC_WITH_CC(s390_vpkshs); 9341 INTRINSIC_WITH_CC(s390_vpksfs); 9342 INTRINSIC_WITH_CC(s390_vpksgs); 9343 9344 INTRINSIC_WITH_CC(s390_vpklshs); 9345 INTRINSIC_WITH_CC(s390_vpklsfs); 9346 INTRINSIC_WITH_CC(s390_vpklsgs); 9347 9348 INTRINSIC_WITH_CC(s390_vceqbs); 9349 INTRINSIC_WITH_CC(s390_vceqhs); 9350 INTRINSIC_WITH_CC(s390_vceqfs); 9351 INTRINSIC_WITH_CC(s390_vceqgs); 9352 9353 INTRINSIC_WITH_CC(s390_vchbs); 9354 INTRINSIC_WITH_CC(s390_vchhs); 9355 INTRINSIC_WITH_CC(s390_vchfs); 9356 INTRINSIC_WITH_CC(s390_vchgs); 9357 9358 INTRINSIC_WITH_CC(s390_vchlbs); 9359 INTRINSIC_WITH_CC(s390_vchlhs); 9360 INTRINSIC_WITH_CC(s390_vchlfs); 9361 INTRINSIC_WITH_CC(s390_vchlgs); 9362 9363 INTRINSIC_WITH_CC(s390_vfaebs); 9364 INTRINSIC_WITH_CC(s390_vfaehs); 9365 INTRINSIC_WITH_CC(s390_vfaefs); 9366 9367 INTRINSIC_WITH_CC(s390_vfaezbs); 9368 INTRINSIC_WITH_CC(s390_vfaezhs); 9369 INTRINSIC_WITH_CC(s390_vfaezfs); 9370 9371 INTRINSIC_WITH_CC(s390_vfeebs); 9372 INTRINSIC_WITH_CC(s390_vfeehs); 9373 INTRINSIC_WITH_CC(s390_vfeefs); 9374 9375 INTRINSIC_WITH_CC(s390_vfeezbs); 9376 INTRINSIC_WITH_CC(s390_vfeezhs); 9377 INTRINSIC_WITH_CC(s390_vfeezfs); 9378 9379 INTRINSIC_WITH_CC(s390_vfenebs); 9380 INTRINSIC_WITH_CC(s390_vfenehs); 9381 INTRINSIC_WITH_CC(s390_vfenefs); 9382 9383 INTRINSIC_WITH_CC(s390_vfenezbs); 9384 INTRINSIC_WITH_CC(s390_vfenezhs); 9385 INTRINSIC_WITH_CC(s390_vfenezfs); 9386 9387 INTRINSIC_WITH_CC(s390_vistrbs); 9388 INTRINSIC_WITH_CC(s390_vistrhs); 9389 INTRINSIC_WITH_CC(s390_vistrfs); 9390 9391 INTRINSIC_WITH_CC(s390_vstrcbs); 9392 INTRINSIC_WITH_CC(s390_vstrchs); 9393 INTRINSIC_WITH_CC(s390_vstrcfs); 9394 9395 INTRINSIC_WITH_CC(s390_vstrczbs); 9396 INTRINSIC_WITH_CC(s390_vstrczhs); 9397 INTRINSIC_WITH_CC(s390_vstrczfs); 9398 9399 INTRINSIC_WITH_CC(s390_vfcesbs); 9400 INTRINSIC_WITH_CC(s390_vfcedbs); 9401 INTRINSIC_WITH_CC(s390_vfchsbs); 9402 INTRINSIC_WITH_CC(s390_vfchdbs); 9403 INTRINSIC_WITH_CC(s390_vfchesbs); 9404 INTRINSIC_WITH_CC(s390_vfchedbs); 9405 9406 INTRINSIC_WITH_CC(s390_vftcisb); 9407 INTRINSIC_WITH_CC(s390_vftcidb); 9408 9409 #undef INTRINSIC_WITH_CC 9410 9411 default: 9412 return nullptr; 9413 } 9414 } 9415 9416 Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, 9417 const CallExpr *E) { 9418 auto MakeLdg = [&](unsigned IntrinsicID) { 9419 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9420 clang::CharUnits Align = 9421 getNaturalPointeeTypeAlignment(E->getArg(0)->getType()); 9422 return Builder.CreateCall( 9423 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9424 Ptr->getType()}), 9425 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())}); 9426 }; 9427 auto MakeScopedAtomic = [&](unsigned IntrinsicID) { 9428 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9429 return Builder.CreateCall( 9430 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9431 Ptr->getType()}), 9432 {Ptr, EmitScalarExpr(E->getArg(1))}); 9433 }; 9434 switch (BuiltinID) { 9435 case NVPTX::BI__nvvm_atom_add_gen_i: 9436 case NVPTX::BI__nvvm_atom_add_gen_l: 9437 case NVPTX::BI__nvvm_atom_add_gen_ll: 9438 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E); 9439 9440 case NVPTX::BI__nvvm_atom_sub_gen_i: 9441 case NVPTX::BI__nvvm_atom_sub_gen_l: 9442 case NVPTX::BI__nvvm_atom_sub_gen_ll: 9443 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E); 9444 9445 case NVPTX::BI__nvvm_atom_and_gen_i: 9446 case NVPTX::BI__nvvm_atom_and_gen_l: 9447 case NVPTX::BI__nvvm_atom_and_gen_ll: 9448 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E); 9449 9450 case NVPTX::BI__nvvm_atom_or_gen_i: 9451 case NVPTX::BI__nvvm_atom_or_gen_l: 9452 case NVPTX::BI__nvvm_atom_or_gen_ll: 9453 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E); 9454 9455 case NVPTX::BI__nvvm_atom_xor_gen_i: 9456 case NVPTX::BI__nvvm_atom_xor_gen_l: 9457 case NVPTX::BI__nvvm_atom_xor_gen_ll: 9458 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E); 9459 9460 case NVPTX::BI__nvvm_atom_xchg_gen_i: 9461 case NVPTX::BI__nvvm_atom_xchg_gen_l: 9462 case NVPTX::BI__nvvm_atom_xchg_gen_ll: 9463 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E); 9464 9465 case NVPTX::BI__nvvm_atom_max_gen_i: 9466 case NVPTX::BI__nvvm_atom_max_gen_l: 9467 case NVPTX::BI__nvvm_atom_max_gen_ll: 9468 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E); 9469 9470 case NVPTX::BI__nvvm_atom_max_gen_ui: 9471 case NVPTX::BI__nvvm_atom_max_gen_ul: 9472 case NVPTX::BI__nvvm_atom_max_gen_ull: 9473 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E); 9474 9475 case NVPTX::BI__nvvm_atom_min_gen_i: 9476 case NVPTX::BI__nvvm_atom_min_gen_l: 9477 case NVPTX::BI__nvvm_atom_min_gen_ll: 9478 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E); 9479 9480 case NVPTX::BI__nvvm_atom_min_gen_ui: 9481 case NVPTX::BI__nvvm_atom_min_gen_ul: 9482 case NVPTX::BI__nvvm_atom_min_gen_ull: 9483 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E); 9484 9485 case NVPTX::BI__nvvm_atom_cas_gen_i: 9486 case NVPTX::BI__nvvm_atom_cas_gen_l: 9487 case NVPTX::BI__nvvm_atom_cas_gen_ll: 9488 // __nvvm_atom_cas_gen_* should return the old value rather than the 9489 // success flag. 9490 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false); 9491 9492 case NVPTX::BI__nvvm_atom_add_gen_f: { 9493 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9494 Value *Val = EmitScalarExpr(E->getArg(1)); 9495 // atomicrmw only deals with integer arguments so we need to use 9496 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that. 9497 Value *FnALAF32 = 9498 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType()); 9499 return Builder.CreateCall(FnALAF32, {Ptr, Val}); 9500 } 9501 9502 case NVPTX::BI__nvvm_atom_add_gen_d: { 9503 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9504 Value *Val = EmitScalarExpr(E->getArg(1)); 9505 // atomicrmw only deals with integer arguments, so we need to use 9506 // LLVM's nvvm_atomic_load_add_f64 intrinsic. 9507 Value *FnALAF64 = 9508 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f64, Ptr->getType()); 9509 return Builder.CreateCall(FnALAF64, {Ptr, Val}); 9510 } 9511 9512 case NVPTX::BI__nvvm_atom_inc_gen_ui: { 9513 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9514 Value *Val = EmitScalarExpr(E->getArg(1)); 9515 Value *FnALI32 = 9516 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType()); 9517 return Builder.CreateCall(FnALI32, {Ptr, Val}); 9518 } 9519 9520 case NVPTX::BI__nvvm_atom_dec_gen_ui: { 9521 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9522 Value *Val = EmitScalarExpr(E->getArg(1)); 9523 Value *FnALD32 = 9524 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType()); 9525 return Builder.CreateCall(FnALD32, {Ptr, Val}); 9526 } 9527 9528 case NVPTX::BI__nvvm_ldg_c: 9529 case NVPTX::BI__nvvm_ldg_c2: 9530 case NVPTX::BI__nvvm_ldg_c4: 9531 case NVPTX::BI__nvvm_ldg_s: 9532 case NVPTX::BI__nvvm_ldg_s2: 9533 case NVPTX::BI__nvvm_ldg_s4: 9534 case NVPTX::BI__nvvm_ldg_i: 9535 case NVPTX::BI__nvvm_ldg_i2: 9536 case NVPTX::BI__nvvm_ldg_i4: 9537 case NVPTX::BI__nvvm_ldg_l: 9538 case NVPTX::BI__nvvm_ldg_ll: 9539 case NVPTX::BI__nvvm_ldg_ll2: 9540 case NVPTX::BI__nvvm_ldg_uc: 9541 case NVPTX::BI__nvvm_ldg_uc2: 9542 case NVPTX::BI__nvvm_ldg_uc4: 9543 case NVPTX::BI__nvvm_ldg_us: 9544 case NVPTX::BI__nvvm_ldg_us2: 9545 case NVPTX::BI__nvvm_ldg_us4: 9546 case NVPTX::BI__nvvm_ldg_ui: 9547 case NVPTX::BI__nvvm_ldg_ui2: 9548 case NVPTX::BI__nvvm_ldg_ui4: 9549 case NVPTX::BI__nvvm_ldg_ul: 9550 case NVPTX::BI__nvvm_ldg_ull: 9551 case NVPTX::BI__nvvm_ldg_ull2: 9552 // PTX Interoperability section 2.2: "For a vector with an even number of 9553 // elements, its alignment is set to number of elements times the alignment 9554 // of its member: n*alignof(t)." 9555 return MakeLdg(Intrinsic::nvvm_ldg_global_i); 9556 case NVPTX::BI__nvvm_ldg_f: 9557 case NVPTX::BI__nvvm_ldg_f2: 9558 case NVPTX::BI__nvvm_ldg_f4: 9559 case NVPTX::BI__nvvm_ldg_d: 9560 case NVPTX::BI__nvvm_ldg_d2: 9561 return MakeLdg(Intrinsic::nvvm_ldg_global_f); 9562 9563 case NVPTX::BI__nvvm_atom_cta_add_gen_i: 9564 case NVPTX::BI__nvvm_atom_cta_add_gen_l: 9565 case NVPTX::BI__nvvm_atom_cta_add_gen_ll: 9566 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta); 9567 case NVPTX::BI__nvvm_atom_sys_add_gen_i: 9568 case NVPTX::BI__nvvm_atom_sys_add_gen_l: 9569 case NVPTX::BI__nvvm_atom_sys_add_gen_ll: 9570 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys); 9571 case NVPTX::BI__nvvm_atom_cta_add_gen_f: 9572 case NVPTX::BI__nvvm_atom_cta_add_gen_d: 9573 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta); 9574 case NVPTX::BI__nvvm_atom_sys_add_gen_f: 9575 case NVPTX::BI__nvvm_atom_sys_add_gen_d: 9576 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys); 9577 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i: 9578 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l: 9579 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll: 9580 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta); 9581 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i: 9582 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l: 9583 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll: 9584 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys); 9585 case NVPTX::BI__nvvm_atom_cta_max_gen_i: 9586 case NVPTX::BI__nvvm_atom_cta_max_gen_ui: 9587 case NVPTX::BI__nvvm_atom_cta_max_gen_l: 9588 case NVPTX::BI__nvvm_atom_cta_max_gen_ul: 9589 case NVPTX::BI__nvvm_atom_cta_max_gen_ll: 9590 case NVPTX::BI__nvvm_atom_cta_max_gen_ull: 9591 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta); 9592 case NVPTX::BI__nvvm_atom_sys_max_gen_i: 9593 case NVPTX::BI__nvvm_atom_sys_max_gen_ui: 9594 case NVPTX::BI__nvvm_atom_sys_max_gen_l: 9595 case NVPTX::BI__nvvm_atom_sys_max_gen_ul: 9596 case NVPTX::BI__nvvm_atom_sys_max_gen_ll: 9597 case NVPTX::BI__nvvm_atom_sys_max_gen_ull: 9598 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys); 9599 case NVPTX::BI__nvvm_atom_cta_min_gen_i: 9600 case NVPTX::BI__nvvm_atom_cta_min_gen_ui: 9601 case NVPTX::BI__nvvm_atom_cta_min_gen_l: 9602 case NVPTX::BI__nvvm_atom_cta_min_gen_ul: 9603 case NVPTX::BI__nvvm_atom_cta_min_gen_ll: 9604 case NVPTX::BI__nvvm_atom_cta_min_gen_ull: 9605 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta); 9606 case NVPTX::BI__nvvm_atom_sys_min_gen_i: 9607 case NVPTX::BI__nvvm_atom_sys_min_gen_ui: 9608 case NVPTX::BI__nvvm_atom_sys_min_gen_l: 9609 case NVPTX::BI__nvvm_atom_sys_min_gen_ul: 9610 case NVPTX::BI__nvvm_atom_sys_min_gen_ll: 9611 case NVPTX::BI__nvvm_atom_sys_min_gen_ull: 9612 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys); 9613 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui: 9614 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta); 9615 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui: 9616 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta); 9617 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui: 9618 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys); 9619 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui: 9620 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys); 9621 case NVPTX::BI__nvvm_atom_cta_and_gen_i: 9622 case NVPTX::BI__nvvm_atom_cta_and_gen_l: 9623 case NVPTX::BI__nvvm_atom_cta_and_gen_ll: 9624 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta); 9625 case NVPTX::BI__nvvm_atom_sys_and_gen_i: 9626 case NVPTX::BI__nvvm_atom_sys_and_gen_l: 9627 case NVPTX::BI__nvvm_atom_sys_and_gen_ll: 9628 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys); 9629 case NVPTX::BI__nvvm_atom_cta_or_gen_i: 9630 case NVPTX::BI__nvvm_atom_cta_or_gen_l: 9631 case NVPTX::BI__nvvm_atom_cta_or_gen_ll: 9632 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta); 9633 case NVPTX::BI__nvvm_atom_sys_or_gen_i: 9634 case NVPTX::BI__nvvm_atom_sys_or_gen_l: 9635 case NVPTX::BI__nvvm_atom_sys_or_gen_ll: 9636 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys); 9637 case NVPTX::BI__nvvm_atom_cta_xor_gen_i: 9638 case NVPTX::BI__nvvm_atom_cta_xor_gen_l: 9639 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll: 9640 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta); 9641 case NVPTX::BI__nvvm_atom_sys_xor_gen_i: 9642 case NVPTX::BI__nvvm_atom_sys_xor_gen_l: 9643 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll: 9644 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys); 9645 case NVPTX::BI__nvvm_atom_cta_cas_gen_i: 9646 case NVPTX::BI__nvvm_atom_cta_cas_gen_l: 9647 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: { 9648 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9649 return Builder.CreateCall( 9650 CGM.getIntrinsic( 9651 Intrinsic::nvvm_atomic_cas_gen_i_cta, 9652 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9653 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9654 } 9655 case NVPTX::BI__nvvm_atom_sys_cas_gen_i: 9656 case NVPTX::BI__nvvm_atom_sys_cas_gen_l: 9657 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: { 9658 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9659 return Builder.CreateCall( 9660 CGM.getIntrinsic( 9661 Intrinsic::nvvm_atomic_cas_gen_i_sys, 9662 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9663 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9664 } 9665 case NVPTX::BI__nvvm_match_all_sync_i32p: 9666 case NVPTX::BI__nvvm_match_all_sync_i64p: { 9667 Value *Mask = EmitScalarExpr(E->getArg(0)); 9668 Value *Val = EmitScalarExpr(E->getArg(1)); 9669 Address PredOutPtr = EmitPointerWithAlignment(E->getArg(2)); 9670 Value *ResultPair = Builder.CreateCall( 9671 CGM.getIntrinsic(BuiltinID == NVPTX::BI__nvvm_match_all_sync_i32p 9672 ? Intrinsic::nvvm_match_all_sync_i32p 9673 : Intrinsic::nvvm_match_all_sync_i64p), 9674 {Mask, Val}); 9675 Value *Pred = Builder.CreateZExt(Builder.CreateExtractValue(ResultPair, 1), 9676 PredOutPtr.getElementType()); 9677 Builder.CreateStore(Pred, PredOutPtr); 9678 return Builder.CreateExtractValue(ResultPair, 0); 9679 } 9680 case NVPTX::BI__hmma_m16n16k16_ld_a: 9681 case NVPTX::BI__hmma_m16n16k16_ld_b: 9682 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9683 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: { 9684 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9685 Value *Src = EmitScalarExpr(E->getArg(1)); 9686 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9687 llvm::APSInt isColMajorArg; 9688 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9689 return nullptr; 9690 bool isColMajor = isColMajorArg.getSExtValue(); 9691 unsigned IID; 9692 unsigned NumResults; 9693 switch (BuiltinID) { 9694 case NVPTX::BI__hmma_m16n16k16_ld_a: 9695 IID = isColMajor ? Intrinsic::nvvm_wmma_load_a_f16_col_stride 9696 : Intrinsic::nvvm_wmma_load_a_f16_row_stride; 9697 NumResults = 8; 9698 break; 9699 case NVPTX::BI__hmma_m16n16k16_ld_b: 9700 IID = isColMajor ? Intrinsic::nvvm_wmma_load_b_f16_col_stride 9701 : Intrinsic::nvvm_wmma_load_b_f16_row_stride; 9702 NumResults = 8; 9703 break; 9704 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9705 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f16_col_stride 9706 : Intrinsic::nvvm_wmma_load_c_f16_row_stride; 9707 NumResults = 4; 9708 break; 9709 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: 9710 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f32_col_stride 9711 : Intrinsic::nvvm_wmma_load_c_f32_row_stride; 9712 NumResults = 8; 9713 break; 9714 default: 9715 llvm_unreachable("Unexpected builtin ID."); 9716 } 9717 Value *Result = 9718 Builder.CreateCall(CGM.getIntrinsic(IID), 9719 {Builder.CreatePointerCast(Src, VoidPtrTy), Ldm}); 9720 9721 // Save returned values. 9722 for (unsigned i = 0; i < NumResults; ++i) { 9723 Builder.CreateAlignedStore( 9724 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), 9725 Dst.getElementType()), 9726 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9727 CharUnits::fromQuantity(4)); 9728 } 9729 return Result; 9730 } 9731 9732 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9733 case NVPTX::BI__hmma_m16n16k16_st_c_f32: { 9734 Value *Dst = EmitScalarExpr(E->getArg(0)); 9735 Address Src = EmitPointerWithAlignment(E->getArg(1)); 9736 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9737 llvm::APSInt isColMajorArg; 9738 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9739 return nullptr; 9740 bool isColMajor = isColMajorArg.getSExtValue(); 9741 unsigned IID; 9742 unsigned NumResults = 8; 9743 // PTX Instructions (and LLVM instrinsics) are defined for slice _d_, yet 9744 // for some reason nvcc builtins use _c_. 9745 switch (BuiltinID) { 9746 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9747 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f16_col_stride 9748 : Intrinsic::nvvm_wmma_store_d_f16_row_stride; 9749 NumResults = 4; 9750 break; 9751 case NVPTX::BI__hmma_m16n16k16_st_c_f32: 9752 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f32_col_stride 9753 : Intrinsic::nvvm_wmma_store_d_f32_row_stride; 9754 break; 9755 default: 9756 llvm_unreachable("Unexpected builtin ID."); 9757 } 9758 Function *Intrinsic = CGM.getIntrinsic(IID); 9759 llvm::Type *ParamType = Intrinsic->getFunctionType()->getParamType(1); 9760 SmallVector<Value *, 10> Values; 9761 Values.push_back(Builder.CreatePointerCast(Dst, VoidPtrTy)); 9762 for (unsigned i = 0; i < NumResults; ++i) { 9763 Value *V = Builder.CreateAlignedLoad( 9764 Builder.CreateGEP(Src.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9765 CharUnits::fromQuantity(4)); 9766 Values.push_back(Builder.CreateBitCast(V, ParamType)); 9767 } 9768 Values.push_back(Ldm); 9769 Value *Result = Builder.CreateCall(Intrinsic, Values); 9770 return Result; 9771 } 9772 9773 // BI__hmma_m16n16k16_mma_<Dtype><CType>(d, a, b, c, layout, satf) 9774 // --> Intrinsic::nvvm_wmma_mma_sync<layout A,B><DType><CType><Satf> 9775 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9776 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9777 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9778 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: { 9779 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9780 Address SrcA = EmitPointerWithAlignment(E->getArg(1)); 9781 Address SrcB = EmitPointerWithAlignment(E->getArg(2)); 9782 Address SrcC = EmitPointerWithAlignment(E->getArg(3)); 9783 llvm::APSInt LayoutArg; 9784 if (!E->getArg(4)->isIntegerConstantExpr(LayoutArg, getContext())) 9785 return nullptr; 9786 int Layout = LayoutArg.getSExtValue(); 9787 if (Layout < 0 || Layout > 3) 9788 return nullptr; 9789 llvm::APSInt SatfArg; 9790 if (!E->getArg(5)->isIntegerConstantExpr(SatfArg, getContext())) 9791 return nullptr; 9792 bool Satf = SatfArg.getSExtValue(); 9793 9794 // clang-format off 9795 #define MMA_VARIANTS(type) {{ \ 9796 Intrinsic::nvvm_wmma_mma_sync_row_row_##type, \ 9797 Intrinsic::nvvm_wmma_mma_sync_row_row_##type##_satfinite, \ 9798 Intrinsic::nvvm_wmma_mma_sync_row_col_##type, \ 9799 Intrinsic::nvvm_wmma_mma_sync_row_col_##type##_satfinite, \ 9800 Intrinsic::nvvm_wmma_mma_sync_col_row_##type, \ 9801 Intrinsic::nvvm_wmma_mma_sync_col_row_##type##_satfinite, \ 9802 Intrinsic::nvvm_wmma_mma_sync_col_col_##type, \ 9803 Intrinsic::nvvm_wmma_mma_sync_col_col_##type##_satfinite \ 9804 }} 9805 // clang-format on 9806 9807 auto getMMAIntrinsic = [Layout, Satf](std::array<unsigned, 8> Variants) { 9808 unsigned Index = Layout * 2 + Satf; 9809 assert(Index < 8); 9810 return Variants[Index]; 9811 }; 9812 unsigned IID; 9813 unsigned NumEltsC; 9814 unsigned NumEltsD; 9815 switch (BuiltinID) { 9816 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9817 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f16)); 9818 NumEltsC = 4; 9819 NumEltsD = 4; 9820 break; 9821 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9822 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f16)); 9823 NumEltsC = 4; 9824 NumEltsD = 8; 9825 break; 9826 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: 9827 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f32)); 9828 NumEltsC = 8; 9829 NumEltsD = 4; 9830 break; 9831 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9832 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f32)); 9833 NumEltsC = 8; 9834 NumEltsD = 8; 9835 break; 9836 default: 9837 llvm_unreachable("Unexpected builtin ID."); 9838 } 9839 #undef MMA_VARIANTS 9840 9841 SmallVector<Value *, 24> Values; 9842 Function *Intrinsic = CGM.getIntrinsic(IID); 9843 llvm::Type *ABType = Intrinsic->getFunctionType()->getParamType(0); 9844 // Load A 9845 for (unsigned i = 0; i < 8; ++i) { 9846 Value *V = Builder.CreateAlignedLoad( 9847 Builder.CreateGEP(SrcA.getPointer(), 9848 llvm::ConstantInt::get(IntTy, i)), 9849 CharUnits::fromQuantity(4)); 9850 Values.push_back(Builder.CreateBitCast(V, ABType)); 9851 } 9852 // Load B 9853 for (unsigned i = 0; i < 8; ++i) { 9854 Value *V = Builder.CreateAlignedLoad( 9855 Builder.CreateGEP(SrcB.getPointer(), 9856 llvm::ConstantInt::get(IntTy, i)), 9857 CharUnits::fromQuantity(4)); 9858 Values.push_back(Builder.CreateBitCast(V, ABType)); 9859 } 9860 // Load C 9861 llvm::Type *CType = Intrinsic->getFunctionType()->getParamType(16); 9862 for (unsigned i = 0; i < NumEltsC; ++i) { 9863 Value *V = Builder.CreateAlignedLoad( 9864 Builder.CreateGEP(SrcC.getPointer(), 9865 llvm::ConstantInt::get(IntTy, i)), 9866 CharUnits::fromQuantity(4)); 9867 Values.push_back(Builder.CreateBitCast(V, CType)); 9868 } 9869 Value *Result = Builder.CreateCall(Intrinsic, Values); 9870 llvm::Type *DType = Dst.getElementType(); 9871 for (unsigned i = 0; i < NumEltsD; ++i) 9872 Builder.CreateAlignedStore( 9873 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType), 9874 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9875 CharUnits::fromQuantity(4)); 9876 return Result; 9877 } 9878 default: 9879 return nullptr; 9880 } 9881 } 9882 9883 Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 9884 const CallExpr *E) { 9885 switch (BuiltinID) { 9886 case WebAssembly::BI__builtin_wasm_current_memory: { 9887 llvm::Type *ResultType = ConvertType(E->getType()); 9888 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType); 9889 return Builder.CreateCall(Callee); 9890 } 9891 case WebAssembly::BI__builtin_wasm_grow_memory: { 9892 Value *X = EmitScalarExpr(E->getArg(0)); 9893 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType()); 9894 return Builder.CreateCall(Callee, X); 9895 } 9896 case WebAssembly::BI__builtin_wasm_throw: { 9897 Value *Tag = EmitScalarExpr(E->getArg(0)); 9898 Value *Obj = EmitScalarExpr(E->getArg(1)); 9899 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw); 9900 return Builder.CreateCall(Callee, {Tag, Obj}); 9901 } 9902 case WebAssembly::BI__builtin_wasm_rethrow: { 9903 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow); 9904 return Builder.CreateCall(Callee); 9905 } 9906 9907 default: 9908 return nullptr; 9909 } 9910 } 9911 9912 Value *CodeGenFunction::EmitHexagonBuiltinExpr(unsigned BuiltinID, 9913 const CallExpr *E) { 9914 SmallVector<llvm::Value *, 4> Ops; 9915 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9916 9917 switch (BuiltinID) { 9918 case Hexagon::BI__builtin_HEXAGON_V6_vaddcarry: 9919 case Hexagon::BI__builtin_HEXAGON_V6_vaddcarry_128B: { 9920 Address Dest = EmitPointerWithAlignment(E->getArg(2)); 9921 unsigned Size; 9922 if (BuiltinID == Hexagon::BI__builtin_HEXAGON_V6_vaddcarry) { 9923 Size = 512; 9924 ID = Intrinsic::hexagon_V6_vaddcarry; 9925 } else { 9926 Size = 1024; 9927 ID = Intrinsic::hexagon_V6_vaddcarry_128B; 9928 } 9929 Dest = Builder.CreateBitCast(Dest, 9930 llvm::VectorType::get(Builder.getInt1Ty(), Size)->getPointerTo(0)); 9931 LoadInst *QLd = Builder.CreateLoad(Dest); 9932 Ops = { EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1)), QLd }; 9933 llvm::Value *Result = Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 9934 llvm::Value *Vprd = Builder.CreateExtractValue(Result, 1); 9935 llvm::Value *Base = Builder.CreateBitCast(EmitScalarExpr(E->getArg(2)), 9936 Vprd->getType()->getPointerTo(0)); 9937 Builder.CreateAlignedStore(Vprd, Base, Dest.getAlignment()); 9938 return Builder.CreateExtractValue(Result, 0); 9939 } 9940 case Hexagon::BI__builtin_HEXAGON_V6_vsubcarry: 9941 case Hexagon::BI__builtin_HEXAGON_V6_vsubcarry_128B: { 9942 Address Dest = EmitPointerWithAlignment(E->getArg(2)); 9943 unsigned Size; 9944 if (BuiltinID == Hexagon::BI__builtin_HEXAGON_V6_vsubcarry) { 9945 Size = 512; 9946 ID = Intrinsic::hexagon_V6_vsubcarry; 9947 } else { 9948 Size = 1024; 9949 ID = Intrinsic::hexagon_V6_vsubcarry_128B; 9950 } 9951 Dest = Builder.CreateBitCast(Dest, 9952 llvm::VectorType::get(Builder.getInt1Ty(), Size)->getPointerTo(0)); 9953 LoadInst *QLd = Builder.CreateLoad(Dest); 9954 Ops = { EmitScalarExpr(E->getArg(0)), EmitScalarExpr(E->getArg(1)), QLd }; 9955 llvm::Value *Result = Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 9956 llvm::Value *Vprd = Builder.CreateExtractValue(Result, 1); 9957 llvm::Value *Base = Builder.CreateBitCast(EmitScalarExpr(E->getArg(2)), 9958 Vprd->getType()->getPointerTo(0)); 9959 Builder.CreateAlignedStore(Vprd, Base, Dest.getAlignment()); 9960 return Builder.CreateExtractValue(Result, 0); 9961 } 9962 } // switch 9963 9964 return nullptr; 9965 } 9966