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/ScopedPrinter.h" 34 #include "llvm/Support/ConvertUTF.h" 35 #include <sstream> 36 37 using namespace clang; 38 using namespace CodeGen; 39 using namespace llvm; 40 41 static 42 int64_t clamp(int64_t Value, int64_t Low, int64_t High) { 43 return std::min(High, std::max(Low, Value)); 44 } 45 46 /// getBuiltinLibFunction - Given a builtin id for a function like 47 /// "__builtin_fabsf", return a Function* for "fabsf". 48 llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, 49 unsigned BuiltinID) { 50 assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); 51 52 // Get the name, skip over the __builtin_ prefix (if necessary). 53 StringRef Name; 54 GlobalDecl D(FD); 55 56 // If the builtin has been declared explicitly with an assembler label, 57 // use the mangled name. This differs from the plain label on platforms 58 // that prefix labels. 59 if (FD->hasAttr<AsmLabelAttr>()) 60 Name = getMangledName(D); 61 else 62 Name = Context.BuiltinInfo.getName(BuiltinID) + 10; 63 64 llvm::FunctionType *Ty = 65 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); 66 67 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); 68 } 69 70 /// Emit the conversions required to turn the given value into an 71 /// integer of the given size. 72 static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V, 73 QualType T, llvm::IntegerType *IntType) { 74 V = CGF.EmitToMemory(V, T); 75 76 if (V->getType()->isPointerTy()) 77 return CGF.Builder.CreatePtrToInt(V, IntType); 78 79 assert(V->getType() == IntType); 80 return V; 81 } 82 83 static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, 84 QualType T, llvm::Type *ResultType) { 85 V = CGF.EmitFromMemory(V, T); 86 87 if (ResultType->isPointerTy()) 88 return CGF.Builder.CreateIntToPtr(V, ResultType); 89 90 assert(V->getType() == ResultType); 91 return V; 92 } 93 94 /// Utility to insert an atomic instruction based on Instrinsic::ID 95 /// and the expression node. 96 static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF, 97 llvm::AtomicRMWInst::BinOp Kind, 98 const CallExpr *E) { 99 QualType T = E->getType(); 100 assert(E->getArg(0)->getType()->isPointerType()); 101 assert(CGF.getContext().hasSameUnqualifiedType(T, 102 E->getArg(0)->getType()->getPointeeType())); 103 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 104 105 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 106 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 107 108 llvm::IntegerType *IntType = 109 llvm::IntegerType::get(CGF.getLLVMContext(), 110 CGF.getContext().getTypeSize(T)); 111 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 112 113 llvm::Value *Args[2]; 114 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 115 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 116 llvm::Type *ValueType = Args[1]->getType(); 117 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 118 119 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 120 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 121 return EmitFromInt(CGF, Result, T, ValueType); 122 } 123 124 static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) { 125 Value *Val = CGF.EmitScalarExpr(E->getArg(0)); 126 Value *Address = CGF.EmitScalarExpr(E->getArg(1)); 127 128 // Convert the type of the pointer to a pointer to the stored type. 129 Val = CGF.EmitToMemory(Val, E->getArg(0)->getType()); 130 Value *BC = CGF.Builder.CreateBitCast( 131 Address, llvm::PointerType::getUnqual(Val->getType()), "cast"); 132 LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType()); 133 LV.setNontemporal(true); 134 CGF.EmitStoreOfScalar(Val, LV, false); 135 return nullptr; 136 } 137 138 static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) { 139 Value *Address = CGF.EmitScalarExpr(E->getArg(0)); 140 141 LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType()); 142 LV.setNontemporal(true); 143 return CGF.EmitLoadOfScalar(LV, E->getExprLoc()); 144 } 145 146 static RValue EmitBinaryAtomic(CodeGenFunction &CGF, 147 llvm::AtomicRMWInst::BinOp Kind, 148 const CallExpr *E) { 149 return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E)); 150 } 151 152 /// Utility to insert an atomic instruction based Instrinsic::ID and 153 /// the expression node, where the return value is the result of the 154 /// operation. 155 static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 156 llvm::AtomicRMWInst::BinOp Kind, 157 const CallExpr *E, 158 Instruction::BinaryOps Op, 159 bool Invert = false) { 160 QualType T = E->getType(); 161 assert(E->getArg(0)->getType()->isPointerType()); 162 assert(CGF.getContext().hasSameUnqualifiedType(T, 163 E->getArg(0)->getType()->getPointeeType())); 164 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 165 166 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 167 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 168 169 llvm::IntegerType *IntType = 170 llvm::IntegerType::get(CGF.getLLVMContext(), 171 CGF.getContext().getTypeSize(T)); 172 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 173 174 llvm::Value *Args[2]; 175 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 176 llvm::Type *ValueType = Args[1]->getType(); 177 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 178 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 179 180 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 181 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 182 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); 183 if (Invert) 184 Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result, 185 llvm::ConstantInt::get(IntType, -1)); 186 Result = EmitFromInt(CGF, Result, T, ValueType); 187 return RValue::get(Result); 188 } 189 190 /// @brief Utility to insert an atomic cmpxchg instruction. 191 /// 192 /// @param CGF The current codegen function. 193 /// @param E Builtin call expression to convert to cmpxchg. 194 /// arg0 - address to operate on 195 /// arg1 - value to compare with 196 /// arg2 - new value 197 /// @param ReturnBool Specifies whether to return success flag of 198 /// cmpxchg result or the old value. 199 /// 200 /// @returns result of cmpxchg, according to ReturnBool 201 static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E, 202 bool ReturnBool) { 203 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType(); 204 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 205 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 206 207 llvm::IntegerType *IntType = llvm::IntegerType::get( 208 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T)); 209 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 210 211 Value *Args[3]; 212 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 213 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 214 llvm::Type *ValueType = Args[1]->getType(); 215 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 216 Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType); 217 218 Value *Pair = CGF.Builder.CreateAtomicCmpXchg( 219 Args[0], Args[1], Args[2], llvm::AtomicOrdering::SequentiallyConsistent, 220 llvm::AtomicOrdering::SequentiallyConsistent); 221 if (ReturnBool) 222 // Extract boolean success flag and zext it to int. 223 return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1), 224 CGF.ConvertType(E->getType())); 225 else 226 // Extract old value and emit it using the same type as compare value. 227 return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T, 228 ValueType); 229 } 230 231 // Emit a simple mangled intrinsic that has 1 argument and a return type 232 // matching the argument type. 233 static Value *emitUnaryBuiltin(CodeGenFunction &CGF, 234 const CallExpr *E, 235 unsigned IntrinsicID) { 236 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 237 238 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 239 return CGF.Builder.CreateCall(F, Src0); 240 } 241 242 // Emit an intrinsic that has 2 operands of the same type as its result. 243 static Value *emitBinaryBuiltin(CodeGenFunction &CGF, 244 const CallExpr *E, 245 unsigned IntrinsicID) { 246 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 247 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 248 249 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 250 return CGF.Builder.CreateCall(F, { Src0, Src1 }); 251 } 252 253 // Emit an intrinsic that has 3 operands of the same type as its result. 254 static Value *emitTernaryBuiltin(CodeGenFunction &CGF, 255 const CallExpr *E, 256 unsigned IntrinsicID) { 257 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 258 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 259 llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2)); 260 261 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 262 return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 }); 263 } 264 265 // Emit an intrinsic that has 1 float or double operand, and 1 integer. 266 static Value *emitFPIntBuiltin(CodeGenFunction &CGF, 267 const CallExpr *E, 268 unsigned IntrinsicID) { 269 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 270 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 271 272 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 273 return CGF.Builder.CreateCall(F, {Src0, Src1}); 274 } 275 276 /// EmitFAbs - Emit a call to @llvm.fabs(). 277 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) { 278 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType()); 279 llvm::CallInst *Call = CGF.Builder.CreateCall(F, V); 280 Call->setDoesNotAccessMemory(); 281 return Call; 282 } 283 284 /// Emit the computation of the sign bit for a floating point value. Returns 285 /// the i1 sign bit value. 286 static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) { 287 LLVMContext &C = CGF.CGM.getLLVMContext(); 288 289 llvm::Type *Ty = V->getType(); 290 int Width = Ty->getPrimitiveSizeInBits(); 291 llvm::Type *IntTy = llvm::IntegerType::get(C, Width); 292 V = CGF.Builder.CreateBitCast(V, IntTy); 293 if (Ty->isPPC_FP128Ty()) { 294 // We want the sign bit of the higher-order double. The bitcast we just 295 // did works as if the double-double was stored to memory and then 296 // read as an i128. The "store" will put the higher-order double in the 297 // lower address in both little- and big-Endian modes, but the "load" 298 // will treat those bits as a different part of the i128: the low bits in 299 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian 300 // we need to shift the high bits down to the low before truncating. 301 Width >>= 1; 302 if (CGF.getTarget().isBigEndian()) { 303 Value *ShiftCst = llvm::ConstantInt::get(IntTy, Width); 304 V = CGF.Builder.CreateLShr(V, ShiftCst); 305 } 306 // We are truncating value in order to extract the higher-order 307 // double, which we will be using to extract the sign from. 308 IntTy = llvm::IntegerType::get(C, Width); 309 V = CGF.Builder.CreateTrunc(V, IntTy); 310 } 311 Value *Zero = llvm::Constant::getNullValue(IntTy); 312 return CGF.Builder.CreateICmpSLT(V, Zero); 313 } 314 315 static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, 316 const CallExpr *E, llvm::Constant *calleeValue) { 317 CGCallee callee = CGCallee::forDirect(calleeValue, FD); 318 return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); 319 } 320 321 /// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.* 322 /// depending on IntrinsicID. 323 /// 324 /// \arg CGF The current codegen function. 325 /// \arg IntrinsicID The ID for the Intrinsic we wish to generate. 326 /// \arg X The first argument to the llvm.*.with.overflow.*. 327 /// \arg Y The second argument to the llvm.*.with.overflow.*. 328 /// \arg Carry The carry returned by the llvm.*.with.overflow.*. 329 /// \returns The result (i.e. sum/product) returned by the intrinsic. 330 static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF, 331 const llvm::Intrinsic::ID IntrinsicID, 332 llvm::Value *X, llvm::Value *Y, 333 llvm::Value *&Carry) { 334 // Make sure we have integers of the same width. 335 assert(X->getType() == Y->getType() && 336 "Arguments must be the same type. (Did you forget to make sure both " 337 "arguments have the same integer width?)"); 338 339 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType()); 340 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y}); 341 Carry = CGF.Builder.CreateExtractValue(Tmp, 1); 342 return CGF.Builder.CreateExtractValue(Tmp, 0); 343 } 344 345 static Value *emitRangedBuiltin(CodeGenFunction &CGF, 346 unsigned IntrinsicID, 347 int low, int high) { 348 llvm::MDBuilder MDHelper(CGF.getLLVMContext()); 349 llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high)); 350 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {}); 351 llvm::Instruction *Call = CGF.Builder.CreateCall(F); 352 Call->setMetadata(llvm::LLVMContext::MD_range, RNode); 353 return Call; 354 } 355 356 namespace { 357 struct WidthAndSignedness { 358 unsigned Width; 359 bool Signed; 360 }; 361 } 362 363 static WidthAndSignedness 364 getIntegerWidthAndSignedness(const clang::ASTContext &context, 365 const clang::QualType Type) { 366 assert(Type->isIntegerType() && "Given type is not an integer."); 367 unsigned Width = Type->isBooleanType() ? 1 : context.getTypeInfo(Type).Width; 368 bool Signed = Type->isSignedIntegerType(); 369 return {Width, Signed}; 370 } 371 372 // Given one or more integer types, this function produces an integer type that 373 // encompasses them: any value in one of the given types could be expressed in 374 // the encompassing type. 375 static struct WidthAndSignedness 376 EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) { 377 assert(Types.size() > 0 && "Empty list of types."); 378 379 // If any of the given types is signed, we must return a signed type. 380 bool Signed = false; 381 for (const auto &Type : Types) { 382 Signed |= Type.Signed; 383 } 384 385 // The encompassing type must have a width greater than or equal to the width 386 // of the specified types. Aditionally, if the encompassing type is signed, 387 // its width must be strictly greater than the width of any unsigned types 388 // given. 389 unsigned Width = 0; 390 for (const auto &Type : Types) { 391 unsigned MinWidth = Type.Width + (Signed && !Type.Signed); 392 if (Width < MinWidth) { 393 Width = MinWidth; 394 } 395 } 396 397 return {Width, Signed}; 398 } 399 400 Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) { 401 llvm::Type *DestType = Int8PtrTy; 402 if (ArgValue->getType() != DestType) 403 ArgValue = 404 Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data()); 405 406 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend; 407 return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue); 408 } 409 410 /// Checks if using the result of __builtin_object_size(p, @p From) in place of 411 /// __builtin_object_size(p, @p To) is correct 412 static bool areBOSTypesCompatible(int From, int To) { 413 // Note: Our __builtin_object_size implementation currently treats Type=0 and 414 // Type=2 identically. Encoding this implementation detail here may make 415 // improving __builtin_object_size difficult in the future, so it's omitted. 416 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2); 417 } 418 419 static llvm::Value * 420 getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) { 421 return ConstantInt::get(ResType, (Type & 2) ? 0 : -1, /*isSigned=*/true); 422 } 423 424 llvm::Value * 425 CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, 426 llvm::IntegerType *ResType, 427 llvm::Value *EmittedE) { 428 uint64_t ObjectSize; 429 if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type)) 430 return emitBuiltinObjectSize(E, Type, ResType, EmittedE); 431 return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); 432 } 433 434 /// Returns a Value corresponding to the size of the given expression. 435 /// This Value may be either of the following: 436 /// - A llvm::Argument (if E is a param with the pass_object_size attribute on 437 /// it) 438 /// - A call to the @llvm.objectsize intrinsic 439 /// 440 /// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null 441 /// and we wouldn't otherwise try to reference a pass_object_size parameter, 442 /// we'll call @llvm.objectsize on EmittedE, rather than emitting E. 443 llvm::Value * 444 CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, 445 llvm::IntegerType *ResType, 446 llvm::Value *EmittedE) { 447 // We need to reference an argument if the pointer is a parameter with the 448 // pass_object_size attribute. 449 if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) { 450 auto *Param = dyn_cast<ParmVarDecl>(D->getDecl()); 451 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>(); 452 if (Param != nullptr && PS != nullptr && 453 areBOSTypesCompatible(PS->getType(), Type)) { 454 auto Iter = SizeArguments.find(Param); 455 assert(Iter != SizeArguments.end()); 456 457 const ImplicitParamDecl *D = Iter->second; 458 auto DIter = LocalDeclMap.find(D); 459 assert(DIter != LocalDeclMap.end()); 460 461 return EmitLoadOfScalar(DIter->second, /*volatile=*/false, 462 getContext().getSizeType(), E->getLocStart()); 463 } 464 } 465 466 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't 467 // evaluate E for side-effects. In either case, we shouldn't lower to 468 // @llvm.objectsize. 469 if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext()))) 470 return getDefaultBuiltinObjectSizeResult(Type, ResType); 471 472 Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E); 473 assert(Ptr->getType()->isPointerTy() && 474 "Non-pointer passed to __builtin_object_size?"); 475 476 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()}); 477 478 // LLVM only supports 0 and 2, make sure that we pass along that as a boolean. 479 Value *Min = Builder.getInt1((Type & 2) != 0); 480 // For GCC compatability, __builtin_object_size treat NULL as unknown size. 481 Value *NullIsUnknown = Builder.getTrue(); 482 return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown}); 483 } 484 485 // Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we 486 // handle them here. 487 enum class CodeGenFunction::MSVCIntrin { 488 _BitScanForward, 489 _BitScanReverse, 490 _InterlockedAnd, 491 _InterlockedDecrement, 492 _InterlockedExchange, 493 _InterlockedExchangeAdd, 494 _InterlockedExchangeSub, 495 _InterlockedIncrement, 496 _InterlockedOr, 497 _InterlockedXor, 498 _interlockedbittestandset, 499 __fastfail, 500 }; 501 502 Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, 503 const CallExpr *E) { 504 switch (BuiltinID) { 505 case MSVCIntrin::_BitScanForward: 506 case MSVCIntrin::_BitScanReverse: { 507 Value *ArgValue = EmitScalarExpr(E->getArg(1)); 508 509 llvm::Type *ArgType = ArgValue->getType(); 510 llvm::Type *IndexType = 511 EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); 512 llvm::Type *ResultType = ConvertType(E->getType()); 513 514 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 515 Value *ResZero = llvm::Constant::getNullValue(ResultType); 516 Value *ResOne = llvm::ConstantInt::get(ResultType, 1); 517 518 BasicBlock *Begin = Builder.GetInsertBlock(); 519 BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn); 520 Builder.SetInsertPoint(End); 521 PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result"); 522 523 Builder.SetInsertPoint(Begin); 524 Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); 525 BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn); 526 Builder.CreateCondBr(IsZero, End, NotZero); 527 Result->addIncoming(ResZero, Begin); 528 529 Builder.SetInsertPoint(NotZero); 530 Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); 531 532 if (BuiltinID == MSVCIntrin::_BitScanForward) { 533 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 534 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 535 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 536 Builder.CreateStore(ZeroCount, IndexAddress, false); 537 } else { 538 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 539 Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); 540 541 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 542 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 543 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 544 Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); 545 Builder.CreateStore(Index, IndexAddress, false); 546 } 547 Builder.CreateBr(End); 548 Result->addIncoming(ResOne, NotZero); 549 550 Builder.SetInsertPoint(End); 551 return Result; 552 } 553 case MSVCIntrin::_InterlockedAnd: 554 return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E); 555 case MSVCIntrin::_InterlockedExchange: 556 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E); 557 case MSVCIntrin::_InterlockedExchangeAdd: 558 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E); 559 case MSVCIntrin::_InterlockedExchangeSub: 560 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Sub, E); 561 case MSVCIntrin::_InterlockedOr: 562 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E); 563 case MSVCIntrin::_InterlockedXor: 564 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E); 565 566 case MSVCIntrin::_interlockedbittestandset: { 567 llvm::Value *Addr = EmitScalarExpr(E->getArg(0)); 568 llvm::Value *Bit = EmitScalarExpr(E->getArg(1)); 569 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 570 AtomicRMWInst::Or, Addr, 571 Builder.CreateShl(ConstantInt::get(Bit->getType(), 1), Bit), 572 llvm::AtomicOrdering::SequentiallyConsistent); 573 // Shift the relevant bit to the least significant position, truncate to 574 // the result type, and test the low bit. 575 llvm::Value *Shifted = Builder.CreateLShr(RMWI, Bit); 576 llvm::Value *Truncated = 577 Builder.CreateTrunc(Shifted, ConvertType(E->getType())); 578 return Builder.CreateAnd(Truncated, 579 ConstantInt::get(Truncated->getType(), 1)); 580 } 581 582 case MSVCIntrin::_InterlockedDecrement: { 583 llvm::Type *IntTy = ConvertType(E->getType()); 584 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 585 AtomicRMWInst::Sub, 586 EmitScalarExpr(E->getArg(0)), 587 ConstantInt::get(IntTy, 1), 588 llvm::AtomicOrdering::SequentiallyConsistent); 589 return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1)); 590 } 591 case MSVCIntrin::_InterlockedIncrement: { 592 llvm::Type *IntTy = ConvertType(E->getType()); 593 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 594 AtomicRMWInst::Add, 595 EmitScalarExpr(E->getArg(0)), 596 ConstantInt::get(IntTy, 1), 597 llvm::AtomicOrdering::SequentiallyConsistent); 598 return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1)); 599 } 600 601 case MSVCIntrin::__fastfail: { 602 // Request immediate process termination from the kernel. The instruction 603 // sequences to do this are documented on MSDN: 604 // https://msdn.microsoft.com/en-us/library/dn774154.aspx 605 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch(); 606 StringRef Asm, Constraints; 607 switch (ISA) { 608 default: 609 ErrorUnsupported(E, "__fastfail call for this architecture"); 610 break; 611 case llvm::Triple::x86: 612 case llvm::Triple::x86_64: 613 Asm = "int $$0x29"; 614 Constraints = "{cx}"; 615 break; 616 case llvm::Triple::thumb: 617 Asm = "udf #251"; 618 Constraints = "{r0}"; 619 break; 620 } 621 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false); 622 llvm::InlineAsm *IA = 623 llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true); 624 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get( 625 getLLVMContext(), llvm::AttributeList::FunctionIndex, 626 llvm::Attribute::NoReturn); 627 CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0))); 628 CS.setAttributes(NoReturnAttr); 629 return CS.getInstruction(); 630 } 631 } 632 llvm_unreachable("Incorrect MSVC intrinsic!"); 633 } 634 635 namespace { 636 // ARC cleanup for __builtin_os_log_format 637 struct CallObjCArcUse final : EHScopeStack::Cleanup { 638 CallObjCArcUse(llvm::Value *object) : object(object) {} 639 llvm::Value *object; 640 641 void Emit(CodeGenFunction &CGF, Flags flags) override { 642 CGF.EmitARCIntrinsicUse(object); 643 } 644 }; 645 } 646 647 Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E, 648 BuiltinCheckKind Kind) { 649 assert((Kind == BCK_CLZPassedZero || Kind == BCK_CTZPassedZero) 650 && "Unsupported builtin check kind"); 651 652 Value *ArgValue = EmitScalarExpr(E); 653 if (!SanOpts.has(SanitizerKind::Builtin) || !getTarget().isCLZForZeroUndef()) 654 return ArgValue; 655 656 SanitizerScope SanScope(this); 657 Value *Cond = Builder.CreateICmpNE( 658 ArgValue, llvm::Constant::getNullValue(ArgValue->getType())); 659 EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin), 660 SanitizerHandler::InvalidBuiltin, 661 {EmitCheckSourceLocation(E->getExprLoc()), 662 llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)}, 663 None); 664 return ArgValue; 665 } 666 667 /// Get the argument type for arguments to os_log_helper. 668 static CanQualType getOSLogArgType(ASTContext &C, int Size) { 669 QualType UnsignedTy = C.getIntTypeForBitwidth(Size * 8, /*Signed=*/false); 670 return C.getCanonicalType(UnsignedTy); 671 } 672 673 llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction( 674 const analyze_os_log::OSLogBufferLayout &Layout, 675 CharUnits BufferAlignment) { 676 ASTContext &Ctx = getContext(); 677 678 llvm::SmallString<64> Name; 679 { 680 raw_svector_ostream OS(Name); 681 OS << "__os_log_helper"; 682 OS << "_" << BufferAlignment.getQuantity(); 683 OS << "_" << int(Layout.getSummaryByte()); 684 OS << "_" << int(Layout.getNumArgsByte()); 685 for (const auto &Item : Layout.Items) 686 OS << "_" << int(Item.getSizeByte()) << "_" 687 << int(Item.getDescriptorByte()); 688 } 689 690 if (llvm::Function *F = CGM.getModule().getFunction(Name)) 691 return F; 692 693 llvm::SmallVector<ImplicitParamDecl, 4> Params; 694 Params.emplace_back(Ctx, nullptr, SourceLocation(), &Ctx.Idents.get("buffer"), 695 Ctx.VoidPtrTy, ImplicitParamDecl::Other); 696 697 for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) { 698 char Size = Layout.Items[I].getSizeByte(); 699 if (!Size) 700 continue; 701 702 Params.emplace_back( 703 Ctx, nullptr, SourceLocation(), 704 &Ctx.Idents.get(std::string("arg") + llvm::to_string(I)), 705 getOSLogArgType(Ctx, Size), ImplicitParamDecl::Other); 706 } 707 708 FunctionArgList Args; 709 for (auto &P : Params) 710 Args.push_back(&P); 711 712 // The helper function has linkonce_odr linkage to enable the linker to merge 713 // identical functions. To ensure the merging always happens, 'noinline' is 714 // attached to the function when compiling with -Oz. 715 const CGFunctionInfo &FI = 716 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args); 717 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI); 718 llvm::Function *Fn = llvm::Function::Create( 719 FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule()); 720 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); 721 CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn); 722 CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn); 723 724 // Attach 'noinline' at -Oz. 725 if (CGM.getCodeGenOpts().OptimizeSize == 2) 726 Fn->addFnAttr(llvm::Attribute::NoInline); 727 728 auto NL = ApplyDebugLocation::CreateEmpty(*this); 729 IdentifierInfo *II = &Ctx.Idents.get(Name); 730 FunctionDecl *FD = FunctionDecl::Create( 731 Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, 732 Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false); 733 734 StartFunction(FD, Ctx.VoidTy, Fn, FI, Args); 735 736 // Create a scope with an artificial location for the body of this function. 737 auto AL = ApplyDebugLocation::CreateArtificial(*this); 738 739 CharUnits Offset; 740 Address BufAddr(Builder.CreateLoad(GetAddrOfLocalVar(&Params[0]), "buf"), 741 BufferAlignment); 742 Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()), 743 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary")); 744 Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()), 745 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs")); 746 747 unsigned I = 1; 748 for (const auto &Item : Layout.Items) { 749 Builder.CreateStore( 750 Builder.getInt8(Item.getDescriptorByte()), 751 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor")); 752 Builder.CreateStore( 753 Builder.getInt8(Item.getSizeByte()), 754 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize")); 755 756 CharUnits Size = Item.size(); 757 if (!Size.getQuantity()) 758 continue; 759 760 Address Arg = GetAddrOfLocalVar(&Params[I]); 761 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset, "argData"); 762 Addr = Builder.CreateBitCast(Addr, Arg.getPointer()->getType(), 763 "argDataCast"); 764 Builder.CreateStore(Builder.CreateLoad(Arg), Addr); 765 Offset += Size; 766 ++I; 767 } 768 769 FinishFunction(); 770 771 return Fn; 772 } 773 774 RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { 775 assert(E.getNumArgs() >= 2 && 776 "__builtin_os_log_format takes at least 2 arguments"); 777 ASTContext &Ctx = getContext(); 778 analyze_os_log::OSLogBufferLayout Layout; 779 analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout); 780 Address BufAddr = EmitPointerWithAlignment(E.getArg(0)); 781 llvm::SmallVector<llvm::Value *, 4> RetainableOperands; 782 783 // Ignore argument 1, the format string. It is not currently used. 784 CallArgList Args; 785 Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy); 786 787 for (const auto &Item : Layout.Items) { 788 int Size = Item.getSizeByte(); 789 if (!Size) 790 continue; 791 792 llvm::Value *ArgVal; 793 794 if (const Expr *TheExpr = Item.getExpr()) { 795 ArgVal = EmitScalarExpr(TheExpr, /*Ignore*/ false); 796 797 // Check if this is a retainable type. 798 if (TheExpr->getType()->isObjCRetainableType()) { 799 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar && 800 "Only scalar can be a ObjC retainable type"); 801 // Check if the object is constant, if not, save it in 802 // RetainableOperands. 803 if (!isa<Constant>(ArgVal)) 804 RetainableOperands.push_back(ArgVal); 805 } 806 } else { 807 ArgVal = Builder.getInt32(Item.getConstValue().getQuantity()); 808 } 809 810 unsigned ArgValSize = 811 CGM.getDataLayout().getTypeSizeInBits(ArgVal->getType()); 812 llvm::IntegerType *IntTy = llvm::Type::getIntNTy(getLLVMContext(), 813 ArgValSize); 814 ArgVal = Builder.CreateBitOrPointerCast(ArgVal, IntTy); 815 CanQualType ArgTy = getOSLogArgType(Ctx, Size); 816 // If ArgVal has type x86_fp80, zero-extend ArgVal. 817 ArgVal = Builder.CreateZExtOrBitCast(ArgVal, ConvertType(ArgTy)); 818 Args.add(RValue::get(ArgVal), ArgTy); 819 } 820 821 const CGFunctionInfo &FI = 822 CGM.getTypes().arrangeBuiltinFunctionCall(Ctx.VoidTy, Args); 823 llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction( 824 Layout, BufAddr.getAlignment()); 825 EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args); 826 827 // Push a clang.arc.use cleanup for each object in RetainableOperands. The 828 // cleanup will cause the use to appear after the final log call, keeping 829 // the object valid while it’s held in the log buffer. Note that if there’s 830 // a release cleanup on the object, it will already be active; since 831 // cleanups are emitted in reverse order, the use will occur before the 832 // object is released. 833 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount && 834 CGM.getCodeGenOpts().OptimizationLevel != 0) 835 for (llvm::Value *Object : RetainableOperands) 836 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), Object); 837 838 return RValue::get(BufAddr.getPointer()); 839 } 840 841 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 842 unsigned BuiltinID, const CallExpr *E, 843 ReturnValueSlot ReturnValue) { 844 // See if we can constant fold this builtin. If so, don't emit it at all. 845 Expr::EvalResult Result; 846 if (E->EvaluateAsRValue(Result, CGM.getContext()) && 847 !Result.hasSideEffects()) { 848 if (Result.Val.isInt()) 849 return RValue::get(llvm::ConstantInt::get(getLLVMContext(), 850 Result.Val.getInt())); 851 if (Result.Val.isFloat()) 852 return RValue::get(llvm::ConstantFP::get(getLLVMContext(), 853 Result.Val.getFloat())); 854 } 855 856 switch (BuiltinID) { 857 default: break; // Handle intrinsics and libm functions below. 858 case Builtin::BI__builtin___CFStringMakeConstantString: 859 case Builtin::BI__builtin___NSStringMakeConstantString: 860 return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType())); 861 case Builtin::BI__builtin_stdarg_start: 862 case Builtin::BI__builtin_va_start: 863 case Builtin::BI__va_start: 864 case Builtin::BI__builtin_va_end: 865 return RValue::get( 866 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start 867 ? EmitScalarExpr(E->getArg(0)) 868 : EmitVAListRef(E->getArg(0)).getPointer(), 869 BuiltinID != Builtin::BI__builtin_va_end)); 870 case Builtin::BI__builtin_va_copy: { 871 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer(); 872 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer(); 873 874 llvm::Type *Type = Int8PtrTy; 875 876 DstPtr = Builder.CreateBitCast(DstPtr, Type); 877 SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 878 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), 879 {DstPtr, SrcPtr})); 880 } 881 case Builtin::BI__builtin_abs: 882 case Builtin::BI__builtin_labs: 883 case Builtin::BI__builtin_llabs: { 884 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 885 886 Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 887 Value *CmpResult = 888 Builder.CreateICmpSGE(ArgValue, 889 llvm::Constant::getNullValue(ArgValue->getType()), 890 "abscond"); 891 Value *Result = 892 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 893 894 return RValue::get(Result); 895 } 896 case Builtin::BI__builtin_fabs: 897 case Builtin::BI__builtin_fabsf: 898 case Builtin::BI__builtin_fabsl: { 899 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs)); 900 } 901 case Builtin::BI__builtin_fmod: 902 case Builtin::BI__builtin_fmodf: 903 case Builtin::BI__builtin_fmodl: { 904 Value *Arg1 = EmitScalarExpr(E->getArg(0)); 905 Value *Arg2 = EmitScalarExpr(E->getArg(1)); 906 Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod"); 907 return RValue::get(Result); 908 } 909 case Builtin::BI__builtin_copysign: 910 case Builtin::BI__builtin_copysignf: 911 case Builtin::BI__builtin_copysignl: { 912 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign)); 913 } 914 case Builtin::BI__builtin_ceil: 915 case Builtin::BI__builtin_ceilf: 916 case Builtin::BI__builtin_ceill: { 917 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil)); 918 } 919 case Builtin::BI__builtin_floor: 920 case Builtin::BI__builtin_floorf: 921 case Builtin::BI__builtin_floorl: { 922 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor)); 923 } 924 case Builtin::BI__builtin_trunc: 925 case Builtin::BI__builtin_truncf: 926 case Builtin::BI__builtin_truncl: { 927 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc)); 928 } 929 case Builtin::BI__builtin_rint: 930 case Builtin::BI__builtin_rintf: 931 case Builtin::BI__builtin_rintl: { 932 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint)); 933 } 934 case Builtin::BI__builtin_nearbyint: 935 case Builtin::BI__builtin_nearbyintf: 936 case Builtin::BI__builtin_nearbyintl: { 937 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint)); 938 } 939 case Builtin::BI__builtin_round: 940 case Builtin::BI__builtin_roundf: 941 case Builtin::BI__builtin_roundl: { 942 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round)); 943 } 944 case Builtin::BI__builtin_fmin: 945 case Builtin::BI__builtin_fminf: 946 case Builtin::BI__builtin_fminl: { 947 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum)); 948 } 949 case Builtin::BI__builtin_fmax: 950 case Builtin::BI__builtin_fmaxf: 951 case Builtin::BI__builtin_fmaxl: { 952 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum)); 953 } 954 case Builtin::BI__builtin_conj: 955 case Builtin::BI__builtin_conjf: 956 case Builtin::BI__builtin_conjl: { 957 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 958 Value *Real = ComplexVal.first; 959 Value *Imag = ComplexVal.second; 960 Value *Zero = 961 Imag->getType()->isFPOrFPVectorTy() 962 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) 963 : llvm::Constant::getNullValue(Imag->getType()); 964 965 Imag = Builder.CreateFSub(Zero, Imag, "sub"); 966 return RValue::getComplex(std::make_pair(Real, Imag)); 967 } 968 case Builtin::BI__builtin_creal: 969 case Builtin::BI__builtin_crealf: 970 case Builtin::BI__builtin_creall: 971 case Builtin::BIcreal: 972 case Builtin::BIcrealf: 973 case Builtin::BIcreall: { 974 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 975 return RValue::get(ComplexVal.first); 976 } 977 978 case Builtin::BI__builtin_cimag: 979 case Builtin::BI__builtin_cimagf: 980 case Builtin::BI__builtin_cimagl: 981 case Builtin::BIcimag: 982 case Builtin::BIcimagf: 983 case Builtin::BIcimagl: { 984 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 985 return RValue::get(ComplexVal.second); 986 } 987 988 case Builtin::BI__builtin_ctzs: 989 case Builtin::BI__builtin_ctz: 990 case Builtin::BI__builtin_ctzl: 991 case Builtin::BI__builtin_ctzll: { 992 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero); 993 994 llvm::Type *ArgType = ArgValue->getType(); 995 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 996 997 llvm::Type *ResultType = ConvertType(E->getType()); 998 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 999 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 1000 if (Result->getType() != ResultType) 1001 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1002 "cast"); 1003 return RValue::get(Result); 1004 } 1005 case Builtin::BI__builtin_clzs: 1006 case Builtin::BI__builtin_clz: 1007 case Builtin::BI__builtin_clzl: 1008 case Builtin::BI__builtin_clzll: { 1009 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero); 1010 1011 llvm::Type *ArgType = ArgValue->getType(); 1012 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 1013 1014 llvm::Type *ResultType = ConvertType(E->getType()); 1015 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 1016 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 1017 if (Result->getType() != ResultType) 1018 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1019 "cast"); 1020 return RValue::get(Result); 1021 } 1022 case Builtin::BI__builtin_ffs: 1023 case Builtin::BI__builtin_ffsl: 1024 case Builtin::BI__builtin_ffsll: { 1025 // ffs(x) -> x ? cttz(x) + 1 : 0 1026 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1027 1028 llvm::Type *ArgType = ArgValue->getType(); 1029 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 1030 1031 llvm::Type *ResultType = ConvertType(E->getType()); 1032 Value *Tmp = 1033 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}), 1034 llvm::ConstantInt::get(ArgType, 1)); 1035 Value *Zero = llvm::Constant::getNullValue(ArgType); 1036 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 1037 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 1038 if (Result->getType() != ResultType) 1039 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1040 "cast"); 1041 return RValue::get(Result); 1042 } 1043 case Builtin::BI__builtin_parity: 1044 case Builtin::BI__builtin_parityl: 1045 case Builtin::BI__builtin_parityll: { 1046 // parity(x) -> ctpop(x) & 1 1047 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1048 1049 llvm::Type *ArgType = ArgValue->getType(); 1050 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 1051 1052 llvm::Type *ResultType = ConvertType(E->getType()); 1053 Value *Tmp = Builder.CreateCall(F, ArgValue); 1054 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1)); 1055 if (Result->getType() != ResultType) 1056 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1057 "cast"); 1058 return RValue::get(Result); 1059 } 1060 case Builtin::BI__popcnt16: 1061 case Builtin::BI__popcnt: 1062 case Builtin::BI__popcnt64: 1063 case Builtin::BI__builtin_popcount: 1064 case Builtin::BI__builtin_popcountl: 1065 case Builtin::BI__builtin_popcountll: { 1066 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1067 1068 llvm::Type *ArgType = ArgValue->getType(); 1069 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 1070 1071 llvm::Type *ResultType = ConvertType(E->getType()); 1072 Value *Result = Builder.CreateCall(F, ArgValue); 1073 if (Result->getType() != ResultType) 1074 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1075 "cast"); 1076 return RValue::get(Result); 1077 } 1078 case Builtin::BI_rotr8: 1079 case Builtin::BI_rotr16: 1080 case Builtin::BI_rotr: 1081 case Builtin::BI_lrotr: 1082 case Builtin::BI_rotr64: { 1083 Value *Val = EmitScalarExpr(E->getArg(0)); 1084 Value *Shift = EmitScalarExpr(E->getArg(1)); 1085 1086 llvm::Type *ArgType = Val->getType(); 1087 Shift = Builder.CreateIntCast(Shift, ArgType, false); 1088 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 1089 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 1090 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 1091 1092 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 1093 Shift = Builder.CreateAnd(Shift, Mask); 1094 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); 1095 1096 Value *RightShifted = Builder.CreateLShr(Val, Shift); 1097 Value *LeftShifted = Builder.CreateShl(Val, LeftShift); 1098 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 1099 1100 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 1101 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 1102 return RValue::get(Result); 1103 } 1104 case Builtin::BI_rotl8: 1105 case Builtin::BI_rotl16: 1106 case Builtin::BI_rotl: 1107 case Builtin::BI_lrotl: 1108 case Builtin::BI_rotl64: { 1109 Value *Val = EmitScalarExpr(E->getArg(0)); 1110 Value *Shift = EmitScalarExpr(E->getArg(1)); 1111 1112 llvm::Type *ArgType = Val->getType(); 1113 Shift = Builder.CreateIntCast(Shift, ArgType, false); 1114 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 1115 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 1116 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 1117 1118 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 1119 Shift = Builder.CreateAnd(Shift, Mask); 1120 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); 1121 1122 Value *LeftShifted = Builder.CreateShl(Val, Shift); 1123 Value *RightShifted = Builder.CreateLShr(Val, RightShift); 1124 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 1125 1126 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 1127 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 1128 return RValue::get(Result); 1129 } 1130 case Builtin::BI__builtin_unpredictable: { 1131 // Always return the argument of __builtin_unpredictable. LLVM does not 1132 // handle this builtin. Metadata for this builtin should be added directly 1133 // to instructions such as branches or switches that use it. 1134 return RValue::get(EmitScalarExpr(E->getArg(0))); 1135 } 1136 case Builtin::BI__builtin_expect: { 1137 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1138 llvm::Type *ArgType = ArgValue->getType(); 1139 1140 Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); 1141 // Don't generate llvm.expect on -O0 as the backend won't use it for 1142 // anything. 1143 // Note, we still IRGen ExpectedValue because it could have side-effects. 1144 if (CGM.getCodeGenOpts().OptimizationLevel == 0) 1145 return RValue::get(ArgValue); 1146 1147 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType); 1148 Value *Result = 1149 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval"); 1150 return RValue::get(Result); 1151 } 1152 case Builtin::BI__builtin_assume_aligned: { 1153 Value *PtrValue = EmitScalarExpr(E->getArg(0)); 1154 Value *OffsetValue = 1155 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr; 1156 1157 Value *AlignmentValue = EmitScalarExpr(E->getArg(1)); 1158 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue); 1159 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue(); 1160 1161 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue); 1162 return RValue::get(PtrValue); 1163 } 1164 case Builtin::BI__assume: 1165 case Builtin::BI__builtin_assume: { 1166 if (E->getArg(0)->HasSideEffects(getContext())) 1167 return RValue::get(nullptr); 1168 1169 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1170 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume); 1171 return RValue::get(Builder.CreateCall(FnAssume, ArgValue)); 1172 } 1173 case Builtin::BI__builtin_bswap16: 1174 case Builtin::BI__builtin_bswap32: 1175 case Builtin::BI__builtin_bswap64: { 1176 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap)); 1177 } 1178 case Builtin::BI__builtin_bitreverse8: 1179 case Builtin::BI__builtin_bitreverse16: 1180 case Builtin::BI__builtin_bitreverse32: 1181 case Builtin::BI__builtin_bitreverse64: { 1182 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse)); 1183 } 1184 case Builtin::BI__builtin_object_size: { 1185 unsigned Type = 1186 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); 1187 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType())); 1188 1189 // We pass this builtin onto the optimizer so that it can figure out the 1190 // object size in more complex cases. 1191 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType, 1192 /*EmittedE=*/nullptr)); 1193 } 1194 case Builtin::BI__builtin_prefetch: { 1195 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 1196 // FIXME: Technically these constants should of type 'int', yes? 1197 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 1198 llvm::ConstantInt::get(Int32Ty, 0); 1199 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 1200 llvm::ConstantInt::get(Int32Ty, 3); 1201 Value *Data = llvm::ConstantInt::get(Int32Ty, 1); 1202 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 1203 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data})); 1204 } 1205 case Builtin::BI__builtin_readcyclecounter: { 1206 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter); 1207 return RValue::get(Builder.CreateCall(F)); 1208 } 1209 case Builtin::BI__builtin___clear_cache: { 1210 Value *Begin = EmitScalarExpr(E->getArg(0)); 1211 Value *End = EmitScalarExpr(E->getArg(1)); 1212 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache); 1213 return RValue::get(Builder.CreateCall(F, {Begin, End})); 1214 } 1215 case Builtin::BI__builtin_trap: 1216 return RValue::get(EmitTrapCall(Intrinsic::trap)); 1217 case Builtin::BI__debugbreak: 1218 return RValue::get(EmitTrapCall(Intrinsic::debugtrap)); 1219 case Builtin::BI__builtin_unreachable: { 1220 if (SanOpts.has(SanitizerKind::Unreachable)) { 1221 SanitizerScope SanScope(this); 1222 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()), 1223 SanitizerKind::Unreachable), 1224 SanitizerHandler::BuiltinUnreachable, 1225 EmitCheckSourceLocation(E->getExprLoc()), None); 1226 } else 1227 Builder.CreateUnreachable(); 1228 1229 // We do need to preserve an insertion point. 1230 EmitBlock(createBasicBlock("unreachable.cont")); 1231 1232 return RValue::get(nullptr); 1233 } 1234 1235 case Builtin::BI__builtin_powi: 1236 case Builtin::BI__builtin_powif: 1237 case Builtin::BI__builtin_powil: { 1238 Value *Base = EmitScalarExpr(E->getArg(0)); 1239 Value *Exponent = EmitScalarExpr(E->getArg(1)); 1240 llvm::Type *ArgType = Base->getType(); 1241 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType); 1242 return RValue::get(Builder.CreateCall(F, {Base, Exponent})); 1243 } 1244 1245 case Builtin::BI__builtin_isgreater: 1246 case Builtin::BI__builtin_isgreaterequal: 1247 case Builtin::BI__builtin_isless: 1248 case Builtin::BI__builtin_islessequal: 1249 case Builtin::BI__builtin_islessgreater: 1250 case Builtin::BI__builtin_isunordered: { 1251 // Ordered comparisons: we know the arguments to these are matching scalar 1252 // floating point values. 1253 Value *LHS = EmitScalarExpr(E->getArg(0)); 1254 Value *RHS = EmitScalarExpr(E->getArg(1)); 1255 1256 switch (BuiltinID) { 1257 default: llvm_unreachable("Unknown ordered comparison"); 1258 case Builtin::BI__builtin_isgreater: 1259 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 1260 break; 1261 case Builtin::BI__builtin_isgreaterequal: 1262 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 1263 break; 1264 case Builtin::BI__builtin_isless: 1265 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 1266 break; 1267 case Builtin::BI__builtin_islessequal: 1268 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 1269 break; 1270 case Builtin::BI__builtin_islessgreater: 1271 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 1272 break; 1273 case Builtin::BI__builtin_isunordered: 1274 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 1275 break; 1276 } 1277 // ZExt bool to int type. 1278 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()))); 1279 } 1280 case Builtin::BI__builtin_isnan: { 1281 Value *V = EmitScalarExpr(E->getArg(0)); 1282 V = Builder.CreateFCmpUNO(V, V, "cmp"); 1283 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1284 } 1285 1286 case Builtin::BIfinite: 1287 case Builtin::BI__finite: 1288 case Builtin::BIfinitef: 1289 case Builtin::BI__finitef: 1290 case Builtin::BIfinitel: 1291 case Builtin::BI__finitel: 1292 case Builtin::BI__builtin_isinf: 1293 case Builtin::BI__builtin_isfinite: { 1294 // isinf(x) --> fabs(x) == infinity 1295 // isfinite(x) --> fabs(x) != infinity 1296 // x != NaN via the ordered compare in either case. 1297 Value *V = EmitScalarExpr(E->getArg(0)); 1298 Value *Fabs = EmitFAbs(*this, V); 1299 Constant *Infinity = ConstantFP::getInfinity(V->getType()); 1300 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf) 1301 ? CmpInst::FCMP_OEQ 1302 : CmpInst::FCMP_ONE; 1303 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf"); 1304 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType()))); 1305 } 1306 1307 case Builtin::BI__builtin_isinf_sign: { 1308 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0 1309 Value *Arg = EmitScalarExpr(E->getArg(0)); 1310 Value *AbsArg = EmitFAbs(*this, Arg); 1311 Value *IsInf = Builder.CreateFCmpOEQ( 1312 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf"); 1313 Value *IsNeg = EmitSignBit(*this, Arg); 1314 1315 llvm::Type *IntTy = ConvertType(E->getType()); 1316 Value *Zero = Constant::getNullValue(IntTy); 1317 Value *One = ConstantInt::get(IntTy, 1); 1318 Value *NegativeOne = ConstantInt::get(IntTy, -1); 1319 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One); 1320 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero); 1321 return RValue::get(Result); 1322 } 1323 1324 case Builtin::BI__builtin_isnormal: { 1325 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 1326 Value *V = EmitScalarExpr(E->getArg(0)); 1327 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 1328 1329 Value *Abs = EmitFAbs(*this, V); 1330 Value *IsLessThanInf = 1331 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 1332 APFloat Smallest = APFloat::getSmallestNormalized( 1333 getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 1334 Value *IsNormal = 1335 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 1336 "isnormal"); 1337 V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 1338 V = Builder.CreateAnd(V, IsNormal, "and"); 1339 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1340 } 1341 1342 case Builtin::BI__builtin_fpclassify: { 1343 Value *V = EmitScalarExpr(E->getArg(5)); 1344 llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 1345 1346 // Create Result 1347 BasicBlock *Begin = Builder.GetInsertBlock(); 1348 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 1349 Builder.SetInsertPoint(End); 1350 PHINode *Result = 1351 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4, 1352 "fpclassify_result"); 1353 1354 // if (V==0) return FP_ZERO 1355 Builder.SetInsertPoint(Begin); 1356 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 1357 "iszero"); 1358 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 1359 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 1360 Builder.CreateCondBr(IsZero, End, NotZero); 1361 Result->addIncoming(ZeroLiteral, Begin); 1362 1363 // if (V != V) return FP_NAN 1364 Builder.SetInsertPoint(NotZero); 1365 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 1366 Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 1367 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 1368 Builder.CreateCondBr(IsNan, End, NotNan); 1369 Result->addIncoming(NanLiteral, NotZero); 1370 1371 // if (fabs(V) == infinity) return FP_INFINITY 1372 Builder.SetInsertPoint(NotNan); 1373 Value *VAbs = EmitFAbs(*this, V); 1374 Value *IsInf = 1375 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 1376 "isinf"); 1377 Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 1378 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 1379 Builder.CreateCondBr(IsInf, End, NotInf); 1380 Result->addIncoming(InfLiteral, NotNan); 1381 1382 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 1383 Builder.SetInsertPoint(NotInf); 1384 APFloat Smallest = APFloat::getSmallestNormalized( 1385 getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 1386 Value *IsNormal = 1387 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 1388 "isnormal"); 1389 Value *NormalResult = 1390 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 1391 EmitScalarExpr(E->getArg(3))); 1392 Builder.CreateBr(End); 1393 Result->addIncoming(NormalResult, NotInf); 1394 1395 // return Result 1396 Builder.SetInsertPoint(End); 1397 return RValue::get(Result); 1398 } 1399 1400 case Builtin::BIalloca: 1401 case Builtin::BI_alloca: 1402 case Builtin::BI__builtin_alloca: { 1403 Value *Size = EmitScalarExpr(E->getArg(0)); 1404 const TargetInfo &TI = getContext().getTargetInfo(); 1405 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__. 1406 unsigned SuitableAlignmentInBytes = 1407 CGM.getContext() 1408 .toCharUnitsFromBits(TI.getSuitableAlign()) 1409 .getQuantity(); 1410 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1411 AI->setAlignment(SuitableAlignmentInBytes); 1412 return RValue::get(AI); 1413 } 1414 1415 case Builtin::BI__builtin_alloca_with_align: { 1416 Value *Size = EmitScalarExpr(E->getArg(0)); 1417 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1)); 1418 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue); 1419 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue(); 1420 unsigned AlignmentInBytes = 1421 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity(); 1422 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1423 AI->setAlignment(AlignmentInBytes); 1424 return RValue::get(AI); 1425 } 1426 1427 case Builtin::BIbzero: 1428 case Builtin::BI__builtin_bzero: { 1429 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1430 Value *SizeVal = EmitScalarExpr(E->getArg(1)); 1431 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1432 E->getArg(0)->getExprLoc(), FD, 0); 1433 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false); 1434 return RValue::get(Dest.getPointer()); 1435 } 1436 case Builtin::BImemcpy: 1437 case Builtin::BI__builtin_memcpy: { 1438 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1439 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1440 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1441 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1442 E->getArg(0)->getExprLoc(), FD, 0); 1443 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1444 E->getArg(1)->getExprLoc(), FD, 1); 1445 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1446 return RValue::get(Dest.getPointer()); 1447 } 1448 1449 case Builtin::BI__builtin_char_memchr: 1450 BuiltinID = Builtin::BI__builtin_memchr; 1451 break; 1452 1453 case Builtin::BI__builtin___memcpy_chk: { 1454 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. 1455 llvm::APSInt Size, DstSize; 1456 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1457 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1458 break; 1459 if (Size.ugt(DstSize)) 1460 break; 1461 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1462 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1463 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1464 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1465 return RValue::get(Dest.getPointer()); 1466 } 1467 1468 case Builtin::BI__builtin_objc_memmove_collectable: { 1469 Address DestAddr = EmitPointerWithAlignment(E->getArg(0)); 1470 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1)); 1471 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1472 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 1473 DestAddr, SrcAddr, SizeVal); 1474 return RValue::get(DestAddr.getPointer()); 1475 } 1476 1477 case Builtin::BI__builtin___memmove_chk: { 1478 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. 1479 llvm::APSInt Size, DstSize; 1480 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1481 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1482 break; 1483 if (Size.ugt(DstSize)) 1484 break; 1485 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1486 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1487 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1488 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1489 return RValue::get(Dest.getPointer()); 1490 } 1491 1492 case Builtin::BImemmove: 1493 case Builtin::BI__builtin_memmove: { 1494 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1495 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1496 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1497 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1498 E->getArg(0)->getExprLoc(), FD, 0); 1499 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1500 E->getArg(1)->getExprLoc(), FD, 1); 1501 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1502 return RValue::get(Dest.getPointer()); 1503 } 1504 case Builtin::BImemset: 1505 case Builtin::BI__builtin_memset: { 1506 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1507 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1508 Builder.getInt8Ty()); 1509 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1510 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1511 E->getArg(0)->getExprLoc(), FD, 0); 1512 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1513 return RValue::get(Dest.getPointer()); 1514 } 1515 case Builtin::BI__builtin___memset_chk: { 1516 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. 1517 llvm::APSInt Size, DstSize; 1518 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1519 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1520 break; 1521 if (Size.ugt(DstSize)) 1522 break; 1523 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1524 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1525 Builder.getInt8Ty()); 1526 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1527 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1528 return RValue::get(Dest.getPointer()); 1529 } 1530 case Builtin::BI__builtin_dwarf_cfa: { 1531 // The offset in bytes from the first argument to the CFA. 1532 // 1533 // Why on earth is this in the frontend? Is there any reason at 1534 // all that the backend can't reasonably determine this while 1535 // lowering llvm.eh.dwarf.cfa()? 1536 // 1537 // TODO: If there's a satisfactory reason, add a target hook for 1538 // this instead of hard-coding 0, which is correct for most targets. 1539 int32_t Offset = 0; 1540 1541 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa); 1542 return RValue::get(Builder.CreateCall(F, 1543 llvm::ConstantInt::get(Int32Ty, Offset))); 1544 } 1545 case Builtin::BI__builtin_return_address: { 1546 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), 1547 getContext().UnsignedIntTy); 1548 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1549 return RValue::get(Builder.CreateCall(F, Depth)); 1550 } 1551 case Builtin::BI_ReturnAddress: { 1552 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1553 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0))); 1554 } 1555 case Builtin::BI__builtin_frame_address: { 1556 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), 1557 getContext().UnsignedIntTy); 1558 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress); 1559 return RValue::get(Builder.CreateCall(F, Depth)); 1560 } 1561 case Builtin::BI__builtin_extract_return_addr: { 1562 Value *Address = EmitScalarExpr(E->getArg(0)); 1563 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 1564 return RValue::get(Result); 1565 } 1566 case Builtin::BI__builtin_frob_return_addr: { 1567 Value *Address = EmitScalarExpr(E->getArg(0)); 1568 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 1569 return RValue::get(Result); 1570 } 1571 case Builtin::BI__builtin_dwarf_sp_column: { 1572 llvm::IntegerType *Ty 1573 = cast<llvm::IntegerType>(ConvertType(E->getType())); 1574 int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 1575 if (Column == -1) { 1576 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 1577 return RValue::get(llvm::UndefValue::get(Ty)); 1578 } 1579 return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 1580 } 1581 case Builtin::BI__builtin_init_dwarf_reg_size_table: { 1582 Value *Address = EmitScalarExpr(E->getArg(0)); 1583 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 1584 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 1585 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 1586 } 1587 case Builtin::BI__builtin_eh_return: { 1588 Value *Int = EmitScalarExpr(E->getArg(0)); 1589 Value *Ptr = EmitScalarExpr(E->getArg(1)); 1590 1591 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 1592 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 1593 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 1594 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 1595 ? Intrinsic::eh_return_i32 1596 : Intrinsic::eh_return_i64); 1597 Builder.CreateCall(F, {Int, Ptr}); 1598 Builder.CreateUnreachable(); 1599 1600 // We do need to preserve an insertion point. 1601 EmitBlock(createBasicBlock("builtin_eh_return.cont")); 1602 1603 return RValue::get(nullptr); 1604 } 1605 case Builtin::BI__builtin_unwind_init: { 1606 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init); 1607 return RValue::get(Builder.CreateCall(F)); 1608 } 1609 case Builtin::BI__builtin_extend_pointer: { 1610 // Extends a pointer to the size of an _Unwind_Word, which is 1611 // uint64_t on all platforms. Generally this gets poked into a 1612 // register and eventually used as an address, so if the 1613 // addressing registers are wider than pointers and the platform 1614 // doesn't implicitly ignore high-order bits when doing 1615 // addressing, we need to make sure we zext / sext based on 1616 // the platform's expectations. 1617 // 1618 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 1619 1620 // Cast the pointer to intptr_t. 1621 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1622 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 1623 1624 // If that's 64 bits, we're done. 1625 if (IntPtrTy->getBitWidth() == 64) 1626 return RValue::get(Result); 1627 1628 // Otherwise, ask the codegen data what to do. 1629 if (getTargetHooks().extendPointerWithSExt()) 1630 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 1631 else 1632 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 1633 } 1634 case Builtin::BI__builtin_setjmp: { 1635 // Buffer is a void**. 1636 Address Buf = EmitPointerWithAlignment(E->getArg(0)); 1637 1638 // Store the frame pointer to the setjmp buffer. 1639 Value *FrameAddr = 1640 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 1641 ConstantInt::get(Int32Ty, 0)); 1642 Builder.CreateStore(FrameAddr, Buf); 1643 1644 // Store the stack pointer to the setjmp buffer. 1645 Value *StackAddr = 1646 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 1647 Address StackSaveSlot = 1648 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize()); 1649 Builder.CreateStore(StackAddr, StackSaveSlot); 1650 1651 // Call LLVM's EH setjmp, which is lightweight. 1652 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 1653 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1654 return RValue::get(Builder.CreateCall(F, Buf.getPointer())); 1655 } 1656 case Builtin::BI__builtin_longjmp: { 1657 Value *Buf = EmitScalarExpr(E->getArg(0)); 1658 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1659 1660 // Call LLVM's EH longjmp, which is lightweight. 1661 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 1662 1663 // longjmp doesn't return; mark this as unreachable. 1664 Builder.CreateUnreachable(); 1665 1666 // We do need to preserve an insertion point. 1667 EmitBlock(createBasicBlock("longjmp.cont")); 1668 1669 return RValue::get(nullptr); 1670 } 1671 case Builtin::BI__sync_fetch_and_add: 1672 case Builtin::BI__sync_fetch_and_sub: 1673 case Builtin::BI__sync_fetch_and_or: 1674 case Builtin::BI__sync_fetch_and_and: 1675 case Builtin::BI__sync_fetch_and_xor: 1676 case Builtin::BI__sync_fetch_and_nand: 1677 case Builtin::BI__sync_add_and_fetch: 1678 case Builtin::BI__sync_sub_and_fetch: 1679 case Builtin::BI__sync_and_and_fetch: 1680 case Builtin::BI__sync_or_and_fetch: 1681 case Builtin::BI__sync_xor_and_fetch: 1682 case Builtin::BI__sync_nand_and_fetch: 1683 case Builtin::BI__sync_val_compare_and_swap: 1684 case Builtin::BI__sync_bool_compare_and_swap: 1685 case Builtin::BI__sync_lock_test_and_set: 1686 case Builtin::BI__sync_lock_release: 1687 case Builtin::BI__sync_swap: 1688 llvm_unreachable("Shouldn't make it through sema"); 1689 case Builtin::BI__sync_fetch_and_add_1: 1690 case Builtin::BI__sync_fetch_and_add_2: 1691 case Builtin::BI__sync_fetch_and_add_4: 1692 case Builtin::BI__sync_fetch_and_add_8: 1693 case Builtin::BI__sync_fetch_and_add_16: 1694 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E); 1695 case Builtin::BI__sync_fetch_and_sub_1: 1696 case Builtin::BI__sync_fetch_and_sub_2: 1697 case Builtin::BI__sync_fetch_and_sub_4: 1698 case Builtin::BI__sync_fetch_and_sub_8: 1699 case Builtin::BI__sync_fetch_and_sub_16: 1700 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E); 1701 case Builtin::BI__sync_fetch_and_or_1: 1702 case Builtin::BI__sync_fetch_and_or_2: 1703 case Builtin::BI__sync_fetch_and_or_4: 1704 case Builtin::BI__sync_fetch_and_or_8: 1705 case Builtin::BI__sync_fetch_and_or_16: 1706 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E); 1707 case Builtin::BI__sync_fetch_and_and_1: 1708 case Builtin::BI__sync_fetch_and_and_2: 1709 case Builtin::BI__sync_fetch_and_and_4: 1710 case Builtin::BI__sync_fetch_and_and_8: 1711 case Builtin::BI__sync_fetch_and_and_16: 1712 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E); 1713 case Builtin::BI__sync_fetch_and_xor_1: 1714 case Builtin::BI__sync_fetch_and_xor_2: 1715 case Builtin::BI__sync_fetch_and_xor_4: 1716 case Builtin::BI__sync_fetch_and_xor_8: 1717 case Builtin::BI__sync_fetch_and_xor_16: 1718 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E); 1719 case Builtin::BI__sync_fetch_and_nand_1: 1720 case Builtin::BI__sync_fetch_and_nand_2: 1721 case Builtin::BI__sync_fetch_and_nand_4: 1722 case Builtin::BI__sync_fetch_and_nand_8: 1723 case Builtin::BI__sync_fetch_and_nand_16: 1724 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E); 1725 1726 // Clang extensions: not overloaded yet. 1727 case Builtin::BI__sync_fetch_and_min: 1728 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E); 1729 case Builtin::BI__sync_fetch_and_max: 1730 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E); 1731 case Builtin::BI__sync_fetch_and_umin: 1732 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E); 1733 case Builtin::BI__sync_fetch_and_umax: 1734 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E); 1735 1736 case Builtin::BI__sync_add_and_fetch_1: 1737 case Builtin::BI__sync_add_and_fetch_2: 1738 case Builtin::BI__sync_add_and_fetch_4: 1739 case Builtin::BI__sync_add_and_fetch_8: 1740 case Builtin::BI__sync_add_and_fetch_16: 1741 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E, 1742 llvm::Instruction::Add); 1743 case Builtin::BI__sync_sub_and_fetch_1: 1744 case Builtin::BI__sync_sub_and_fetch_2: 1745 case Builtin::BI__sync_sub_and_fetch_4: 1746 case Builtin::BI__sync_sub_and_fetch_8: 1747 case Builtin::BI__sync_sub_and_fetch_16: 1748 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E, 1749 llvm::Instruction::Sub); 1750 case Builtin::BI__sync_and_and_fetch_1: 1751 case Builtin::BI__sync_and_and_fetch_2: 1752 case Builtin::BI__sync_and_and_fetch_4: 1753 case Builtin::BI__sync_and_and_fetch_8: 1754 case Builtin::BI__sync_and_and_fetch_16: 1755 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E, 1756 llvm::Instruction::And); 1757 case Builtin::BI__sync_or_and_fetch_1: 1758 case Builtin::BI__sync_or_and_fetch_2: 1759 case Builtin::BI__sync_or_and_fetch_4: 1760 case Builtin::BI__sync_or_and_fetch_8: 1761 case Builtin::BI__sync_or_and_fetch_16: 1762 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E, 1763 llvm::Instruction::Or); 1764 case Builtin::BI__sync_xor_and_fetch_1: 1765 case Builtin::BI__sync_xor_and_fetch_2: 1766 case Builtin::BI__sync_xor_and_fetch_4: 1767 case Builtin::BI__sync_xor_and_fetch_8: 1768 case Builtin::BI__sync_xor_and_fetch_16: 1769 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E, 1770 llvm::Instruction::Xor); 1771 case Builtin::BI__sync_nand_and_fetch_1: 1772 case Builtin::BI__sync_nand_and_fetch_2: 1773 case Builtin::BI__sync_nand_and_fetch_4: 1774 case Builtin::BI__sync_nand_and_fetch_8: 1775 case Builtin::BI__sync_nand_and_fetch_16: 1776 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E, 1777 llvm::Instruction::And, true); 1778 1779 case Builtin::BI__sync_val_compare_and_swap_1: 1780 case Builtin::BI__sync_val_compare_and_swap_2: 1781 case Builtin::BI__sync_val_compare_and_swap_4: 1782 case Builtin::BI__sync_val_compare_and_swap_8: 1783 case Builtin::BI__sync_val_compare_and_swap_16: 1784 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false)); 1785 1786 case Builtin::BI__sync_bool_compare_and_swap_1: 1787 case Builtin::BI__sync_bool_compare_and_swap_2: 1788 case Builtin::BI__sync_bool_compare_and_swap_4: 1789 case Builtin::BI__sync_bool_compare_and_swap_8: 1790 case Builtin::BI__sync_bool_compare_and_swap_16: 1791 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true)); 1792 1793 case Builtin::BI__sync_swap_1: 1794 case Builtin::BI__sync_swap_2: 1795 case Builtin::BI__sync_swap_4: 1796 case Builtin::BI__sync_swap_8: 1797 case Builtin::BI__sync_swap_16: 1798 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1799 1800 case Builtin::BI__sync_lock_test_and_set_1: 1801 case Builtin::BI__sync_lock_test_and_set_2: 1802 case Builtin::BI__sync_lock_test_and_set_4: 1803 case Builtin::BI__sync_lock_test_and_set_8: 1804 case Builtin::BI__sync_lock_test_and_set_16: 1805 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1806 1807 case Builtin::BI__sync_lock_release_1: 1808 case Builtin::BI__sync_lock_release_2: 1809 case Builtin::BI__sync_lock_release_4: 1810 case Builtin::BI__sync_lock_release_8: 1811 case Builtin::BI__sync_lock_release_16: { 1812 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1813 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 1814 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 1815 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 1816 StoreSize.getQuantity() * 8); 1817 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 1818 llvm::StoreInst *Store = 1819 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr, 1820 StoreSize); 1821 Store->setAtomic(llvm::AtomicOrdering::Release); 1822 return RValue::get(nullptr); 1823 } 1824 1825 case Builtin::BI__sync_synchronize: { 1826 // We assume this is supposed to correspond to a C++0x-style 1827 // sequentially-consistent fence (i.e. this is only usable for 1828 // synchonization, not device I/O or anything like that). This intrinsic 1829 // is really badly designed in the sense that in theory, there isn't 1830 // any way to safely use it... but in practice, it mostly works 1831 // to use it with non-atomic loads and stores to get acquire/release 1832 // semantics. 1833 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent); 1834 return RValue::get(nullptr); 1835 } 1836 1837 case Builtin::BI__builtin_nontemporal_load: 1838 return RValue::get(EmitNontemporalLoad(*this, E)); 1839 case Builtin::BI__builtin_nontemporal_store: 1840 return RValue::get(EmitNontemporalStore(*this, E)); 1841 case Builtin::BI__c11_atomic_is_lock_free: 1842 case Builtin::BI__atomic_is_lock_free: { 1843 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the 1844 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since 1845 // _Atomic(T) is always properly-aligned. 1846 const char *LibCallName = "__atomic_is_lock_free"; 1847 CallArgList Args; 1848 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))), 1849 getContext().getSizeType()); 1850 if (BuiltinID == Builtin::BI__atomic_is_lock_free) 1851 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))), 1852 getContext().VoidPtrTy); 1853 else 1854 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)), 1855 getContext().VoidPtrTy); 1856 const CGFunctionInfo &FuncInfo = 1857 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args); 1858 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); 1859 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); 1860 return EmitCall(FuncInfo, CGCallee::forDirect(Func), 1861 ReturnValueSlot(), Args); 1862 } 1863 1864 case Builtin::BI__atomic_test_and_set: { 1865 // Look at the argument type to determine whether this is a volatile 1866 // operation. The parameter type is always volatile. 1867 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1868 bool Volatile = 1869 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1870 1871 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1872 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 1873 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1874 Value *NewVal = Builder.getInt8(1); 1875 Value *Order = EmitScalarExpr(E->getArg(1)); 1876 if (isa<llvm::ConstantInt>(Order)) { 1877 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1878 AtomicRMWInst *Result = nullptr; 1879 switch (ord) { 1880 case 0: // memory_order_relaxed 1881 default: // invalid order 1882 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1883 llvm::AtomicOrdering::Monotonic); 1884 break; 1885 case 1: // memory_order_consume 1886 case 2: // memory_order_acquire 1887 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1888 llvm::AtomicOrdering::Acquire); 1889 break; 1890 case 3: // memory_order_release 1891 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1892 llvm::AtomicOrdering::Release); 1893 break; 1894 case 4: // memory_order_acq_rel 1895 1896 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1897 llvm::AtomicOrdering::AcquireRelease); 1898 break; 1899 case 5: // memory_order_seq_cst 1900 Result = Builder.CreateAtomicRMW( 1901 llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1902 llvm::AtomicOrdering::SequentiallyConsistent); 1903 break; 1904 } 1905 Result->setVolatile(Volatile); 1906 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1907 } 1908 1909 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1910 1911 llvm::BasicBlock *BBs[5] = { 1912 createBasicBlock("monotonic", CurFn), 1913 createBasicBlock("acquire", CurFn), 1914 createBasicBlock("release", CurFn), 1915 createBasicBlock("acqrel", CurFn), 1916 createBasicBlock("seqcst", CurFn) 1917 }; 1918 llvm::AtomicOrdering Orders[5] = { 1919 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire, 1920 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease, 1921 llvm::AtomicOrdering::SequentiallyConsistent}; 1922 1923 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1924 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1925 1926 Builder.SetInsertPoint(ContBB); 1927 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set"); 1928 1929 for (unsigned i = 0; i < 5; ++i) { 1930 Builder.SetInsertPoint(BBs[i]); 1931 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1932 Ptr, NewVal, Orders[i]); 1933 RMW->setVolatile(Volatile); 1934 Result->addIncoming(RMW, BBs[i]); 1935 Builder.CreateBr(ContBB); 1936 } 1937 1938 SI->addCase(Builder.getInt32(0), BBs[0]); 1939 SI->addCase(Builder.getInt32(1), BBs[1]); 1940 SI->addCase(Builder.getInt32(2), BBs[1]); 1941 SI->addCase(Builder.getInt32(3), BBs[2]); 1942 SI->addCase(Builder.getInt32(4), BBs[3]); 1943 SI->addCase(Builder.getInt32(5), BBs[4]); 1944 1945 Builder.SetInsertPoint(ContBB); 1946 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1947 } 1948 1949 case Builtin::BI__atomic_clear: { 1950 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1951 bool Volatile = 1952 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1953 1954 Address Ptr = EmitPointerWithAlignment(E->getArg(0)); 1955 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace(); 1956 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1957 Value *NewVal = Builder.getInt8(0); 1958 Value *Order = EmitScalarExpr(E->getArg(1)); 1959 if (isa<llvm::ConstantInt>(Order)) { 1960 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1961 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1962 switch (ord) { 1963 case 0: // memory_order_relaxed 1964 default: // invalid order 1965 Store->setOrdering(llvm::AtomicOrdering::Monotonic); 1966 break; 1967 case 3: // memory_order_release 1968 Store->setOrdering(llvm::AtomicOrdering::Release); 1969 break; 1970 case 5: // memory_order_seq_cst 1971 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent); 1972 break; 1973 } 1974 return RValue::get(nullptr); 1975 } 1976 1977 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1978 1979 llvm::BasicBlock *BBs[3] = { 1980 createBasicBlock("monotonic", CurFn), 1981 createBasicBlock("release", CurFn), 1982 createBasicBlock("seqcst", CurFn) 1983 }; 1984 llvm::AtomicOrdering Orders[3] = { 1985 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release, 1986 llvm::AtomicOrdering::SequentiallyConsistent}; 1987 1988 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1989 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1990 1991 for (unsigned i = 0; i < 3; ++i) { 1992 Builder.SetInsertPoint(BBs[i]); 1993 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1994 Store->setOrdering(Orders[i]); 1995 Builder.CreateBr(ContBB); 1996 } 1997 1998 SI->addCase(Builder.getInt32(0), BBs[0]); 1999 SI->addCase(Builder.getInt32(3), BBs[1]); 2000 SI->addCase(Builder.getInt32(5), BBs[2]); 2001 2002 Builder.SetInsertPoint(ContBB); 2003 return RValue::get(nullptr); 2004 } 2005 2006 case Builtin::BI__atomic_thread_fence: 2007 case Builtin::BI__atomic_signal_fence: 2008 case Builtin::BI__c11_atomic_thread_fence: 2009 case Builtin::BI__c11_atomic_signal_fence: { 2010 llvm::SyncScope::ID SSID; 2011 if (BuiltinID == Builtin::BI__atomic_signal_fence || 2012 BuiltinID == Builtin::BI__c11_atomic_signal_fence) 2013 SSID = llvm::SyncScope::SingleThread; 2014 else 2015 SSID = llvm::SyncScope::System; 2016 Value *Order = EmitScalarExpr(E->getArg(0)); 2017 if (isa<llvm::ConstantInt>(Order)) { 2018 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 2019 switch (ord) { 2020 case 0: // memory_order_relaxed 2021 default: // invalid order 2022 break; 2023 case 1: // memory_order_consume 2024 case 2: // memory_order_acquire 2025 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID); 2026 break; 2027 case 3: // memory_order_release 2028 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID); 2029 break; 2030 case 4: // memory_order_acq_rel 2031 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID); 2032 break; 2033 case 5: // memory_order_seq_cst 2034 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID); 2035 break; 2036 } 2037 return RValue::get(nullptr); 2038 } 2039 2040 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB; 2041 AcquireBB = createBasicBlock("acquire", CurFn); 2042 ReleaseBB = createBasicBlock("release", CurFn); 2043 AcqRelBB = createBasicBlock("acqrel", CurFn); 2044 SeqCstBB = createBasicBlock("seqcst", CurFn); 2045 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 2046 2047 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 2048 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB); 2049 2050 Builder.SetInsertPoint(AcquireBB); 2051 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID); 2052 Builder.CreateBr(ContBB); 2053 SI->addCase(Builder.getInt32(1), AcquireBB); 2054 SI->addCase(Builder.getInt32(2), AcquireBB); 2055 2056 Builder.SetInsertPoint(ReleaseBB); 2057 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID); 2058 Builder.CreateBr(ContBB); 2059 SI->addCase(Builder.getInt32(3), ReleaseBB); 2060 2061 Builder.SetInsertPoint(AcqRelBB); 2062 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID); 2063 Builder.CreateBr(ContBB); 2064 SI->addCase(Builder.getInt32(4), AcqRelBB); 2065 2066 Builder.SetInsertPoint(SeqCstBB); 2067 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID); 2068 Builder.CreateBr(ContBB); 2069 SI->addCase(Builder.getInt32(5), SeqCstBB); 2070 2071 Builder.SetInsertPoint(ContBB); 2072 return RValue::get(nullptr); 2073 } 2074 2075 case Builtin::BIsqrt: 2076 case Builtin::BIsqrtf: 2077 case Builtin::BIsqrtl: 2078 // Builtins have the same semantics as library functions. The LLVM intrinsic 2079 // has the same semantics as the library function except it does not set 2080 // errno. Thus, we can transform either sqrt or __builtin_sqrt to @llvm.sqrt 2081 // if the call is 'const' (the call must not set errno). 2082 // 2083 // FIXME: The builtin cases are not here because they are marked 'const' in 2084 // Builtins.def. So that means they are wrongly defined to have different 2085 // semantics than the library functions. If we included them here, we would 2086 // turn them into LLVM intrinsics regardless of whether -fmath-errno was on. 2087 if (FD->hasAttr<ConstAttr>()) 2088 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::sqrt)); 2089 break; 2090 2091 case Builtin::BI__builtin_pow: 2092 case Builtin::BI__builtin_powf: 2093 case Builtin::BI__builtin_powl: 2094 case Builtin::BIpow: 2095 case Builtin::BIpowf: 2096 case Builtin::BIpowl: { 2097 // Transform a call to pow* into a @llvm.pow.* intrinsic call. 2098 if (!FD->hasAttr<ConstAttr>()) 2099 break; 2100 Value *Base = EmitScalarExpr(E->getArg(0)); 2101 Value *Exponent = EmitScalarExpr(E->getArg(1)); 2102 llvm::Type *ArgType = Base->getType(); 2103 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 2104 return RValue::get(Builder.CreateCall(F, {Base, Exponent})); 2105 } 2106 2107 case Builtin::BIfma: 2108 case Builtin::BIfmaf: 2109 case Builtin::BIfmal: 2110 case Builtin::BI__builtin_fma: 2111 case Builtin::BI__builtin_fmaf: 2112 case Builtin::BI__builtin_fmal: { 2113 // Rewrite fma to intrinsic. 2114 Value *FirstArg = EmitScalarExpr(E->getArg(0)); 2115 llvm::Type *ArgType = FirstArg->getType(); 2116 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 2117 return RValue::get( 2118 Builder.CreateCall(F, {FirstArg, EmitScalarExpr(E->getArg(1)), 2119 EmitScalarExpr(E->getArg(2))})); 2120 } 2121 2122 case Builtin::BI__builtin_signbit: 2123 case Builtin::BI__builtin_signbitf: 2124 case Builtin::BI__builtin_signbitl: { 2125 return RValue::get( 2126 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))), 2127 ConvertType(E->getType()))); 2128 } 2129 case Builtin::BI__annotation: { 2130 // Re-encode each wide string to UTF8 and make an MDString. 2131 SmallVector<Metadata *, 1> Strings; 2132 for (const Expr *Arg : E->arguments()) { 2133 const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts()); 2134 assert(Str->getCharByteWidth() == 2); 2135 StringRef WideBytes = Str->getBytes(); 2136 std::string StrUtf8; 2137 if (!convertUTF16ToUTF8String( 2138 makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) { 2139 CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument"); 2140 continue; 2141 } 2142 Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8)); 2143 } 2144 2145 // Build and MDTuple of MDStrings and emit the intrinsic call. 2146 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {}); 2147 MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings); 2148 Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple)); 2149 return RValue::getIgnored(); 2150 } 2151 case Builtin::BI__builtin_annotation: { 2152 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 2153 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 2154 AnnVal->getType()); 2155 2156 // Get the annotation string, go through casts. Sema requires this to be a 2157 // non-wide string literal, potentially casted, so the cast<> is safe. 2158 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 2159 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 2160 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 2161 } 2162 case Builtin::BI__builtin_addcb: 2163 case Builtin::BI__builtin_addcs: 2164 case Builtin::BI__builtin_addc: 2165 case Builtin::BI__builtin_addcl: 2166 case Builtin::BI__builtin_addcll: 2167 case Builtin::BI__builtin_subcb: 2168 case Builtin::BI__builtin_subcs: 2169 case Builtin::BI__builtin_subc: 2170 case Builtin::BI__builtin_subcl: 2171 case Builtin::BI__builtin_subcll: { 2172 2173 // We translate all of these builtins from expressions of the form: 2174 // int x = ..., y = ..., carryin = ..., carryout, result; 2175 // result = __builtin_addc(x, y, carryin, &carryout); 2176 // 2177 // to LLVM IR of the form: 2178 // 2179 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 2180 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 2181 // %carry1 = extractvalue {i32, i1} %tmp1, 1 2182 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 2183 // i32 %carryin) 2184 // %result = extractvalue {i32, i1} %tmp2, 0 2185 // %carry2 = extractvalue {i32, i1} %tmp2, 1 2186 // %tmp3 = or i1 %carry1, %carry2 2187 // %tmp4 = zext i1 %tmp3 to i32 2188 // store i32 %tmp4, i32* %carryout 2189 2190 // Scalarize our inputs. 2191 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2192 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2193 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 2194 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3)); 2195 2196 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 2197 llvm::Intrinsic::ID IntrinsicId; 2198 switch (BuiltinID) { 2199 default: llvm_unreachable("Unknown multiprecision builtin id."); 2200 case Builtin::BI__builtin_addcb: 2201 case Builtin::BI__builtin_addcs: 2202 case Builtin::BI__builtin_addc: 2203 case Builtin::BI__builtin_addcl: 2204 case Builtin::BI__builtin_addcll: 2205 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2206 break; 2207 case Builtin::BI__builtin_subcb: 2208 case Builtin::BI__builtin_subcs: 2209 case Builtin::BI__builtin_subc: 2210 case Builtin::BI__builtin_subcl: 2211 case Builtin::BI__builtin_subcll: 2212 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2213 break; 2214 } 2215 2216 // Construct our resulting LLVM IR expression. 2217 llvm::Value *Carry1; 2218 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 2219 X, Y, Carry1); 2220 llvm::Value *Carry2; 2221 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 2222 Sum1, Carryin, Carry2); 2223 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 2224 X->getType()); 2225 Builder.CreateStore(CarryOut, CarryOutPtr); 2226 return RValue::get(Sum2); 2227 } 2228 2229 case Builtin::BI__builtin_add_overflow: 2230 case Builtin::BI__builtin_sub_overflow: 2231 case Builtin::BI__builtin_mul_overflow: { 2232 const clang::Expr *LeftArg = E->getArg(0); 2233 const clang::Expr *RightArg = E->getArg(1); 2234 const clang::Expr *ResultArg = E->getArg(2); 2235 2236 clang::QualType ResultQTy = 2237 ResultArg->getType()->castAs<PointerType>()->getPointeeType(); 2238 2239 WidthAndSignedness LeftInfo = 2240 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType()); 2241 WidthAndSignedness RightInfo = 2242 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType()); 2243 WidthAndSignedness ResultInfo = 2244 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy); 2245 WidthAndSignedness EncompassingInfo = 2246 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo}); 2247 2248 llvm::Type *EncompassingLLVMTy = 2249 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width); 2250 2251 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy); 2252 2253 llvm::Intrinsic::ID IntrinsicId; 2254 switch (BuiltinID) { 2255 default: 2256 llvm_unreachable("Unknown overflow builtin id."); 2257 case Builtin::BI__builtin_add_overflow: 2258 IntrinsicId = EncompassingInfo.Signed 2259 ? llvm::Intrinsic::sadd_with_overflow 2260 : llvm::Intrinsic::uadd_with_overflow; 2261 break; 2262 case Builtin::BI__builtin_sub_overflow: 2263 IntrinsicId = EncompassingInfo.Signed 2264 ? llvm::Intrinsic::ssub_with_overflow 2265 : llvm::Intrinsic::usub_with_overflow; 2266 break; 2267 case Builtin::BI__builtin_mul_overflow: 2268 IntrinsicId = EncompassingInfo.Signed 2269 ? llvm::Intrinsic::smul_with_overflow 2270 : llvm::Intrinsic::umul_with_overflow; 2271 break; 2272 } 2273 2274 llvm::Value *Left = EmitScalarExpr(LeftArg); 2275 llvm::Value *Right = EmitScalarExpr(RightArg); 2276 Address ResultPtr = EmitPointerWithAlignment(ResultArg); 2277 2278 // Extend each operand to the encompassing type. 2279 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed); 2280 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed); 2281 2282 // Perform the operation on the extended values. 2283 llvm::Value *Overflow, *Result; 2284 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow); 2285 2286 if (EncompassingInfo.Width > ResultInfo.Width) { 2287 // The encompassing type is wider than the result type, so we need to 2288 // truncate it. 2289 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy); 2290 2291 // To see if the truncation caused an overflow, we will extend 2292 // the result and then compare it to the original result. 2293 llvm::Value *ResultTruncExt = Builder.CreateIntCast( 2294 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed); 2295 llvm::Value *TruncationOverflow = 2296 Builder.CreateICmpNE(Result, ResultTruncExt); 2297 2298 Overflow = Builder.CreateOr(Overflow, TruncationOverflow); 2299 Result = ResultTrunc; 2300 } 2301 2302 // Finally, store the result using the pointer. 2303 bool isVolatile = 2304 ResultArg->getType()->getPointeeType().isVolatileQualified(); 2305 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile); 2306 2307 return RValue::get(Overflow); 2308 } 2309 2310 case Builtin::BI__builtin_uadd_overflow: 2311 case Builtin::BI__builtin_uaddl_overflow: 2312 case Builtin::BI__builtin_uaddll_overflow: 2313 case Builtin::BI__builtin_usub_overflow: 2314 case Builtin::BI__builtin_usubl_overflow: 2315 case Builtin::BI__builtin_usubll_overflow: 2316 case Builtin::BI__builtin_umul_overflow: 2317 case Builtin::BI__builtin_umull_overflow: 2318 case Builtin::BI__builtin_umulll_overflow: 2319 case Builtin::BI__builtin_sadd_overflow: 2320 case Builtin::BI__builtin_saddl_overflow: 2321 case Builtin::BI__builtin_saddll_overflow: 2322 case Builtin::BI__builtin_ssub_overflow: 2323 case Builtin::BI__builtin_ssubl_overflow: 2324 case Builtin::BI__builtin_ssubll_overflow: 2325 case Builtin::BI__builtin_smul_overflow: 2326 case Builtin::BI__builtin_smull_overflow: 2327 case Builtin::BI__builtin_smulll_overflow: { 2328 2329 // We translate all of these builtins directly to the relevant llvm IR node. 2330 2331 // Scalarize our inputs. 2332 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2333 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2334 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2)); 2335 2336 // Decide which of the overflow intrinsics we are lowering to: 2337 llvm::Intrinsic::ID IntrinsicId; 2338 switch (BuiltinID) { 2339 default: llvm_unreachable("Unknown overflow builtin id."); 2340 case Builtin::BI__builtin_uadd_overflow: 2341 case Builtin::BI__builtin_uaddl_overflow: 2342 case Builtin::BI__builtin_uaddll_overflow: 2343 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2344 break; 2345 case Builtin::BI__builtin_usub_overflow: 2346 case Builtin::BI__builtin_usubl_overflow: 2347 case Builtin::BI__builtin_usubll_overflow: 2348 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2349 break; 2350 case Builtin::BI__builtin_umul_overflow: 2351 case Builtin::BI__builtin_umull_overflow: 2352 case Builtin::BI__builtin_umulll_overflow: 2353 IntrinsicId = llvm::Intrinsic::umul_with_overflow; 2354 break; 2355 case Builtin::BI__builtin_sadd_overflow: 2356 case Builtin::BI__builtin_saddl_overflow: 2357 case Builtin::BI__builtin_saddll_overflow: 2358 IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 2359 break; 2360 case Builtin::BI__builtin_ssub_overflow: 2361 case Builtin::BI__builtin_ssubl_overflow: 2362 case Builtin::BI__builtin_ssubll_overflow: 2363 IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 2364 break; 2365 case Builtin::BI__builtin_smul_overflow: 2366 case Builtin::BI__builtin_smull_overflow: 2367 case Builtin::BI__builtin_smulll_overflow: 2368 IntrinsicId = llvm::Intrinsic::smul_with_overflow; 2369 break; 2370 } 2371 2372 2373 llvm::Value *Carry; 2374 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 2375 Builder.CreateStore(Sum, SumOutPtr); 2376 2377 return RValue::get(Carry); 2378 } 2379 case Builtin::BI__builtin_addressof: 2380 return RValue::get(EmitLValue(E->getArg(0)).getPointer()); 2381 case Builtin::BI__builtin_operator_new: 2382 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2383 E->getArg(0), false); 2384 case Builtin::BI__builtin_operator_delete: 2385 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2386 E->getArg(0), true); 2387 case Builtin::BI__noop: 2388 // __noop always evaluates to an integer literal zero. 2389 return RValue::get(ConstantInt::get(IntTy, 0)); 2390 case Builtin::BI__builtin_call_with_static_chain: { 2391 const CallExpr *Call = cast<CallExpr>(E->getArg(0)); 2392 const Expr *Chain = E->getArg(1); 2393 return EmitCall(Call->getCallee()->getType(), 2394 EmitCallee(Call->getCallee()), Call, ReturnValue, 2395 EmitScalarExpr(Chain)); 2396 } 2397 case Builtin::BI_InterlockedExchange8: 2398 case Builtin::BI_InterlockedExchange16: 2399 case Builtin::BI_InterlockedExchange: 2400 case Builtin::BI_InterlockedExchangePointer: 2401 return RValue::get( 2402 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E)); 2403 case Builtin::BI_InterlockedCompareExchangePointer: { 2404 llvm::Type *RTy; 2405 llvm::IntegerType *IntType = 2406 IntegerType::get(getLLVMContext(), 2407 getContext().getTypeSize(E->getType())); 2408 llvm::Type *IntPtrType = IntType->getPointerTo(); 2409 2410 llvm::Value *Destination = 2411 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType); 2412 2413 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1)); 2414 RTy = Exchange->getType(); 2415 Exchange = Builder.CreatePtrToInt(Exchange, IntType); 2416 2417 llvm::Value *Comparand = 2418 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType); 2419 2420 auto Result = 2421 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange, 2422 AtomicOrdering::SequentiallyConsistent, 2423 AtomicOrdering::SequentiallyConsistent); 2424 Result->setVolatile(true); 2425 2426 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result, 2427 0), 2428 RTy)); 2429 } 2430 case Builtin::BI_InterlockedCompareExchange8: 2431 case Builtin::BI_InterlockedCompareExchange16: 2432 case Builtin::BI_InterlockedCompareExchange: 2433 case Builtin::BI_InterlockedCompareExchange64: { 2434 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg( 2435 EmitScalarExpr(E->getArg(0)), 2436 EmitScalarExpr(E->getArg(2)), 2437 EmitScalarExpr(E->getArg(1)), 2438 AtomicOrdering::SequentiallyConsistent, 2439 AtomicOrdering::SequentiallyConsistent); 2440 CXI->setVolatile(true); 2441 return RValue::get(Builder.CreateExtractValue(CXI, 0)); 2442 } 2443 case Builtin::BI_InterlockedIncrement16: 2444 case Builtin::BI_InterlockedIncrement: 2445 return RValue::get( 2446 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E)); 2447 case Builtin::BI_InterlockedDecrement16: 2448 case Builtin::BI_InterlockedDecrement: 2449 return RValue::get( 2450 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E)); 2451 case Builtin::BI_InterlockedAnd8: 2452 case Builtin::BI_InterlockedAnd16: 2453 case Builtin::BI_InterlockedAnd: 2454 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E)); 2455 case Builtin::BI_InterlockedExchangeAdd8: 2456 case Builtin::BI_InterlockedExchangeAdd16: 2457 case Builtin::BI_InterlockedExchangeAdd: 2458 return RValue::get( 2459 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E)); 2460 case Builtin::BI_InterlockedExchangeSub8: 2461 case Builtin::BI_InterlockedExchangeSub16: 2462 case Builtin::BI_InterlockedExchangeSub: 2463 return RValue::get( 2464 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E)); 2465 case Builtin::BI_InterlockedOr8: 2466 case Builtin::BI_InterlockedOr16: 2467 case Builtin::BI_InterlockedOr: 2468 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E)); 2469 case Builtin::BI_InterlockedXor8: 2470 case Builtin::BI_InterlockedXor16: 2471 case Builtin::BI_InterlockedXor: 2472 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E)); 2473 case Builtin::BI_interlockedbittestandset: 2474 return RValue::get( 2475 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E)); 2476 2477 case Builtin::BI__exception_code: 2478 case Builtin::BI_exception_code: 2479 return RValue::get(EmitSEHExceptionCode()); 2480 case Builtin::BI__exception_info: 2481 case Builtin::BI_exception_info: 2482 return RValue::get(EmitSEHExceptionInfo()); 2483 case Builtin::BI__abnormal_termination: 2484 case Builtin::BI_abnormal_termination: 2485 return RValue::get(EmitSEHAbnormalTermination()); 2486 case Builtin::BI_setjmpex: { 2487 if (getTarget().getTriple().isOSMSVCRT()) { 2488 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2489 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2490 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2491 llvm::Attribute::ReturnsTwice); 2492 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction( 2493 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2494 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true); 2495 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2496 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2497 llvm::Value *FrameAddr = 2498 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2499 ConstantInt::get(Int32Ty, 0)); 2500 llvm::Value *Args[] = {Buf, FrameAddr}; 2501 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args); 2502 CS.setAttributes(ReturnsTwiceAttr); 2503 return RValue::get(CS.getInstruction()); 2504 } 2505 break; 2506 } 2507 case Builtin::BI_setjmp: { 2508 if (getTarget().getTriple().isOSMSVCRT()) { 2509 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2510 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2511 llvm::Attribute::ReturnsTwice); 2512 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2513 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2514 llvm::CallSite CS; 2515 if (getTarget().getTriple().getArch() == llvm::Triple::x86) { 2516 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy}; 2517 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction( 2518 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true), 2519 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true); 2520 llvm::Value *Count = ConstantInt::get(IntTy, 0); 2521 llvm::Value *Args[] = {Buf, Count}; 2522 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args); 2523 } else { 2524 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2525 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( 2526 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2527 "_setjmp", ReturnsTwiceAttr, /*Local=*/true); 2528 llvm::Value *FrameAddr = 2529 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2530 ConstantInt::get(Int32Ty, 0)); 2531 llvm::Value *Args[] = {Buf, FrameAddr}; 2532 CS = EmitRuntimeCallOrInvoke(SetJmp, Args); 2533 } 2534 CS.setAttributes(ReturnsTwiceAttr); 2535 return RValue::get(CS.getInstruction()); 2536 } 2537 break; 2538 } 2539 2540 case Builtin::BI__GetExceptionInfo: { 2541 if (llvm::GlobalVariable *GV = 2542 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType())) 2543 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy)); 2544 break; 2545 } 2546 2547 case Builtin::BI__fastfail: 2548 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E)); 2549 2550 case Builtin::BI__builtin_coro_size: { 2551 auto & Context = getContext(); 2552 auto SizeTy = Context.getSizeType(); 2553 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy)); 2554 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T); 2555 return RValue::get(Builder.CreateCall(F)); 2556 } 2557 2558 case Builtin::BI__builtin_coro_id: 2559 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id); 2560 case Builtin::BI__builtin_coro_promise: 2561 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise); 2562 case Builtin::BI__builtin_coro_resume: 2563 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume); 2564 case Builtin::BI__builtin_coro_frame: 2565 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame); 2566 case Builtin::BI__builtin_coro_free: 2567 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free); 2568 case Builtin::BI__builtin_coro_destroy: 2569 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy); 2570 case Builtin::BI__builtin_coro_done: 2571 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done); 2572 case Builtin::BI__builtin_coro_alloc: 2573 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc); 2574 case Builtin::BI__builtin_coro_begin: 2575 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin); 2576 case Builtin::BI__builtin_coro_end: 2577 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end); 2578 case Builtin::BI__builtin_coro_suspend: 2579 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend); 2580 case Builtin::BI__builtin_coro_param: 2581 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param); 2582 2583 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions 2584 case Builtin::BIread_pipe: 2585 case Builtin::BIwrite_pipe: { 2586 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2587 *Arg1 = EmitScalarExpr(E->getArg(1)); 2588 CGOpenCLRuntime OpenCLRT(CGM); 2589 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2590 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2591 2592 // Type of the generic packet parameter. 2593 unsigned GenericAS = 2594 getContext().getTargetAddressSpace(LangAS::opencl_generic); 2595 llvm::Type *I8PTy = llvm::PointerType::get( 2596 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS); 2597 2598 // Testing which overloaded version we should generate the call for. 2599 if (2U == E->getNumArgs()) { 2600 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2" 2601 : "__write_pipe_2"; 2602 // Creating a generic function type to be able to call with any builtin or 2603 // user defined type. 2604 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty}; 2605 llvm::FunctionType *FTy = llvm::FunctionType::get( 2606 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2607 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy); 2608 return RValue::get( 2609 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2610 {Arg0, BCast, PacketSize, PacketAlign})); 2611 } else { 2612 assert(4 == E->getNumArgs() && 2613 "Illegal number of parameters to pipe function"); 2614 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4" 2615 : "__write_pipe_4"; 2616 2617 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy, 2618 Int32Ty, Int32Ty}; 2619 Value *Arg2 = EmitScalarExpr(E->getArg(2)), 2620 *Arg3 = EmitScalarExpr(E->getArg(3)); 2621 llvm::FunctionType *FTy = llvm::FunctionType::get( 2622 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2623 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy); 2624 // We know the third argument is an integer type, but we may need to cast 2625 // it to i32. 2626 if (Arg2->getType() != Int32Ty) 2627 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty); 2628 return RValue::get(Builder.CreateCall( 2629 CGM.CreateRuntimeFunction(FTy, Name), 2630 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign})); 2631 } 2632 } 2633 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write 2634 // functions 2635 case Builtin::BIreserve_read_pipe: 2636 case Builtin::BIreserve_write_pipe: 2637 case Builtin::BIwork_group_reserve_read_pipe: 2638 case Builtin::BIwork_group_reserve_write_pipe: 2639 case Builtin::BIsub_group_reserve_read_pipe: 2640 case Builtin::BIsub_group_reserve_write_pipe: { 2641 // Composing the mangled name for the function. 2642 const char *Name; 2643 if (BuiltinID == Builtin::BIreserve_read_pipe) 2644 Name = "__reserve_read_pipe"; 2645 else if (BuiltinID == Builtin::BIreserve_write_pipe) 2646 Name = "__reserve_write_pipe"; 2647 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe) 2648 Name = "__work_group_reserve_read_pipe"; 2649 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe) 2650 Name = "__work_group_reserve_write_pipe"; 2651 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe) 2652 Name = "__sub_group_reserve_read_pipe"; 2653 else 2654 Name = "__sub_group_reserve_write_pipe"; 2655 2656 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2657 *Arg1 = EmitScalarExpr(E->getArg(1)); 2658 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy); 2659 CGOpenCLRuntime OpenCLRT(CGM); 2660 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2661 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2662 2663 // Building the generic function prototype. 2664 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty}; 2665 llvm::FunctionType *FTy = llvm::FunctionType::get( 2666 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2667 // We know the second argument is an integer type, but we may need to cast 2668 // it to i32. 2669 if (Arg1->getType() != Int32Ty) 2670 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty); 2671 return RValue::get( 2672 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2673 {Arg0, Arg1, PacketSize, PacketAlign})); 2674 } 2675 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write 2676 // functions 2677 case Builtin::BIcommit_read_pipe: 2678 case Builtin::BIcommit_write_pipe: 2679 case Builtin::BIwork_group_commit_read_pipe: 2680 case Builtin::BIwork_group_commit_write_pipe: 2681 case Builtin::BIsub_group_commit_read_pipe: 2682 case Builtin::BIsub_group_commit_write_pipe: { 2683 const char *Name; 2684 if (BuiltinID == Builtin::BIcommit_read_pipe) 2685 Name = "__commit_read_pipe"; 2686 else if (BuiltinID == Builtin::BIcommit_write_pipe) 2687 Name = "__commit_write_pipe"; 2688 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe) 2689 Name = "__work_group_commit_read_pipe"; 2690 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe) 2691 Name = "__work_group_commit_write_pipe"; 2692 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe) 2693 Name = "__sub_group_commit_read_pipe"; 2694 else 2695 Name = "__sub_group_commit_write_pipe"; 2696 2697 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2698 *Arg1 = EmitScalarExpr(E->getArg(1)); 2699 CGOpenCLRuntime OpenCLRT(CGM); 2700 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2701 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2702 2703 // Building the generic function prototype. 2704 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty}; 2705 llvm::FunctionType *FTy = 2706 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 2707 llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2708 2709 return RValue::get( 2710 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2711 {Arg0, Arg1, PacketSize, PacketAlign})); 2712 } 2713 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions 2714 case Builtin::BIget_pipe_num_packets: 2715 case Builtin::BIget_pipe_max_packets: { 2716 const char *Name; 2717 if (BuiltinID == Builtin::BIget_pipe_num_packets) 2718 Name = "__get_pipe_num_packets"; 2719 else 2720 Name = "__get_pipe_max_packets"; 2721 2722 // Building the generic function prototype. 2723 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 2724 CGOpenCLRuntime OpenCLRT(CGM); 2725 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2726 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2727 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty}; 2728 llvm::FunctionType *FTy = llvm::FunctionType::get( 2729 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2730 2731 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2732 {Arg0, PacketSize, PacketAlign})); 2733 } 2734 2735 // OpenCL v2.0 s6.13.9 - Address space qualifier functions. 2736 case Builtin::BIto_global: 2737 case Builtin::BIto_local: 2738 case Builtin::BIto_private: { 2739 auto Arg0 = EmitScalarExpr(E->getArg(0)); 2740 auto NewArgT = llvm::PointerType::get(Int8Ty, 2741 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2742 auto NewRetT = llvm::PointerType::get(Int8Ty, 2743 CGM.getContext().getTargetAddressSpace( 2744 E->getType()->getPointeeType().getAddressSpace())); 2745 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false); 2746 llvm::Value *NewArg; 2747 if (Arg0->getType()->getPointerAddressSpace() != 2748 NewArgT->getPointerAddressSpace()) 2749 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT); 2750 else 2751 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT); 2752 auto NewName = std::string("__") + E->getDirectCallee()->getName().str(); 2753 auto NewCall = 2754 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg}); 2755 return RValue::get(Builder.CreateBitOrPointerCast(NewCall, 2756 ConvertType(E->getType()))); 2757 } 2758 2759 // OpenCL v2.0, s6.13.17 - Enqueue kernel function. 2760 // It contains four different overload formats specified in Table 6.13.17.1. 2761 case Builtin::BIenqueue_kernel: { 2762 StringRef Name; // Generated function call name 2763 unsigned NumArgs = E->getNumArgs(); 2764 2765 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy); 2766 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2767 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2768 2769 llvm::Value *Queue = EmitScalarExpr(E->getArg(0)); 2770 llvm::Value *Flags = EmitScalarExpr(E->getArg(1)); 2771 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2)); 2772 llvm::Value *Range = NDRangeL.getAddress().getPointer(); 2773 llvm::Type *RangeTy = NDRangeL.getAddress().getType(); 2774 2775 if (NumArgs == 4) { 2776 // The most basic form of the call with parameters: 2777 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void) 2778 Name = "__enqueue_kernel_basic"; 2779 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy, 2780 GenericVoidPtrTy}; 2781 llvm::FunctionType *FTy = llvm::FunctionType::get( 2782 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2783 2784 auto Info = 2785 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2786 llvm::Value *Kernel = 2787 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2788 llvm::Value *Block = 2789 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2790 2791 AttrBuilder B; 2792 B.addAttribute(Attribute::ByVal); 2793 llvm::AttributeList ByValAttrSet = 2794 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B); 2795 2796 auto RTCall = 2797 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet), 2798 {Queue, Flags, Range, Kernel, Block}); 2799 RTCall->setAttributes(ByValAttrSet); 2800 return RValue::get(RTCall); 2801 } 2802 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature"); 2803 2804 // Create a temporary array to hold the sizes of local pointer arguments 2805 // for the block. \p First is the position of the first size argument. 2806 auto CreateArrayForSizeVar = [=](unsigned First) { 2807 auto *AT = llvm::ArrayType::get(SizeTy, NumArgs - First); 2808 auto *Arr = Builder.CreateAlloca(AT); 2809 llvm::Value *Ptr; 2810 // Each of the following arguments specifies the size of the corresponding 2811 // argument passed to the enqueued block. 2812 auto *Zero = llvm::ConstantInt::get(IntTy, 0); 2813 for (unsigned I = First; I < NumArgs; ++I) { 2814 auto *Index = llvm::ConstantInt::get(IntTy, I - First); 2815 auto *GEP = Builder.CreateGEP(Arr, {Zero, Index}); 2816 if (I == First) 2817 Ptr = GEP; 2818 auto *V = 2819 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy); 2820 Builder.CreateAlignedStore( 2821 V, GEP, CGM.getDataLayout().getPrefTypeAlignment(SizeTy)); 2822 } 2823 return Ptr; 2824 }; 2825 2826 // Could have events and/or vaargs. 2827 if (E->getArg(3)->getType()->isBlockPointerType()) { 2828 // No events passed, but has variadic arguments. 2829 Name = "__enqueue_kernel_vaargs"; 2830 auto Info = 2831 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2832 llvm::Value *Kernel = 2833 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2834 auto *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2835 auto *PtrToSizeArray = CreateArrayForSizeVar(4); 2836 2837 // Create a vector of the arguments, as well as a constant value to 2838 // express to the runtime the number of variadic arguments. 2839 std::vector<llvm::Value *> Args = { 2840 Queue, Flags, Range, 2841 Kernel, Block, ConstantInt::get(IntTy, NumArgs - 4), 2842 PtrToSizeArray}; 2843 std::vector<llvm::Type *> ArgTys = { 2844 QueueTy, IntTy, RangeTy, 2845 GenericVoidPtrTy, GenericVoidPtrTy, IntTy, 2846 PtrToSizeArray->getType()}; 2847 2848 llvm::FunctionType *FTy = llvm::FunctionType::get( 2849 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2850 return RValue::get( 2851 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2852 llvm::ArrayRef<llvm::Value *>(Args))); 2853 } 2854 // Any calls now have event arguments passed. 2855 if (NumArgs >= 7) { 2856 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy); 2857 llvm::Type *EventPtrTy = EventTy->getPointerTo( 2858 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2859 2860 llvm::Value *NumEvents = 2861 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty); 2862 llvm::Value *EventList = 2863 E->getArg(4)->getType()->isArrayType() 2864 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer() 2865 : EmitScalarExpr(E->getArg(4)); 2866 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5)); 2867 // Convert to generic address space. 2868 EventList = Builder.CreatePointerCast(EventList, EventPtrTy); 2869 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy); 2870 auto Info = 2871 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(6)); 2872 llvm::Value *Kernel = 2873 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2874 llvm::Value *Block = 2875 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2876 2877 std::vector<llvm::Type *> ArgTys = { 2878 QueueTy, Int32Ty, RangeTy, Int32Ty, 2879 EventPtrTy, EventPtrTy, GenericVoidPtrTy, GenericVoidPtrTy}; 2880 2881 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents, 2882 EventList, ClkEvent, Kernel, Block}; 2883 2884 if (NumArgs == 7) { 2885 // Has events but no variadics. 2886 Name = "__enqueue_kernel_basic_events"; 2887 llvm::FunctionType *FTy = llvm::FunctionType::get( 2888 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2889 return RValue::get( 2890 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2891 llvm::ArrayRef<llvm::Value *>(Args))); 2892 } 2893 // Has event info and variadics 2894 // Pass the number of variadics to the runtime function too. 2895 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7)); 2896 ArgTys.push_back(Int32Ty); 2897 Name = "__enqueue_kernel_events_vaargs"; 2898 2899 auto *PtrToSizeArray = CreateArrayForSizeVar(7); 2900 Args.push_back(PtrToSizeArray); 2901 ArgTys.push_back(PtrToSizeArray->getType()); 2902 2903 llvm::FunctionType *FTy = llvm::FunctionType::get( 2904 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2905 return RValue::get( 2906 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2907 llvm::ArrayRef<llvm::Value *>(Args))); 2908 } 2909 LLVM_FALLTHROUGH; 2910 } 2911 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block 2912 // parameter. 2913 case Builtin::BIget_kernel_work_group_size: { 2914 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2915 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2916 auto Info = 2917 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 2918 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2919 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2920 return RValue::get(Builder.CreateCall( 2921 CGM.CreateRuntimeFunction( 2922 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 2923 false), 2924 "__get_kernel_work_group_size_impl"), 2925 {Kernel, Arg})); 2926 } 2927 case Builtin::BIget_kernel_preferred_work_group_size_multiple: { 2928 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2929 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2930 auto Info = 2931 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 2932 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2933 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2934 return RValue::get(Builder.CreateCall( 2935 CGM.CreateRuntimeFunction( 2936 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 2937 false), 2938 "__get_kernel_preferred_work_group_multiple_impl"), 2939 {Kernel, Arg})); 2940 } 2941 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange: 2942 case Builtin::BIget_kernel_sub_group_count_for_ndrange: { 2943 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2944 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2945 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0)); 2946 llvm::Value *NDRange = NDRangeL.getAddress().getPointer(); 2947 auto Info = 2948 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(1)); 2949 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2950 Value *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2951 const char *Name = 2952 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange 2953 ? "__get_kernel_max_sub_group_size_for_ndrange_impl" 2954 : "__get_kernel_sub_group_count_for_ndrange_impl"; 2955 return RValue::get(Builder.CreateCall( 2956 CGM.CreateRuntimeFunction( 2957 llvm::FunctionType::get( 2958 IntTy, {NDRange->getType(), GenericVoidPtrTy, GenericVoidPtrTy}, 2959 false), 2960 Name), 2961 {NDRange, Kernel, Block})); 2962 } 2963 2964 case Builtin::BI__builtin_store_half: 2965 case Builtin::BI__builtin_store_halff: { 2966 Value *Val = EmitScalarExpr(E->getArg(0)); 2967 Address Address = EmitPointerWithAlignment(E->getArg(1)); 2968 Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy()); 2969 return RValue::get(Builder.CreateStore(HalfVal, Address)); 2970 } 2971 case Builtin::BI__builtin_load_half: { 2972 Address Address = EmitPointerWithAlignment(E->getArg(0)); 2973 Value *HalfVal = Builder.CreateLoad(Address); 2974 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy())); 2975 } 2976 case Builtin::BI__builtin_load_halff: { 2977 Address Address = EmitPointerWithAlignment(E->getArg(0)); 2978 Value *HalfVal = Builder.CreateLoad(Address); 2979 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy())); 2980 } 2981 case Builtin::BIprintf: 2982 if (getTarget().getTriple().isNVPTX()) 2983 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue); 2984 break; 2985 case Builtin::BI__builtin_canonicalize: 2986 case Builtin::BI__builtin_canonicalizef: 2987 case Builtin::BI__builtin_canonicalizel: 2988 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize)); 2989 2990 case Builtin::BI__builtin_thread_pointer: { 2991 if (!getContext().getTargetInfo().isTLSSupported()) 2992 CGM.ErrorUnsupported(E, "__builtin_thread_pointer"); 2993 // Fall through - it's already mapped to the intrinsic by GCCBuiltin. 2994 break; 2995 } 2996 case Builtin::BI__builtin_os_log_format: 2997 return emitBuiltinOSLogFormat(*E); 2998 2999 case Builtin::BI__builtin_os_log_format_buffer_size: { 3000 analyze_os_log::OSLogBufferLayout Layout; 3001 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); 3002 return RValue::get(ConstantInt::get(ConvertType(E->getType()), 3003 Layout.size().getQuantity())); 3004 } 3005 3006 case Builtin::BI__xray_customevent: { 3007 if (!ShouldXRayInstrumentFunction()) 3008 return RValue::getIgnored(); 3009 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) { 3010 if (XRayAttr->neverXRayInstrument()) 3011 return RValue::getIgnored(); 3012 } 3013 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent); 3014 auto FTy = F->getFunctionType(); 3015 auto Arg0 = E->getArg(0); 3016 auto Arg0Val = EmitScalarExpr(Arg0); 3017 auto Arg0Ty = Arg0->getType(); 3018 auto PTy0 = FTy->getParamType(0); 3019 if (PTy0 != Arg0Val->getType()) { 3020 if (Arg0Ty->isArrayType()) 3021 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer(); 3022 else 3023 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0); 3024 } 3025 auto Arg1 = EmitScalarExpr(E->getArg(1)); 3026 auto PTy1 = FTy->getParamType(1); 3027 if (PTy1 != Arg1->getType()) 3028 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1); 3029 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1})); 3030 } 3031 3032 case Builtin::BI__builtin_ms_va_start: 3033 case Builtin::BI__builtin_ms_va_end: 3034 return RValue::get( 3035 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(), 3036 BuiltinID == Builtin::BI__builtin_ms_va_start)); 3037 3038 case Builtin::BI__builtin_ms_va_copy: { 3039 // Lower this manually. We can't reliably determine whether or not any 3040 // given va_copy() is for a Win64 va_list from the calling convention 3041 // alone, because it's legal to do this from a System V ABI function. 3042 // With opaque pointer types, we won't have enough information in LLVM 3043 // IR to determine this from the argument types, either. Best to do it 3044 // now, while we have enough information. 3045 Address DestAddr = EmitMSVAListRef(E->getArg(0)); 3046 Address SrcAddr = EmitMSVAListRef(E->getArg(1)); 3047 3048 llvm::Type *BPP = Int8PtrPtrTy; 3049 3050 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"), 3051 DestAddr.getAlignment()); 3052 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"), 3053 SrcAddr.getAlignment()); 3054 3055 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); 3056 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr)); 3057 } 3058 } 3059 3060 // If this is an alias for a lib function (e.g. __builtin_sin), emit 3061 // the call using the normal call path, but using the unmangled 3062 // version of the function name. 3063 if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 3064 return emitLibraryCall(*this, FD, E, 3065 CGM.getBuiltinLibFunction(FD, BuiltinID)); 3066 3067 // If this is a predefined lib function (e.g. malloc), emit the call 3068 // using exactly the normal call path. 3069 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 3070 return emitLibraryCall(*this, FD, E, 3071 cast<llvm::Constant>(EmitScalarExpr(E->getCallee()))); 3072 3073 // Check that a call to a target specific builtin has the correct target 3074 // features. 3075 // This is down here to avoid non-target specific builtins, however, if 3076 // generic builtins start to require generic target features then we 3077 // can move this up to the beginning of the function. 3078 checkTargetFeatures(E, FD); 3079 3080 // See if we have a target specific intrinsic. 3081 const char *Name = getContext().BuiltinInfo.getName(BuiltinID); 3082 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 3083 StringRef Prefix = 3084 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); 3085 if (!Prefix.empty()) { 3086 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name); 3087 // NOTE we dont need to perform a compatibility flag check here since the 3088 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the 3089 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. 3090 if (IntrinsicID == Intrinsic::not_intrinsic) 3091 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name); 3092 } 3093 3094 if (IntrinsicID != Intrinsic::not_intrinsic) { 3095 SmallVector<Value*, 16> Args; 3096 3097 // Find out if any arguments are required to be integer constant 3098 // expressions. 3099 unsigned ICEArguments = 0; 3100 ASTContext::GetBuiltinTypeError Error; 3101 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 3102 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 3103 3104 Function *F = CGM.getIntrinsic(IntrinsicID); 3105 llvm::FunctionType *FTy = F->getFunctionType(); 3106 3107 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 3108 Value *ArgValue; 3109 // If this is a normal argument, just emit it as a scalar. 3110 if ((ICEArguments & (1 << i)) == 0) { 3111 ArgValue = EmitScalarExpr(E->getArg(i)); 3112 } else { 3113 // If this is required to be a constant, constant fold it so that we 3114 // know that the generated intrinsic gets a ConstantInt. 3115 llvm::APSInt Result; 3116 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 3117 assert(IsConst && "Constant arg isn't actually constant?"); 3118 (void)IsConst; 3119 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 3120 } 3121 3122 // If the intrinsic arg type is different from the builtin arg type 3123 // we need to do a bit cast. 3124 llvm::Type *PTy = FTy->getParamType(i); 3125 if (PTy != ArgValue->getType()) { 3126 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 3127 "Must be able to losslessly bit cast to param"); 3128 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 3129 } 3130 3131 Args.push_back(ArgValue); 3132 } 3133 3134 Value *V = Builder.CreateCall(F, Args); 3135 QualType BuiltinRetType = E->getType(); 3136 3137 llvm::Type *RetTy = VoidTy; 3138 if (!BuiltinRetType->isVoidType()) 3139 RetTy = ConvertType(BuiltinRetType); 3140 3141 if (RetTy != V->getType()) { 3142 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 3143 "Must be able to losslessly bit cast result type"); 3144 V = Builder.CreateBitCast(V, RetTy); 3145 } 3146 3147 return RValue::get(V); 3148 } 3149 3150 // See if we have a target specific builtin that needs to be lowered. 3151 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 3152 return RValue::get(V); 3153 3154 ErrorUnsupported(E, "builtin function"); 3155 3156 // Unknown builtin, for now just dump it out and return undef. 3157 return GetUndefRValue(E->getType()); 3158 } 3159 3160 static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, 3161 unsigned BuiltinID, const CallExpr *E, 3162 llvm::Triple::ArchType Arch) { 3163 switch (Arch) { 3164 case llvm::Triple::arm: 3165 case llvm::Triple::armeb: 3166 case llvm::Triple::thumb: 3167 case llvm::Triple::thumbeb: 3168 return CGF->EmitARMBuiltinExpr(BuiltinID, E); 3169 case llvm::Triple::aarch64: 3170 case llvm::Triple::aarch64_be: 3171 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E); 3172 case llvm::Triple::x86: 3173 case llvm::Triple::x86_64: 3174 return CGF->EmitX86BuiltinExpr(BuiltinID, E); 3175 case llvm::Triple::ppc: 3176 case llvm::Triple::ppc64: 3177 case llvm::Triple::ppc64le: 3178 return CGF->EmitPPCBuiltinExpr(BuiltinID, E); 3179 case llvm::Triple::r600: 3180 case llvm::Triple::amdgcn: 3181 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E); 3182 case llvm::Triple::systemz: 3183 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E); 3184 case llvm::Triple::nvptx: 3185 case llvm::Triple::nvptx64: 3186 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E); 3187 case llvm::Triple::wasm32: 3188 case llvm::Triple::wasm64: 3189 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E); 3190 default: 3191 return nullptr; 3192 } 3193 } 3194 3195 Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 3196 const CallExpr *E) { 3197 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { 3198 assert(getContext().getAuxTargetInfo() && "Missing aux target info"); 3199 return EmitTargetArchBuiltinExpr( 3200 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E, 3201 getContext().getAuxTargetInfo()->getTriple().getArch()); 3202 } 3203 3204 return EmitTargetArchBuiltinExpr(this, BuiltinID, E, 3205 getTarget().getTriple().getArch()); 3206 } 3207 3208 static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 3209 NeonTypeFlags TypeFlags, 3210 bool V1Ty=false) { 3211 int IsQuad = TypeFlags.isQuad(); 3212 switch (TypeFlags.getEltType()) { 3213 case NeonTypeFlags::Int8: 3214 case NeonTypeFlags::Poly8: 3215 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); 3216 case NeonTypeFlags::Int16: 3217 case NeonTypeFlags::Poly16: 3218 case NeonTypeFlags::Float16: 3219 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); 3220 case NeonTypeFlags::Int32: 3221 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); 3222 case NeonTypeFlags::Int64: 3223 case NeonTypeFlags::Poly64: 3224 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad)); 3225 case NeonTypeFlags::Poly128: 3226 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm. 3227 // There is a lot of i128 and f128 API missing. 3228 // so we use v16i8 to represent poly128 and get pattern matched. 3229 return llvm::VectorType::get(CGF->Int8Ty, 16); 3230 case NeonTypeFlags::Float32: 3231 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); 3232 case NeonTypeFlags::Float64: 3233 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad)); 3234 } 3235 llvm_unreachable("Unknown vector element type!"); 3236 } 3237 3238 static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF, 3239 NeonTypeFlags IntTypeFlags) { 3240 int IsQuad = IntTypeFlags.isQuad(); 3241 switch (IntTypeFlags.getEltType()) { 3242 case NeonTypeFlags::Int32: 3243 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad)); 3244 case NeonTypeFlags::Int64: 3245 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad)); 3246 default: 3247 llvm_unreachable("Type can't be converted to floating-point!"); 3248 } 3249 } 3250 3251 Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 3252 unsigned nElts = V->getType()->getVectorNumElements(); 3253 Value* SV = llvm::ConstantVector::getSplat(nElts, C); 3254 return Builder.CreateShuffleVector(V, V, SV, "lane"); 3255 } 3256 3257 Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 3258 const char *name, 3259 unsigned shift, bool rightshift) { 3260 unsigned j = 0; 3261 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3262 ai != ae; ++ai, ++j) 3263 if (shift > 0 && shift == j) 3264 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 3265 else 3266 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 3267 3268 return Builder.CreateCall(F, Ops, name); 3269 } 3270 3271 Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 3272 bool neg) { 3273 int SV = cast<ConstantInt>(V)->getSExtValue(); 3274 return ConstantInt::get(Ty, neg ? -SV : SV); 3275 } 3276 3277 // \brief Right-shift a vector by a constant. 3278 Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, 3279 llvm::Type *Ty, bool usgn, 3280 const char *name) { 3281 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3282 3283 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); 3284 int EltSize = VTy->getScalarSizeInBits(); 3285 3286 Vec = Builder.CreateBitCast(Vec, Ty); 3287 3288 // lshr/ashr are undefined when the shift amount is equal to the vector 3289 // element size. 3290 if (ShiftAmt == EltSize) { 3291 if (usgn) { 3292 // Right-shifting an unsigned value by its size yields 0. 3293 return llvm::ConstantAggregateZero::get(VTy); 3294 } else { 3295 // Right-shifting a signed value by its size is equivalent 3296 // to a shift of size-1. 3297 --ShiftAmt; 3298 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); 3299 } 3300 } 3301 3302 Shift = EmitNeonShiftVector(Shift, Ty, false); 3303 if (usgn) 3304 return Builder.CreateLShr(Vec, Shift, name); 3305 else 3306 return Builder.CreateAShr(Vec, Shift, name); 3307 } 3308 3309 enum { 3310 AddRetType = (1 << 0), 3311 Add1ArgType = (1 << 1), 3312 Add2ArgTypes = (1 << 2), 3313 3314 VectorizeRetType = (1 << 3), 3315 VectorizeArgTypes = (1 << 4), 3316 3317 InventFloatType = (1 << 5), 3318 UnsignedAlts = (1 << 6), 3319 3320 Use64BitVectors = (1 << 7), 3321 Use128BitVectors = (1 << 8), 3322 3323 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes, 3324 VectorRet = AddRetType | VectorizeRetType, 3325 VectorRetGetArgs01 = 3326 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes, 3327 FpCmpzModifiers = 3328 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType 3329 }; 3330 3331 namespace { 3332 struct NeonIntrinsicInfo { 3333 const char *NameHint; 3334 unsigned BuiltinID; 3335 unsigned LLVMIntrinsic; 3336 unsigned AltLLVMIntrinsic; 3337 unsigned TypeModifier; 3338 3339 bool operator<(unsigned RHSBuiltinID) const { 3340 return BuiltinID < RHSBuiltinID; 3341 } 3342 bool operator<(const NeonIntrinsicInfo &TE) const { 3343 return BuiltinID < TE.BuiltinID; 3344 } 3345 }; 3346 } // end anonymous namespace 3347 3348 #define NEONMAP0(NameBase) \ 3349 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 } 3350 3351 #define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ 3352 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3353 Intrinsic::LLVMIntrinsic, 0, TypeModifier } 3354 3355 #define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \ 3356 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3357 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ 3358 TypeModifier } 3359 3360 static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { 3361 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3362 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3363 NEONMAP1(vabs_v, arm_neon_vabs, 0), 3364 NEONMAP1(vabsq_v, arm_neon_vabs, 0), 3365 NEONMAP0(vaddhn_v), 3366 NEONMAP1(vaesdq_v, arm_neon_aesd, 0), 3367 NEONMAP1(vaeseq_v, arm_neon_aese, 0), 3368 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), 3369 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), 3370 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), 3371 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), 3372 NEONMAP1(vcage_v, arm_neon_vacge, 0), 3373 NEONMAP1(vcageq_v, arm_neon_vacge, 0), 3374 NEONMAP1(vcagt_v, arm_neon_vacgt, 0), 3375 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0), 3376 NEONMAP1(vcale_v, arm_neon_vacge, 0), 3377 NEONMAP1(vcaleq_v, arm_neon_vacge, 0), 3378 NEONMAP1(vcalt_v, arm_neon_vacgt, 0), 3379 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0), 3380 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType), 3381 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType), 3382 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3383 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3384 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3385 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3386 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0), 3387 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), 3388 NEONMAP0(vcvt_f32_v), 3389 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3390 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3391 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3392 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3393 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3394 NEONMAP0(vcvt_s32_v), 3395 NEONMAP0(vcvt_s64_v), 3396 NEONMAP0(vcvt_u32_v), 3397 NEONMAP0(vcvt_u64_v), 3398 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), 3399 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), 3400 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), 3401 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), 3402 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), 3403 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), 3404 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), 3405 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), 3406 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), 3407 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), 3408 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), 3409 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), 3410 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), 3411 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), 3412 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), 3413 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), 3414 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), 3415 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), 3416 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), 3417 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), 3418 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), 3419 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), 3420 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), 3421 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), 3422 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), 3423 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), 3424 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), 3425 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), 3426 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), 3427 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), 3428 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), 3429 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), 3430 NEONMAP0(vcvtq_f32_v), 3431 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3432 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3433 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3434 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3435 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3436 NEONMAP0(vcvtq_s32_v), 3437 NEONMAP0(vcvtq_s64_v), 3438 NEONMAP0(vcvtq_u32_v), 3439 NEONMAP0(vcvtq_u64_v), 3440 NEONMAP0(vext_v), 3441 NEONMAP0(vextq_v), 3442 NEONMAP0(vfma_v), 3443 NEONMAP0(vfmaq_v), 3444 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3445 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3446 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3447 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3448 NEONMAP0(vld1_dup_v), 3449 NEONMAP1(vld1_v, arm_neon_vld1, 0), 3450 NEONMAP0(vld1q_dup_v), 3451 NEONMAP1(vld1q_v, arm_neon_vld1, 0), 3452 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0), 3453 NEONMAP1(vld2_v, arm_neon_vld2, 0), 3454 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0), 3455 NEONMAP1(vld2q_v, arm_neon_vld2, 0), 3456 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0), 3457 NEONMAP1(vld3_v, arm_neon_vld3, 0), 3458 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0), 3459 NEONMAP1(vld3q_v, arm_neon_vld3, 0), 3460 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0), 3461 NEONMAP1(vld4_v, arm_neon_vld4, 0), 3462 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0), 3463 NEONMAP1(vld4q_v, arm_neon_vld4, 0), 3464 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3465 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType), 3466 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType), 3467 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3468 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3469 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType), 3470 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType), 3471 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3472 NEONMAP0(vmovl_v), 3473 NEONMAP0(vmovn_v), 3474 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType), 3475 NEONMAP0(vmull_v), 3476 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType), 3477 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3478 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3479 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType), 3480 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3481 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3482 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType), 3483 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts), 3484 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts), 3485 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType), 3486 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType), 3487 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3488 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3489 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0), 3490 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0), 3491 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType), 3492 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType), 3493 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType), 3494 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts), 3495 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), 3496 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), 3497 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), 3498 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), 3499 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), 3500 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3501 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3502 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3503 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3504 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3505 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3506 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0), 3507 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0), 3508 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3509 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3510 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType), 3511 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3512 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3513 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType), 3514 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType), 3515 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3516 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3517 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType), 3518 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType), 3519 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType), 3520 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType), 3521 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType), 3522 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType), 3523 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType), 3524 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType), 3525 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType), 3526 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType), 3527 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType), 3528 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType), 3529 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3530 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3531 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3532 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3533 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3534 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3535 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType), 3536 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType), 3537 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType), 3538 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0), 3539 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0), 3540 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0), 3541 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0), 3542 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0), 3543 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0), 3544 NEONMAP0(vshl_n_v), 3545 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3546 NEONMAP0(vshll_n_v), 3547 NEONMAP0(vshlq_n_v), 3548 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3549 NEONMAP0(vshr_n_v), 3550 NEONMAP0(vshrn_n_v), 3551 NEONMAP0(vshrq_n_v), 3552 NEONMAP1(vst1_v, arm_neon_vst1, 0), 3553 NEONMAP1(vst1q_v, arm_neon_vst1, 0), 3554 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0), 3555 NEONMAP1(vst2_v, arm_neon_vst2, 0), 3556 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0), 3557 NEONMAP1(vst2q_v, arm_neon_vst2, 0), 3558 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0), 3559 NEONMAP1(vst3_v, arm_neon_vst3, 0), 3560 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0), 3561 NEONMAP1(vst3q_v, arm_neon_vst3, 0), 3562 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0), 3563 NEONMAP1(vst4_v, arm_neon_vst4, 0), 3564 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0), 3565 NEONMAP1(vst4q_v, arm_neon_vst4, 0), 3566 NEONMAP0(vsubhn_v), 3567 NEONMAP0(vtrn_v), 3568 NEONMAP0(vtrnq_v), 3569 NEONMAP0(vtst_v), 3570 NEONMAP0(vtstq_v), 3571 NEONMAP0(vuzp_v), 3572 NEONMAP0(vuzpq_v), 3573 NEONMAP0(vzip_v), 3574 NEONMAP0(vzipq_v) 3575 }; 3576 3577 static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = { 3578 NEONMAP1(vabs_v, aarch64_neon_abs, 0), 3579 NEONMAP1(vabsq_v, aarch64_neon_abs, 0), 3580 NEONMAP0(vaddhn_v), 3581 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0), 3582 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0), 3583 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0), 3584 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0), 3585 NEONMAP1(vcage_v, aarch64_neon_facge, 0), 3586 NEONMAP1(vcageq_v, aarch64_neon_facge, 0), 3587 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0), 3588 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0), 3589 NEONMAP1(vcale_v, aarch64_neon_facge, 0), 3590 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0), 3591 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0), 3592 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0), 3593 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType), 3594 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType), 3595 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3596 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3597 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3598 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3599 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0), 3600 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0), 3601 NEONMAP0(vcvt_f32_v), 3602 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3603 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3604 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3605 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3606 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3607 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3608 NEONMAP0(vcvtq_f32_v), 3609 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3610 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3611 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3612 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3613 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3614 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3615 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType), 3616 NEONMAP0(vext_v), 3617 NEONMAP0(vextq_v), 3618 NEONMAP0(vfma_v), 3619 NEONMAP0(vfmaq_v), 3620 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3621 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3622 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3623 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3624 NEONMAP0(vmovl_v), 3625 NEONMAP0(vmovn_v), 3626 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType), 3627 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType), 3628 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType), 3629 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3630 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3631 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType), 3632 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType), 3633 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType), 3634 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3635 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3636 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0), 3637 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0), 3638 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType), 3639 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType), 3640 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType), 3641 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts), 3642 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType), 3643 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType), 3644 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType), 3645 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType), 3646 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType), 3647 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3648 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3649 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts), 3650 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3651 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts), 3652 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3653 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0), 3654 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0), 3655 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3656 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3657 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType), 3658 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3659 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3660 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType), 3661 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType), 3662 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3663 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3664 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3665 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3666 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3667 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3668 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3669 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3670 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType), 3671 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType), 3672 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType), 3673 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0), 3674 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0), 3675 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0), 3676 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0), 3677 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0), 3678 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0), 3679 NEONMAP0(vshl_n_v), 3680 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3681 NEONMAP0(vshll_n_v), 3682 NEONMAP0(vshlq_n_v), 3683 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3684 NEONMAP0(vshr_n_v), 3685 NEONMAP0(vshrn_n_v), 3686 NEONMAP0(vshrq_n_v), 3687 NEONMAP0(vsubhn_v), 3688 NEONMAP0(vtst_v), 3689 NEONMAP0(vtstq_v), 3690 }; 3691 3692 static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = { 3693 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType), 3694 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType), 3695 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType), 3696 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3697 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3698 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3699 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3700 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3701 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3702 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3703 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3704 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType), 3705 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3706 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType), 3707 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3708 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3709 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3710 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3711 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3712 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3713 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3714 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3715 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3716 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3717 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3718 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3719 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3720 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3721 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3722 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3723 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3724 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3725 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3726 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3727 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3728 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3729 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3730 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3731 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3732 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3733 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3734 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3735 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3736 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3737 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3738 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3739 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3740 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3741 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0), 3742 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3743 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3744 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3745 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3746 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3747 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3748 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3749 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3750 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3751 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3752 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3753 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3754 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3755 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3756 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3757 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3758 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3759 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3760 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3761 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3762 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0), 3763 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType), 3764 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType), 3765 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3766 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3767 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3768 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3769 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3770 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3771 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3772 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3773 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3774 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3775 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3776 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType), 3777 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3778 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType), 3779 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3780 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3781 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType), 3782 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType), 3783 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3784 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3785 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType), 3786 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType), 3787 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors), 3788 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType), 3789 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors), 3790 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0), 3791 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType), 3792 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType), 3793 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3794 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3795 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3796 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3797 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType), 3798 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3799 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3800 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3801 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType), 3802 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3803 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType), 3804 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors), 3805 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType), 3806 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3807 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3808 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType), 3809 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType), 3810 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3811 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3812 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType), 3813 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType), 3814 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType), 3815 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType), 3816 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3817 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3818 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3819 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3820 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType), 3821 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3822 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3823 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3824 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3825 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3826 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3827 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType), 3828 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType), 3829 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3830 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3831 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3832 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3833 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType), 3834 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType), 3835 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType), 3836 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType), 3837 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3838 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3839 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType), 3840 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType), 3841 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType), 3842 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3843 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3844 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3845 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3846 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType), 3847 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3848 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3849 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3850 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3851 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType), 3852 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType), 3853 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3854 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3855 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType), 3856 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType), 3857 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType), 3858 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType), 3859 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType), 3860 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType), 3861 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType), 3862 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType), 3863 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType), 3864 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType), 3865 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType), 3866 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType), 3867 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0), 3868 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0), 3869 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0), 3870 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0), 3871 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType), 3872 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType), 3873 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType), 3874 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType), 3875 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3876 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType), 3877 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3878 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType), 3879 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType), 3880 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType), 3881 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3882 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType), 3883 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3884 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType), 3885 }; 3886 3887 #undef NEONMAP0 3888 #undef NEONMAP1 3889 #undef NEONMAP2 3890 3891 static bool NEONSIMDIntrinsicsProvenSorted = false; 3892 3893 static bool AArch64SIMDIntrinsicsProvenSorted = false; 3894 static bool AArch64SISDIntrinsicsProvenSorted = false; 3895 3896 3897 static const NeonIntrinsicInfo * 3898 findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap, 3899 unsigned BuiltinID, bool &MapProvenSorted) { 3900 3901 #ifndef NDEBUG 3902 if (!MapProvenSorted) { 3903 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap))); 3904 MapProvenSorted = true; 3905 } 3906 #endif 3907 3908 const NeonIntrinsicInfo *Builtin = 3909 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID); 3910 3911 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) 3912 return Builtin; 3913 3914 return nullptr; 3915 } 3916 3917 Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 3918 unsigned Modifier, 3919 llvm::Type *ArgType, 3920 const CallExpr *E) { 3921 int VectorSize = 0; 3922 if (Modifier & Use64BitVectors) 3923 VectorSize = 64; 3924 else if (Modifier & Use128BitVectors) 3925 VectorSize = 128; 3926 3927 // Return type. 3928 SmallVector<llvm::Type *, 3> Tys; 3929 if (Modifier & AddRetType) { 3930 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 3931 if (Modifier & VectorizeRetType) 3932 Ty = llvm::VectorType::get( 3933 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1); 3934 3935 Tys.push_back(Ty); 3936 } 3937 3938 // Arguments. 3939 if (Modifier & VectorizeArgTypes) { 3940 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1; 3941 ArgType = llvm::VectorType::get(ArgType, Elts); 3942 } 3943 3944 if (Modifier & (Add1ArgType | Add2ArgTypes)) 3945 Tys.push_back(ArgType); 3946 3947 if (Modifier & Add2ArgTypes) 3948 Tys.push_back(ArgType); 3949 3950 if (Modifier & InventFloatType) 3951 Tys.push_back(FloatTy); 3952 3953 return CGM.getIntrinsic(IntrinsicID, Tys); 3954 } 3955 3956 static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF, 3957 const NeonIntrinsicInfo &SISDInfo, 3958 SmallVectorImpl<Value *> &Ops, 3959 const CallExpr *E) { 3960 unsigned BuiltinID = SISDInfo.BuiltinID; 3961 unsigned int Int = SISDInfo.LLVMIntrinsic; 3962 unsigned Modifier = SISDInfo.TypeModifier; 3963 const char *s = SISDInfo.NameHint; 3964 3965 switch (BuiltinID) { 3966 case NEON::BI__builtin_neon_vcled_s64: 3967 case NEON::BI__builtin_neon_vcled_u64: 3968 case NEON::BI__builtin_neon_vcles_f32: 3969 case NEON::BI__builtin_neon_vcled_f64: 3970 case NEON::BI__builtin_neon_vcltd_s64: 3971 case NEON::BI__builtin_neon_vcltd_u64: 3972 case NEON::BI__builtin_neon_vclts_f32: 3973 case NEON::BI__builtin_neon_vcltd_f64: 3974 case NEON::BI__builtin_neon_vcales_f32: 3975 case NEON::BI__builtin_neon_vcaled_f64: 3976 case NEON::BI__builtin_neon_vcalts_f32: 3977 case NEON::BI__builtin_neon_vcaltd_f64: 3978 // Only one direction of comparisons actually exist, cmle is actually a cmge 3979 // with swapped operands. The table gives us the right intrinsic but we 3980 // still need to do the swap. 3981 std::swap(Ops[0], Ops[1]); 3982 break; 3983 } 3984 3985 assert(Int && "Generic code assumes a valid intrinsic"); 3986 3987 // Determine the type(s) of this overloaded AArch64 intrinsic. 3988 const Expr *Arg = E->getArg(0); 3989 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType()); 3990 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E); 3991 3992 int j = 0; 3993 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0); 3994 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3995 ai != ae; ++ai, ++j) { 3996 llvm::Type *ArgTy = ai->getType(); 3997 if (Ops[j]->getType()->getPrimitiveSizeInBits() == 3998 ArgTy->getPrimitiveSizeInBits()) 3999 continue; 4000 4001 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy()); 4002 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate 4003 // it before inserting. 4004 Ops[j] = 4005 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType()); 4006 Ops[j] = 4007 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0); 4008 } 4009 4010 Value *Result = CGF.EmitNeonCall(F, Ops, s); 4011 llvm::Type *ResultType = CGF.ConvertType(E->getType()); 4012 if (ResultType->getPrimitiveSizeInBits() < 4013 Result->getType()->getPrimitiveSizeInBits()) 4014 return CGF.Builder.CreateExtractElement(Result, C0); 4015 4016 return CGF.Builder.CreateBitCast(Result, ResultType, s); 4017 } 4018 4019 Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( 4020 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, 4021 const char *NameHint, unsigned Modifier, const CallExpr *E, 4022 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) { 4023 // Get the last argument, which specifies the vector type. 4024 llvm::APSInt NeonTypeConst; 4025 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 4026 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext())) 4027 return nullptr; 4028 4029 // Determine the type of this overloaded NEON intrinsic. 4030 NeonTypeFlags Type(NeonTypeConst.getZExtValue()); 4031 bool Usgn = Type.isUnsigned(); 4032 bool Quad = Type.isQuad(); 4033 4034 llvm::VectorType *VTy = GetNeonType(this, Type); 4035 llvm::Type *Ty = VTy; 4036 if (!Ty) 4037 return nullptr; 4038 4039 auto getAlignmentValue32 = [&](Address addr) -> Value* { 4040 return Builder.getInt32(addr.getAlignment().getQuantity()); 4041 }; 4042 4043 unsigned Int = LLVMIntrinsic; 4044 if ((Modifier & UnsignedAlts) && !Usgn) 4045 Int = AltLLVMIntrinsic; 4046 4047 switch (BuiltinID) { 4048 default: break; 4049 case NEON::BI__builtin_neon_vabs_v: 4050 case NEON::BI__builtin_neon_vabsq_v: 4051 if (VTy->getElementType()->isFloatingPointTy()) 4052 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); 4053 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs"); 4054 case NEON::BI__builtin_neon_vaddhn_v: { 4055 llvm::VectorType *SrcTy = 4056 llvm::VectorType::getExtendedElementVectorType(VTy); 4057 4058 // %sum = add <4 x i32> %lhs, %rhs 4059 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4060 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4061 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 4062 4063 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4064 Constant *ShiftAmt = 4065 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4066 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 4067 4068 // %res = trunc <4 x i32> %high to <4 x i16> 4069 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 4070 } 4071 case NEON::BI__builtin_neon_vcale_v: 4072 case NEON::BI__builtin_neon_vcaleq_v: 4073 case NEON::BI__builtin_neon_vcalt_v: 4074 case NEON::BI__builtin_neon_vcaltq_v: 4075 std::swap(Ops[0], Ops[1]); 4076 LLVM_FALLTHROUGH; 4077 case NEON::BI__builtin_neon_vcage_v: 4078 case NEON::BI__builtin_neon_vcageq_v: 4079 case NEON::BI__builtin_neon_vcagt_v: 4080 case NEON::BI__builtin_neon_vcagtq_v: { 4081 llvm::Type *VecFlt = llvm::VectorType::get( 4082 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, 4083 VTy->getNumElements()); 4084 llvm::Type *Tys[] = { VTy, VecFlt }; 4085 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4086 return EmitNeonCall(F, Ops, NameHint); 4087 } 4088 case NEON::BI__builtin_neon_vclz_v: 4089 case NEON::BI__builtin_neon_vclzq_v: 4090 // We generate target-independent intrinsic, which needs a second argument 4091 // for whether or not clz of zero is undefined; on ARM it isn't. 4092 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 4093 break; 4094 case NEON::BI__builtin_neon_vcvt_f32_v: 4095 case NEON::BI__builtin_neon_vcvtq_f32_v: 4096 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4097 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); 4098 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 4099 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 4100 case NEON::BI__builtin_neon_vcvt_n_f32_v: 4101 case NEON::BI__builtin_neon_vcvt_n_f64_v: 4102 case NEON::BI__builtin_neon_vcvtq_n_f32_v: 4103 case NEON::BI__builtin_neon_vcvtq_n_f64_v: { 4104 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty }; 4105 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic; 4106 Function *F = CGM.getIntrinsic(Int, Tys); 4107 return EmitNeonCall(F, Ops, "vcvt_n"); 4108 } 4109 case NEON::BI__builtin_neon_vcvt_n_s32_v: 4110 case NEON::BI__builtin_neon_vcvt_n_u32_v: 4111 case NEON::BI__builtin_neon_vcvt_n_s64_v: 4112 case NEON::BI__builtin_neon_vcvt_n_u64_v: 4113 case NEON::BI__builtin_neon_vcvtq_n_s32_v: 4114 case NEON::BI__builtin_neon_vcvtq_n_u32_v: 4115 case NEON::BI__builtin_neon_vcvtq_n_s64_v: 4116 case NEON::BI__builtin_neon_vcvtq_n_u64_v: { 4117 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4118 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4119 return EmitNeonCall(F, Ops, "vcvt_n"); 4120 } 4121 case NEON::BI__builtin_neon_vcvt_s32_v: 4122 case NEON::BI__builtin_neon_vcvt_u32_v: 4123 case NEON::BI__builtin_neon_vcvt_s64_v: 4124 case NEON::BI__builtin_neon_vcvt_u64_v: 4125 case NEON::BI__builtin_neon_vcvtq_s32_v: 4126 case NEON::BI__builtin_neon_vcvtq_u32_v: 4127 case NEON::BI__builtin_neon_vcvtq_s64_v: 4128 case NEON::BI__builtin_neon_vcvtq_u64_v: { 4129 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 4130 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 4131 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 4132 } 4133 case NEON::BI__builtin_neon_vcvta_s32_v: 4134 case NEON::BI__builtin_neon_vcvta_s64_v: 4135 case NEON::BI__builtin_neon_vcvta_u32_v: 4136 case NEON::BI__builtin_neon_vcvta_u64_v: 4137 case NEON::BI__builtin_neon_vcvtaq_s32_v: 4138 case NEON::BI__builtin_neon_vcvtaq_s64_v: 4139 case NEON::BI__builtin_neon_vcvtaq_u32_v: 4140 case NEON::BI__builtin_neon_vcvtaq_u64_v: 4141 case NEON::BI__builtin_neon_vcvtn_s32_v: 4142 case NEON::BI__builtin_neon_vcvtn_s64_v: 4143 case NEON::BI__builtin_neon_vcvtn_u32_v: 4144 case NEON::BI__builtin_neon_vcvtn_u64_v: 4145 case NEON::BI__builtin_neon_vcvtnq_s32_v: 4146 case NEON::BI__builtin_neon_vcvtnq_s64_v: 4147 case NEON::BI__builtin_neon_vcvtnq_u32_v: 4148 case NEON::BI__builtin_neon_vcvtnq_u64_v: 4149 case NEON::BI__builtin_neon_vcvtp_s32_v: 4150 case NEON::BI__builtin_neon_vcvtp_s64_v: 4151 case NEON::BI__builtin_neon_vcvtp_u32_v: 4152 case NEON::BI__builtin_neon_vcvtp_u64_v: 4153 case NEON::BI__builtin_neon_vcvtpq_s32_v: 4154 case NEON::BI__builtin_neon_vcvtpq_s64_v: 4155 case NEON::BI__builtin_neon_vcvtpq_u32_v: 4156 case NEON::BI__builtin_neon_vcvtpq_u64_v: 4157 case NEON::BI__builtin_neon_vcvtm_s32_v: 4158 case NEON::BI__builtin_neon_vcvtm_s64_v: 4159 case NEON::BI__builtin_neon_vcvtm_u32_v: 4160 case NEON::BI__builtin_neon_vcvtm_u64_v: 4161 case NEON::BI__builtin_neon_vcvtmq_s32_v: 4162 case NEON::BI__builtin_neon_vcvtmq_s64_v: 4163 case NEON::BI__builtin_neon_vcvtmq_u32_v: 4164 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 4165 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4166 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint); 4167 } 4168 case NEON::BI__builtin_neon_vext_v: 4169 case NEON::BI__builtin_neon_vextq_v: { 4170 int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 4171 SmallVector<uint32_t, 16> Indices; 4172 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4173 Indices.push_back(i+CV); 4174 4175 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4176 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4177 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext"); 4178 } 4179 case NEON::BI__builtin_neon_vfma_v: 4180 case NEON::BI__builtin_neon_vfmaq_v: { 4181 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 4182 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4183 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4184 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4185 4186 // NEON intrinsic puts accumulator first, unlike the LLVM fma. 4187 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 4188 } 4189 case NEON::BI__builtin_neon_vld1_v: 4190 case NEON::BI__builtin_neon_vld1q_v: { 4191 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4192 Ops.push_back(getAlignmentValue32(PtrOp0)); 4193 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1"); 4194 } 4195 case NEON::BI__builtin_neon_vld2_v: 4196 case NEON::BI__builtin_neon_vld2q_v: 4197 case NEON::BI__builtin_neon_vld3_v: 4198 case NEON::BI__builtin_neon_vld3q_v: 4199 case NEON::BI__builtin_neon_vld4_v: 4200 case NEON::BI__builtin_neon_vld4q_v: { 4201 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4202 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4203 Value *Align = getAlignmentValue32(PtrOp1); 4204 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint); 4205 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4206 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4207 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4208 } 4209 case NEON::BI__builtin_neon_vld1_dup_v: 4210 case NEON::BI__builtin_neon_vld1q_dup_v: { 4211 Value *V = UndefValue::get(Ty); 4212 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 4213 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty); 4214 LoadInst *Ld = Builder.CreateLoad(PtrOp0); 4215 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 4216 Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 4217 return EmitNeonSplat(Ops[0], CI); 4218 } 4219 case NEON::BI__builtin_neon_vld2_lane_v: 4220 case NEON::BI__builtin_neon_vld2q_lane_v: 4221 case NEON::BI__builtin_neon_vld3_lane_v: 4222 case NEON::BI__builtin_neon_vld3q_lane_v: 4223 case NEON::BI__builtin_neon_vld4_lane_v: 4224 case NEON::BI__builtin_neon_vld4q_lane_v: { 4225 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4226 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4227 for (unsigned I = 2; I < Ops.size() - 1; ++I) 4228 Ops[I] = Builder.CreateBitCast(Ops[I], Ty); 4229 Ops.push_back(getAlignmentValue32(PtrOp1)); 4230 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint); 4231 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4232 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4233 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4234 } 4235 case NEON::BI__builtin_neon_vmovl_v: { 4236 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 4237 Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 4238 if (Usgn) 4239 return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 4240 return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 4241 } 4242 case NEON::BI__builtin_neon_vmovn_v: { 4243 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4244 Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 4245 return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 4246 } 4247 case NEON::BI__builtin_neon_vmull_v: 4248 // FIXME: the integer vmull operations could be emitted in terms of pure 4249 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 4250 // hoisting the exts outside loops. Until global ISel comes along that can 4251 // see through such movement this leads to bad CodeGen. So we need an 4252 // intrinsic for now. 4253 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 4254 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 4255 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 4256 case NEON::BI__builtin_neon_vpadal_v: 4257 case NEON::BI__builtin_neon_vpadalq_v: { 4258 // The source operand type has twice as many elements of half the size. 4259 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4260 llvm::Type *EltTy = 4261 llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4262 llvm::Type *NarrowTy = 4263 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4264 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4265 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); 4266 } 4267 case NEON::BI__builtin_neon_vpaddl_v: 4268 case NEON::BI__builtin_neon_vpaddlq_v: { 4269 // The source operand type has twice as many elements of half the size. 4270 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4271 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4272 llvm::Type *NarrowTy = 4273 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4274 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4275 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 4276 } 4277 case NEON::BI__builtin_neon_vqdmlal_v: 4278 case NEON::BI__builtin_neon_vqdmlsl_v: { 4279 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 4280 Ops[1] = 4281 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal"); 4282 Ops.resize(2); 4283 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint); 4284 } 4285 case NEON::BI__builtin_neon_vqshl_n_v: 4286 case NEON::BI__builtin_neon_vqshlq_n_v: 4287 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 4288 1, false); 4289 case NEON::BI__builtin_neon_vqshlu_n_v: 4290 case NEON::BI__builtin_neon_vqshluq_n_v: 4291 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n", 4292 1, false); 4293 case NEON::BI__builtin_neon_vrecpe_v: 4294 case NEON::BI__builtin_neon_vrecpeq_v: 4295 case NEON::BI__builtin_neon_vrsqrte_v: 4296 case NEON::BI__builtin_neon_vrsqrteq_v: 4297 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic; 4298 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint); 4299 4300 case NEON::BI__builtin_neon_vrshr_n_v: 4301 case NEON::BI__builtin_neon_vrshrq_n_v: 4302 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 4303 1, true); 4304 case NEON::BI__builtin_neon_vshl_n_v: 4305 case NEON::BI__builtin_neon_vshlq_n_v: 4306 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 4307 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 4308 "vshl_n"); 4309 case NEON::BI__builtin_neon_vshll_n_v: { 4310 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 4311 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4312 if (Usgn) 4313 Ops[0] = Builder.CreateZExt(Ops[0], VTy); 4314 else 4315 Ops[0] = Builder.CreateSExt(Ops[0], VTy); 4316 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 4317 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 4318 } 4319 case NEON::BI__builtin_neon_vshrn_n_v: { 4320 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4321 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4322 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 4323 if (Usgn) 4324 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 4325 else 4326 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 4327 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 4328 } 4329 case NEON::BI__builtin_neon_vshr_n_v: 4330 case NEON::BI__builtin_neon_vshrq_n_v: 4331 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n"); 4332 case NEON::BI__builtin_neon_vst1_v: 4333 case NEON::BI__builtin_neon_vst1q_v: 4334 case NEON::BI__builtin_neon_vst2_v: 4335 case NEON::BI__builtin_neon_vst2q_v: 4336 case NEON::BI__builtin_neon_vst3_v: 4337 case NEON::BI__builtin_neon_vst3q_v: 4338 case NEON::BI__builtin_neon_vst4_v: 4339 case NEON::BI__builtin_neon_vst4q_v: 4340 case NEON::BI__builtin_neon_vst2_lane_v: 4341 case NEON::BI__builtin_neon_vst2q_lane_v: 4342 case NEON::BI__builtin_neon_vst3_lane_v: 4343 case NEON::BI__builtin_neon_vst3q_lane_v: 4344 case NEON::BI__builtin_neon_vst4_lane_v: 4345 case NEON::BI__builtin_neon_vst4q_lane_v: { 4346 llvm::Type *Tys[] = {Int8PtrTy, Ty}; 4347 Ops.push_back(getAlignmentValue32(PtrOp0)); 4348 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 4349 } 4350 case NEON::BI__builtin_neon_vsubhn_v: { 4351 llvm::VectorType *SrcTy = 4352 llvm::VectorType::getExtendedElementVectorType(VTy); 4353 4354 // %sum = add <4 x i32> %lhs, %rhs 4355 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4356 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4357 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 4358 4359 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4360 Constant *ShiftAmt = 4361 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4362 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 4363 4364 // %res = trunc <4 x i32> %high to <4 x i16> 4365 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 4366 } 4367 case NEON::BI__builtin_neon_vtrn_v: 4368 case NEON::BI__builtin_neon_vtrnq_v: { 4369 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4370 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4371 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4372 Value *SV = nullptr; 4373 4374 for (unsigned vi = 0; vi != 2; ++vi) { 4375 SmallVector<uint32_t, 16> Indices; 4376 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4377 Indices.push_back(i+vi); 4378 Indices.push_back(i+e+vi); 4379 } 4380 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4381 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 4382 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4383 } 4384 return SV; 4385 } 4386 case NEON::BI__builtin_neon_vtst_v: 4387 case NEON::BI__builtin_neon_vtstq_v: { 4388 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4389 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4390 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 4391 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 4392 ConstantAggregateZero::get(Ty)); 4393 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 4394 } 4395 case NEON::BI__builtin_neon_vuzp_v: 4396 case NEON::BI__builtin_neon_vuzpq_v: { 4397 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4398 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4399 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4400 Value *SV = nullptr; 4401 4402 for (unsigned vi = 0; vi != 2; ++vi) { 4403 SmallVector<uint32_t, 16> Indices; 4404 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4405 Indices.push_back(2*i+vi); 4406 4407 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4408 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 4409 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4410 } 4411 return SV; 4412 } 4413 case NEON::BI__builtin_neon_vzip_v: 4414 case NEON::BI__builtin_neon_vzipq_v: { 4415 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4416 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4417 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4418 Value *SV = nullptr; 4419 4420 for (unsigned vi = 0; vi != 2; ++vi) { 4421 SmallVector<uint32_t, 16> Indices; 4422 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4423 Indices.push_back((i + vi*e) >> 1); 4424 Indices.push_back(((i + vi*e) >> 1)+e); 4425 } 4426 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4427 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 4428 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4429 } 4430 return SV; 4431 } 4432 } 4433 4434 assert(Int && "Expected valid intrinsic number"); 4435 4436 // Determine the type(s) of this overloaded AArch64 intrinsic. 4437 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E); 4438 4439 Value *Result = EmitNeonCall(F, Ops, NameHint); 4440 llvm::Type *ResultType = ConvertType(E->getType()); 4441 // AArch64 intrinsic one-element vector type cast to 4442 // scalar type expected by the builtin 4443 return Builder.CreateBitCast(Result, ResultType, NameHint); 4444 } 4445 4446 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( 4447 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, 4448 const CmpInst::Predicate Ip, const Twine &Name) { 4449 llvm::Type *OTy = Op->getType(); 4450 4451 // FIXME: this is utterly horrific. We should not be looking at previous 4452 // codegen context to find out what needs doing. Unfortunately TableGen 4453 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32 4454 // (etc). 4455 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op)) 4456 OTy = BI->getOperand(0)->getType(); 4457 4458 Op = Builder.CreateBitCast(Op, OTy); 4459 if (OTy->getScalarType()->isFloatingPointTy()) { 4460 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy)); 4461 } else { 4462 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy)); 4463 } 4464 return Builder.CreateSExt(Op, Ty, Name); 4465 } 4466 4467 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, 4468 Value *ExtOp, Value *IndexOp, 4469 llvm::Type *ResTy, unsigned IntID, 4470 const char *Name) { 4471 SmallVector<Value *, 2> TblOps; 4472 if (ExtOp) 4473 TblOps.push_back(ExtOp); 4474 4475 // Build a vector containing sequential number like (0, 1, 2, ..., 15) 4476 SmallVector<uint32_t, 16> Indices; 4477 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); 4478 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { 4479 Indices.push_back(2*i); 4480 Indices.push_back(2*i+1); 4481 } 4482 4483 int PairPos = 0, End = Ops.size() - 1; 4484 while (PairPos < End) { 4485 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4486 Ops[PairPos+1], Indices, 4487 Name)); 4488 PairPos += 2; 4489 } 4490 4491 // If there's an odd number of 64-bit lookup table, fill the high 64-bit 4492 // of the 128-bit lookup table with zero. 4493 if (PairPos == End) { 4494 Value *ZeroTbl = ConstantAggregateZero::get(TblTy); 4495 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4496 ZeroTbl, Indices, Name)); 4497 } 4498 4499 Function *TblF; 4500 TblOps.push_back(IndexOp); 4501 TblF = CGF.CGM.getIntrinsic(IntID, ResTy); 4502 4503 return CGF.EmitNeonCall(TblF, TblOps, Name); 4504 } 4505 4506 Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) { 4507 unsigned Value; 4508 switch (BuiltinID) { 4509 default: 4510 return nullptr; 4511 case ARM::BI__builtin_arm_nop: 4512 Value = 0; 4513 break; 4514 case ARM::BI__builtin_arm_yield: 4515 case ARM::BI__yield: 4516 Value = 1; 4517 break; 4518 case ARM::BI__builtin_arm_wfe: 4519 case ARM::BI__wfe: 4520 Value = 2; 4521 break; 4522 case ARM::BI__builtin_arm_wfi: 4523 case ARM::BI__wfi: 4524 Value = 3; 4525 break; 4526 case ARM::BI__builtin_arm_sev: 4527 case ARM::BI__sev: 4528 Value = 4; 4529 break; 4530 case ARM::BI__builtin_arm_sevl: 4531 case ARM::BI__sevl: 4532 Value = 5; 4533 break; 4534 } 4535 4536 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint), 4537 llvm::ConstantInt::get(Int32Ty, Value)); 4538 } 4539 4540 // Generates the IR for the read/write special register builtin, 4541 // ValueType is the type of the value that is to be written or read, 4542 // RegisterType is the type of the register being written to or read from. 4543 static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF, 4544 const CallExpr *E, 4545 llvm::Type *RegisterType, 4546 llvm::Type *ValueType, 4547 bool IsRead, 4548 StringRef SysReg = "") { 4549 // write and register intrinsics only support 32 and 64 bit operations. 4550 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64)) 4551 && "Unsupported size for register."); 4552 4553 CodeGen::CGBuilderTy &Builder = CGF.Builder; 4554 CodeGen::CodeGenModule &CGM = CGF.CGM; 4555 LLVMContext &Context = CGM.getLLVMContext(); 4556 4557 if (SysReg.empty()) { 4558 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts(); 4559 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString(); 4560 } 4561 4562 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) }; 4563 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops); 4564 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName); 4565 4566 llvm::Type *Types[] = { RegisterType }; 4567 4568 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32); 4569 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64)) 4570 && "Can't fit 64-bit value in 32-bit register"); 4571 4572 if (IsRead) { 4573 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types); 4574 llvm::Value *Call = Builder.CreateCall(F, Metadata); 4575 4576 if (MixedTypes) 4577 // Read into 64 bit register and then truncate result to 32 bit. 4578 return Builder.CreateTrunc(Call, ValueType); 4579 4580 if (ValueType->isPointerTy()) 4581 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*). 4582 return Builder.CreateIntToPtr(Call, ValueType); 4583 4584 return Call; 4585 } 4586 4587 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types); 4588 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1)); 4589 if (MixedTypes) { 4590 // Extend 32 bit write value to 64 bit to pass to write. 4591 ArgValue = Builder.CreateZExt(ArgValue, RegisterType); 4592 return Builder.CreateCall(F, { Metadata, ArgValue }); 4593 } 4594 4595 if (ValueType->isPointerTy()) { 4596 // Have VoidPtrTy ArgValue but want to return an i32/i64. 4597 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType); 4598 return Builder.CreateCall(F, { Metadata, ArgValue }); 4599 } 4600 4601 return Builder.CreateCall(F, { Metadata, ArgValue }); 4602 } 4603 4604 /// Return true if BuiltinID is an overloaded Neon intrinsic with an extra 4605 /// argument that specifies the vector type. 4606 static bool HasExtraNeonArgument(unsigned BuiltinID) { 4607 switch (BuiltinID) { 4608 default: break; 4609 case NEON::BI__builtin_neon_vget_lane_i8: 4610 case NEON::BI__builtin_neon_vget_lane_i16: 4611 case NEON::BI__builtin_neon_vget_lane_i32: 4612 case NEON::BI__builtin_neon_vget_lane_i64: 4613 case NEON::BI__builtin_neon_vget_lane_f32: 4614 case NEON::BI__builtin_neon_vgetq_lane_i8: 4615 case NEON::BI__builtin_neon_vgetq_lane_i16: 4616 case NEON::BI__builtin_neon_vgetq_lane_i32: 4617 case NEON::BI__builtin_neon_vgetq_lane_i64: 4618 case NEON::BI__builtin_neon_vgetq_lane_f32: 4619 case NEON::BI__builtin_neon_vset_lane_i8: 4620 case NEON::BI__builtin_neon_vset_lane_i16: 4621 case NEON::BI__builtin_neon_vset_lane_i32: 4622 case NEON::BI__builtin_neon_vset_lane_i64: 4623 case NEON::BI__builtin_neon_vset_lane_f32: 4624 case NEON::BI__builtin_neon_vsetq_lane_i8: 4625 case NEON::BI__builtin_neon_vsetq_lane_i16: 4626 case NEON::BI__builtin_neon_vsetq_lane_i32: 4627 case NEON::BI__builtin_neon_vsetq_lane_i64: 4628 case NEON::BI__builtin_neon_vsetq_lane_f32: 4629 case NEON::BI__builtin_neon_vsha1h_u32: 4630 case NEON::BI__builtin_neon_vsha1cq_u32: 4631 case NEON::BI__builtin_neon_vsha1pq_u32: 4632 case NEON::BI__builtin_neon_vsha1mq_u32: 4633 case ARM::BI_MoveToCoprocessor: 4634 case ARM::BI_MoveToCoprocessor2: 4635 return false; 4636 } 4637 return true; 4638 } 4639 4640 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 4641 const CallExpr *E) { 4642 if (auto Hint = GetValueForARMHint(BuiltinID)) 4643 return Hint; 4644 4645 if (BuiltinID == ARM::BI__emit) { 4646 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb; 4647 llvm::FunctionType *FTy = 4648 llvm::FunctionType::get(VoidTy, /*Variadic=*/false); 4649 4650 APSInt Value; 4651 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext())) 4652 llvm_unreachable("Sema will ensure that the parameter is constant"); 4653 4654 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue(); 4655 4656 llvm::InlineAsm *Emit = 4657 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "", 4658 /*SideEffects=*/true) 4659 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "", 4660 /*SideEffects=*/true); 4661 4662 return Builder.CreateCall(Emit); 4663 } 4664 4665 if (BuiltinID == ARM::BI__builtin_arm_dbg) { 4666 Value *Option = EmitScalarExpr(E->getArg(0)); 4667 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option); 4668 } 4669 4670 if (BuiltinID == ARM::BI__builtin_arm_prefetch) { 4671 Value *Address = EmitScalarExpr(E->getArg(0)); 4672 Value *RW = EmitScalarExpr(E->getArg(1)); 4673 Value *IsData = EmitScalarExpr(E->getArg(2)); 4674 4675 // Locality is not supported on ARM target 4676 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3); 4677 4678 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4679 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 4680 } 4681 4682 if (BuiltinID == ARM::BI__builtin_arm_rbit) { 4683 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 4684 return Builder.CreateCall( 4685 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 4686 } 4687 4688 if (BuiltinID == ARM::BI__clear_cache) { 4689 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 4690 const FunctionDecl *FD = E->getDirectCallee(); 4691 Value *Ops[2]; 4692 for (unsigned i = 0; i < 2; i++) 4693 Ops[i] = EmitScalarExpr(E->getArg(i)); 4694 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 4695 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 4696 StringRef Name = FD->getName(); 4697 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 4698 } 4699 4700 if (BuiltinID == ARM::BI__builtin_arm_mcrr || 4701 BuiltinID == ARM::BI__builtin_arm_mcrr2) { 4702 Function *F; 4703 4704 switch (BuiltinID) { 4705 default: llvm_unreachable("unexpected builtin"); 4706 case ARM::BI__builtin_arm_mcrr: 4707 F = CGM.getIntrinsic(Intrinsic::arm_mcrr); 4708 break; 4709 case ARM::BI__builtin_arm_mcrr2: 4710 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2); 4711 break; 4712 } 4713 4714 // MCRR{2} instruction has 5 operands but 4715 // the intrinsic has 4 because Rt and Rt2 4716 // are represented as a single unsigned 64 4717 // bit integer in the intrinsic definition 4718 // but internally it's represented as 2 32 4719 // bit integers. 4720 4721 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4722 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4723 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2)); 4724 Value *CRm = EmitScalarExpr(E->getArg(3)); 4725 4726 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4727 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty); 4728 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1); 4729 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty); 4730 4731 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm}); 4732 } 4733 4734 if (BuiltinID == ARM::BI__builtin_arm_mrrc || 4735 BuiltinID == ARM::BI__builtin_arm_mrrc2) { 4736 Function *F; 4737 4738 switch (BuiltinID) { 4739 default: llvm_unreachable("unexpected builtin"); 4740 case ARM::BI__builtin_arm_mrrc: 4741 F = CGM.getIntrinsic(Intrinsic::arm_mrrc); 4742 break; 4743 case ARM::BI__builtin_arm_mrrc2: 4744 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2); 4745 break; 4746 } 4747 4748 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4749 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4750 Value *CRm = EmitScalarExpr(E->getArg(2)); 4751 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm}); 4752 4753 // Returns an unsigned 64 bit integer, represented 4754 // as two 32 bit integers. 4755 4756 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1); 4757 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0); 4758 Rt = Builder.CreateZExt(Rt, Int64Ty); 4759 Rt1 = Builder.CreateZExt(Rt1, Int64Ty); 4760 4761 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32); 4762 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true); 4763 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1); 4764 4765 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType())); 4766 } 4767 4768 if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 4769 ((BuiltinID == ARM::BI__builtin_arm_ldrex || 4770 BuiltinID == ARM::BI__builtin_arm_ldaex) && 4771 getContext().getTypeSize(E->getType()) == 64) || 4772 BuiltinID == ARM::BI__ldrexd) { 4773 Function *F; 4774 4775 switch (BuiltinID) { 4776 default: llvm_unreachable("unexpected builtin"); 4777 case ARM::BI__builtin_arm_ldaex: 4778 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd); 4779 break; 4780 case ARM::BI__builtin_arm_ldrexd: 4781 case ARM::BI__builtin_arm_ldrex: 4782 case ARM::BI__ldrexd: 4783 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 4784 break; 4785 } 4786 4787 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 4788 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 4789 "ldrexd"); 4790 4791 Value *Val0 = Builder.CreateExtractValue(Val, 1); 4792 Value *Val1 = Builder.CreateExtractValue(Val, 0); 4793 Val0 = Builder.CreateZExt(Val0, Int64Ty); 4794 Val1 = Builder.CreateZExt(Val1, Int64Ty); 4795 4796 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 4797 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 4798 Val = Builder.CreateOr(Val, Val1); 4799 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 4800 } 4801 4802 if (BuiltinID == ARM::BI__builtin_arm_ldrex || 4803 BuiltinID == ARM::BI__builtin_arm_ldaex) { 4804 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 4805 4806 QualType Ty = E->getType(); 4807 llvm::Type *RealResTy = ConvertType(Ty); 4808 llvm::Type *PtrTy = llvm::IntegerType::get( 4809 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 4810 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 4811 4812 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex 4813 ? Intrinsic::arm_ldaex 4814 : Intrinsic::arm_ldrex, 4815 PtrTy); 4816 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 4817 4818 if (RealResTy->isPointerTy()) 4819 return Builder.CreateIntToPtr(Val, RealResTy); 4820 else { 4821 llvm::Type *IntResTy = llvm::IntegerType::get( 4822 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 4823 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 4824 return Builder.CreateBitCast(Val, RealResTy); 4825 } 4826 } 4827 4828 if (BuiltinID == ARM::BI__builtin_arm_strexd || 4829 ((BuiltinID == ARM::BI__builtin_arm_stlex || 4830 BuiltinID == ARM::BI__builtin_arm_strex) && 4831 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 4832 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4833 ? Intrinsic::arm_stlexd 4834 : Intrinsic::arm_strexd); 4835 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty); 4836 4837 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 4838 Value *Val = EmitScalarExpr(E->getArg(0)); 4839 Builder.CreateStore(Val, Tmp); 4840 4841 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 4842 Val = Builder.CreateLoad(LdPtr); 4843 4844 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 4845 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 4846 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 4847 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd"); 4848 } 4849 4850 if (BuiltinID == ARM::BI__builtin_arm_strex || 4851 BuiltinID == ARM::BI__builtin_arm_stlex) { 4852 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 4853 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 4854 4855 QualType Ty = E->getArg(0)->getType(); 4856 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 4857 getContext().getTypeSize(Ty)); 4858 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 4859 4860 if (StoreVal->getType()->isPointerTy()) 4861 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 4862 else { 4863 llvm::Type *IntTy = llvm::IntegerType::get( 4864 getLLVMContext(), 4865 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 4866 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 4867 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 4868 } 4869 4870 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4871 ? Intrinsic::arm_stlex 4872 : Intrinsic::arm_strex, 4873 StoreAddr->getType()); 4874 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex"); 4875 } 4876 4877 switch (BuiltinID) { 4878 case ARM::BI__iso_volatile_load8: 4879 case ARM::BI__iso_volatile_load16: 4880 case ARM::BI__iso_volatile_load32: 4881 case ARM::BI__iso_volatile_load64: { 4882 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4883 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4884 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); 4885 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4886 LoadSize.getQuantity() * 8); 4887 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4888 llvm::LoadInst *Load = 4889 Builder.CreateAlignedLoad(Ptr, LoadSize); 4890 Load->setVolatile(true); 4891 return Load; 4892 } 4893 case ARM::BI__iso_volatile_store8: 4894 case ARM::BI__iso_volatile_store16: 4895 case ARM::BI__iso_volatile_store32: 4896 case ARM::BI__iso_volatile_store64: { 4897 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4898 Value *Value = EmitScalarExpr(E->getArg(1)); 4899 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4900 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 4901 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4902 StoreSize.getQuantity() * 8); 4903 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4904 llvm::StoreInst *Store = 4905 Builder.CreateAlignedStore(Value, Ptr, 4906 StoreSize); 4907 Store->setVolatile(true); 4908 return Store; 4909 } 4910 } 4911 4912 if (BuiltinID == ARM::BI__builtin_arm_clrex) { 4913 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 4914 return Builder.CreateCall(F); 4915 } 4916 4917 // CRC32 4918 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 4919 switch (BuiltinID) { 4920 case ARM::BI__builtin_arm_crc32b: 4921 CRCIntrinsicID = Intrinsic::arm_crc32b; break; 4922 case ARM::BI__builtin_arm_crc32cb: 4923 CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 4924 case ARM::BI__builtin_arm_crc32h: 4925 CRCIntrinsicID = Intrinsic::arm_crc32h; break; 4926 case ARM::BI__builtin_arm_crc32ch: 4927 CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 4928 case ARM::BI__builtin_arm_crc32w: 4929 case ARM::BI__builtin_arm_crc32d: 4930 CRCIntrinsicID = Intrinsic::arm_crc32w; break; 4931 case ARM::BI__builtin_arm_crc32cw: 4932 case ARM::BI__builtin_arm_crc32cd: 4933 CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 4934 } 4935 4936 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 4937 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 4938 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 4939 4940 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 4941 // intrinsics, hence we need different codegen for these cases. 4942 if (BuiltinID == ARM::BI__builtin_arm_crc32d || 4943 BuiltinID == ARM::BI__builtin_arm_crc32cd) { 4944 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4945 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 4946 Value *Arg1b = Builder.CreateLShr(Arg1, C1); 4947 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 4948 4949 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4950 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a}); 4951 return Builder.CreateCall(F, {Res, Arg1b}); 4952 } else { 4953 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 4954 4955 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4956 return Builder.CreateCall(F, {Arg0, Arg1}); 4957 } 4958 } 4959 4960 if (BuiltinID == ARM::BI__builtin_arm_rsr || 4961 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4962 BuiltinID == ARM::BI__builtin_arm_rsrp || 4963 BuiltinID == ARM::BI__builtin_arm_wsr || 4964 BuiltinID == ARM::BI__builtin_arm_wsr64 || 4965 BuiltinID == ARM::BI__builtin_arm_wsrp) { 4966 4967 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr || 4968 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4969 BuiltinID == ARM::BI__builtin_arm_rsrp; 4970 4971 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp || 4972 BuiltinID == ARM::BI__builtin_arm_wsrp; 4973 4974 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 || 4975 BuiltinID == ARM::BI__builtin_arm_wsr64; 4976 4977 llvm::Type *ValueType; 4978 llvm::Type *RegisterType; 4979 if (IsPointerBuiltin) { 4980 ValueType = VoidPtrTy; 4981 RegisterType = Int32Ty; 4982 } else if (Is64Bit) { 4983 ValueType = RegisterType = Int64Ty; 4984 } else { 4985 ValueType = RegisterType = Int32Ty; 4986 } 4987 4988 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 4989 } 4990 4991 // Find out if any arguments are required to be integer constant 4992 // expressions. 4993 unsigned ICEArguments = 0; 4994 ASTContext::GetBuiltinTypeError Error; 4995 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 4996 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 4997 4998 auto getAlignmentValue32 = [&](Address addr) -> Value* { 4999 return Builder.getInt32(addr.getAlignment().getQuantity()); 5000 }; 5001 5002 Address PtrOp0 = Address::invalid(); 5003 Address PtrOp1 = Address::invalid(); 5004 SmallVector<Value*, 4> Ops; 5005 bool HasExtraArg = HasExtraNeonArgument(BuiltinID); 5006 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0); 5007 for (unsigned i = 0, e = NumArgs; i != e; i++) { 5008 if (i == 0) { 5009 switch (BuiltinID) { 5010 case NEON::BI__builtin_neon_vld1_v: 5011 case NEON::BI__builtin_neon_vld1q_v: 5012 case NEON::BI__builtin_neon_vld1q_lane_v: 5013 case NEON::BI__builtin_neon_vld1_lane_v: 5014 case NEON::BI__builtin_neon_vld1_dup_v: 5015 case NEON::BI__builtin_neon_vld1q_dup_v: 5016 case NEON::BI__builtin_neon_vst1_v: 5017 case NEON::BI__builtin_neon_vst1q_v: 5018 case NEON::BI__builtin_neon_vst1q_lane_v: 5019 case NEON::BI__builtin_neon_vst1_lane_v: 5020 case NEON::BI__builtin_neon_vst2_v: 5021 case NEON::BI__builtin_neon_vst2q_v: 5022 case NEON::BI__builtin_neon_vst2_lane_v: 5023 case NEON::BI__builtin_neon_vst2q_lane_v: 5024 case NEON::BI__builtin_neon_vst3_v: 5025 case NEON::BI__builtin_neon_vst3q_v: 5026 case NEON::BI__builtin_neon_vst3_lane_v: 5027 case NEON::BI__builtin_neon_vst3q_lane_v: 5028 case NEON::BI__builtin_neon_vst4_v: 5029 case NEON::BI__builtin_neon_vst4q_v: 5030 case NEON::BI__builtin_neon_vst4_lane_v: 5031 case NEON::BI__builtin_neon_vst4q_lane_v: 5032 // Get the alignment for the argument in addition to the value; 5033 // we'll use it later. 5034 PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); 5035 Ops.push_back(PtrOp0.getPointer()); 5036 continue; 5037 } 5038 } 5039 if (i == 1) { 5040 switch (BuiltinID) { 5041 case NEON::BI__builtin_neon_vld2_v: 5042 case NEON::BI__builtin_neon_vld2q_v: 5043 case NEON::BI__builtin_neon_vld3_v: 5044 case NEON::BI__builtin_neon_vld3q_v: 5045 case NEON::BI__builtin_neon_vld4_v: 5046 case NEON::BI__builtin_neon_vld4q_v: 5047 case NEON::BI__builtin_neon_vld2_lane_v: 5048 case NEON::BI__builtin_neon_vld2q_lane_v: 5049 case NEON::BI__builtin_neon_vld3_lane_v: 5050 case NEON::BI__builtin_neon_vld3q_lane_v: 5051 case NEON::BI__builtin_neon_vld4_lane_v: 5052 case NEON::BI__builtin_neon_vld4q_lane_v: 5053 case NEON::BI__builtin_neon_vld2_dup_v: 5054 case NEON::BI__builtin_neon_vld3_dup_v: 5055 case NEON::BI__builtin_neon_vld4_dup_v: 5056 // Get the alignment for the argument in addition to the value; 5057 // we'll use it later. 5058 PtrOp1 = EmitPointerWithAlignment(E->getArg(1)); 5059 Ops.push_back(PtrOp1.getPointer()); 5060 continue; 5061 } 5062 } 5063 5064 if ((ICEArguments & (1 << i)) == 0) { 5065 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5066 } else { 5067 // If this is required to be a constant, constant fold it so that we know 5068 // that the generated intrinsic gets a ConstantInt. 5069 llvm::APSInt Result; 5070 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5071 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 5072 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5073 } 5074 } 5075 5076 switch (BuiltinID) { 5077 default: break; 5078 5079 case NEON::BI__builtin_neon_vget_lane_i8: 5080 case NEON::BI__builtin_neon_vget_lane_i16: 5081 case NEON::BI__builtin_neon_vget_lane_i32: 5082 case NEON::BI__builtin_neon_vget_lane_i64: 5083 case NEON::BI__builtin_neon_vget_lane_f32: 5084 case NEON::BI__builtin_neon_vgetq_lane_i8: 5085 case NEON::BI__builtin_neon_vgetq_lane_i16: 5086 case NEON::BI__builtin_neon_vgetq_lane_i32: 5087 case NEON::BI__builtin_neon_vgetq_lane_i64: 5088 case NEON::BI__builtin_neon_vgetq_lane_f32: 5089 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); 5090 5091 case NEON::BI__builtin_neon_vset_lane_i8: 5092 case NEON::BI__builtin_neon_vset_lane_i16: 5093 case NEON::BI__builtin_neon_vset_lane_i32: 5094 case NEON::BI__builtin_neon_vset_lane_i64: 5095 case NEON::BI__builtin_neon_vset_lane_f32: 5096 case NEON::BI__builtin_neon_vsetq_lane_i8: 5097 case NEON::BI__builtin_neon_vsetq_lane_i16: 5098 case NEON::BI__builtin_neon_vsetq_lane_i32: 5099 case NEON::BI__builtin_neon_vsetq_lane_i64: 5100 case NEON::BI__builtin_neon_vsetq_lane_f32: 5101 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 5102 5103 case NEON::BI__builtin_neon_vsha1h_u32: 5104 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, 5105 "vsha1h"); 5106 case NEON::BI__builtin_neon_vsha1cq_u32: 5107 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, 5108 "vsha1h"); 5109 case NEON::BI__builtin_neon_vsha1pq_u32: 5110 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, 5111 "vsha1h"); 5112 case NEON::BI__builtin_neon_vsha1mq_u32: 5113 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, 5114 "vsha1h"); 5115 5116 // The ARM _MoveToCoprocessor builtins put the input register value as 5117 // the first argument, but the LLVM intrinsic expects it as the third one. 5118 case ARM::BI_MoveToCoprocessor: 5119 case ARM::BI_MoveToCoprocessor2: { 5120 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ? 5121 Intrinsic::arm_mcr : Intrinsic::arm_mcr2); 5122 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], 5123 Ops[3], Ops[4], Ops[5]}); 5124 } 5125 case ARM::BI_BitScanForward: 5126 case ARM::BI_BitScanForward64: 5127 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 5128 case ARM::BI_BitScanReverse: 5129 case ARM::BI_BitScanReverse64: 5130 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 5131 5132 case ARM::BI_InterlockedAnd64: 5133 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 5134 case ARM::BI_InterlockedExchange64: 5135 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 5136 case ARM::BI_InterlockedExchangeAdd64: 5137 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 5138 case ARM::BI_InterlockedExchangeSub64: 5139 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 5140 case ARM::BI_InterlockedOr64: 5141 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 5142 case ARM::BI_InterlockedXor64: 5143 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 5144 case ARM::BI_InterlockedDecrement64: 5145 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 5146 case ARM::BI_InterlockedIncrement64: 5147 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 5148 } 5149 5150 // Get the last argument, which specifies the vector type. 5151 assert(HasExtraArg); 5152 llvm::APSInt Result; 5153 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5154 if (!Arg->isIntegerConstantExpr(Result, getContext())) 5155 return nullptr; 5156 5157 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 5158 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 5159 // Determine the overloaded type of this builtin. 5160 llvm::Type *Ty; 5161 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 5162 Ty = FloatTy; 5163 else 5164 Ty = DoubleTy; 5165 5166 // Determine whether this is an unsigned conversion or not. 5167 bool usgn = Result.getZExtValue() == 1; 5168 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 5169 5170 // Call the appropriate intrinsic. 5171 Function *F = CGM.getIntrinsic(Int, Ty); 5172 return Builder.CreateCall(F, Ops, "vcvtr"); 5173 } 5174 5175 // Determine the type of this overloaded NEON intrinsic. 5176 NeonTypeFlags Type(Result.getZExtValue()); 5177 bool usgn = Type.isUnsigned(); 5178 bool rightShift = false; 5179 5180 llvm::VectorType *VTy = GetNeonType(this, Type); 5181 llvm::Type *Ty = VTy; 5182 if (!Ty) 5183 return nullptr; 5184 5185 // Many NEON builtins have identical semantics and uses in ARM and 5186 // AArch64. Emit these in a single function. 5187 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap); 5188 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5189 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); 5190 if (Builtin) 5191 return EmitCommonNeonBuiltinExpr( 5192 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 5193 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1); 5194 5195 unsigned Int; 5196 switch (BuiltinID) { 5197 default: return nullptr; 5198 case NEON::BI__builtin_neon_vld1q_lane_v: 5199 // Handle 64-bit integer elements as a special case. Use shuffles of 5200 // one-element vectors to avoid poor code for i64 in the backend. 5201 if (VTy->getElementType()->isIntegerTy(64)) { 5202 // Extract the other lane. 5203 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5204 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 5205 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 5206 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5207 // Load the value as a one-element vector. 5208 Ty = llvm::VectorType::get(VTy->getElementType(), 1); 5209 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5210 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys); 5211 Value *Align = getAlignmentValue32(PtrOp0); 5212 Value *Ld = Builder.CreateCall(F, {Ops[0], Align}); 5213 // Combine them. 5214 uint32_t Indices[] = {1 - Lane, Lane}; 5215 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices); 5216 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 5217 } 5218 // fall through 5219 case NEON::BI__builtin_neon_vld1_lane_v: { 5220 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5221 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType()); 5222 Value *Ld = Builder.CreateLoad(PtrOp0); 5223 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 5224 } 5225 case NEON::BI__builtin_neon_vld2_dup_v: 5226 case NEON::BI__builtin_neon_vld3_dup_v: 5227 case NEON::BI__builtin_neon_vld4_dup_v: { 5228 // Handle 64-bit elements as a special-case. There is no "dup" needed. 5229 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 5230 switch (BuiltinID) { 5231 case NEON::BI__builtin_neon_vld2_dup_v: 5232 Int = Intrinsic::arm_neon_vld2; 5233 break; 5234 case NEON::BI__builtin_neon_vld3_dup_v: 5235 Int = Intrinsic::arm_neon_vld3; 5236 break; 5237 case NEON::BI__builtin_neon_vld4_dup_v: 5238 Int = Intrinsic::arm_neon_vld4; 5239 break; 5240 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5241 } 5242 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5243 Function *F = CGM.getIntrinsic(Int, Tys); 5244 llvm::Value *Align = getAlignmentValue32(PtrOp1); 5245 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup"); 5246 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5247 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5248 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5249 } 5250 switch (BuiltinID) { 5251 case NEON::BI__builtin_neon_vld2_dup_v: 5252 Int = Intrinsic::arm_neon_vld2lane; 5253 break; 5254 case NEON::BI__builtin_neon_vld3_dup_v: 5255 Int = Intrinsic::arm_neon_vld3lane; 5256 break; 5257 case NEON::BI__builtin_neon_vld4_dup_v: 5258 Int = Intrinsic::arm_neon_vld4lane; 5259 break; 5260 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5261 } 5262 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5263 Function *F = CGM.getIntrinsic(Int, Tys); 5264 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 5265 5266 SmallVector<Value*, 6> Args; 5267 Args.push_back(Ops[1]); 5268 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 5269 5270 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 5271 Args.push_back(CI); 5272 Args.push_back(getAlignmentValue32(PtrOp1)); 5273 5274 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 5275 // splat lane 0 to all elts in each vector of the result. 5276 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 5277 Value *Val = Builder.CreateExtractValue(Ops[1], i); 5278 Value *Elt = Builder.CreateBitCast(Val, Ty); 5279 Elt = EmitNeonSplat(Elt, CI); 5280 Elt = Builder.CreateBitCast(Elt, Val->getType()); 5281 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 5282 } 5283 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5284 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5285 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5286 } 5287 case NEON::BI__builtin_neon_vqrshrn_n_v: 5288 Int = 5289 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 5290 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 5291 1, true); 5292 case NEON::BI__builtin_neon_vqrshrun_n_v: 5293 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 5294 Ops, "vqrshrun_n", 1, true); 5295 case NEON::BI__builtin_neon_vqshrn_n_v: 5296 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 5297 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 5298 1, true); 5299 case NEON::BI__builtin_neon_vqshrun_n_v: 5300 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 5301 Ops, "vqshrun_n", 1, true); 5302 case NEON::BI__builtin_neon_vrecpe_v: 5303 case NEON::BI__builtin_neon_vrecpeq_v: 5304 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 5305 Ops, "vrecpe"); 5306 case NEON::BI__builtin_neon_vrshrn_n_v: 5307 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 5308 Ops, "vrshrn_n", 1, true); 5309 case NEON::BI__builtin_neon_vrsra_n_v: 5310 case NEON::BI__builtin_neon_vrsraq_n_v: 5311 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5312 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5313 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 5314 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 5315 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]}); 5316 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 5317 case NEON::BI__builtin_neon_vsri_n_v: 5318 case NEON::BI__builtin_neon_vsriq_n_v: 5319 rightShift = true; 5320 LLVM_FALLTHROUGH; 5321 case NEON::BI__builtin_neon_vsli_n_v: 5322 case NEON::BI__builtin_neon_vsliq_n_v: 5323 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 5324 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 5325 Ops, "vsli_n"); 5326 case NEON::BI__builtin_neon_vsra_n_v: 5327 case NEON::BI__builtin_neon_vsraq_n_v: 5328 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5329 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 5330 return Builder.CreateAdd(Ops[0], Ops[1]); 5331 case NEON::BI__builtin_neon_vst1q_lane_v: 5332 // Handle 64-bit integer elements as a special case. Use a shuffle to get 5333 // a one-element vector and avoid poor code for i64 in the backend. 5334 if (VTy->getElementType()->isIntegerTy(64)) { 5335 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5336 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 5337 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5338 Ops[2] = getAlignmentValue32(PtrOp0); 5339 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()}; 5340 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 5341 Tys), Ops); 5342 } 5343 // fall through 5344 case NEON::BI__builtin_neon_vst1_lane_v: { 5345 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5346 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 5347 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5348 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty)); 5349 return St; 5350 } 5351 case NEON::BI__builtin_neon_vtbl1_v: 5352 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 5353 Ops, "vtbl1"); 5354 case NEON::BI__builtin_neon_vtbl2_v: 5355 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 5356 Ops, "vtbl2"); 5357 case NEON::BI__builtin_neon_vtbl3_v: 5358 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 5359 Ops, "vtbl3"); 5360 case NEON::BI__builtin_neon_vtbl4_v: 5361 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 5362 Ops, "vtbl4"); 5363 case NEON::BI__builtin_neon_vtbx1_v: 5364 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 5365 Ops, "vtbx1"); 5366 case NEON::BI__builtin_neon_vtbx2_v: 5367 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 5368 Ops, "vtbx2"); 5369 case NEON::BI__builtin_neon_vtbx3_v: 5370 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 5371 Ops, "vtbx3"); 5372 case NEON::BI__builtin_neon_vtbx4_v: 5373 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 5374 Ops, "vtbx4"); 5375 } 5376 } 5377 5378 static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID, 5379 const CallExpr *E, 5380 SmallVectorImpl<Value *> &Ops) { 5381 unsigned int Int = 0; 5382 const char *s = nullptr; 5383 5384 switch (BuiltinID) { 5385 default: 5386 return nullptr; 5387 case NEON::BI__builtin_neon_vtbl1_v: 5388 case NEON::BI__builtin_neon_vqtbl1_v: 5389 case NEON::BI__builtin_neon_vqtbl1q_v: 5390 case NEON::BI__builtin_neon_vtbl2_v: 5391 case NEON::BI__builtin_neon_vqtbl2_v: 5392 case NEON::BI__builtin_neon_vqtbl2q_v: 5393 case NEON::BI__builtin_neon_vtbl3_v: 5394 case NEON::BI__builtin_neon_vqtbl3_v: 5395 case NEON::BI__builtin_neon_vqtbl3q_v: 5396 case NEON::BI__builtin_neon_vtbl4_v: 5397 case NEON::BI__builtin_neon_vqtbl4_v: 5398 case NEON::BI__builtin_neon_vqtbl4q_v: 5399 break; 5400 case NEON::BI__builtin_neon_vtbx1_v: 5401 case NEON::BI__builtin_neon_vqtbx1_v: 5402 case NEON::BI__builtin_neon_vqtbx1q_v: 5403 case NEON::BI__builtin_neon_vtbx2_v: 5404 case NEON::BI__builtin_neon_vqtbx2_v: 5405 case NEON::BI__builtin_neon_vqtbx2q_v: 5406 case NEON::BI__builtin_neon_vtbx3_v: 5407 case NEON::BI__builtin_neon_vqtbx3_v: 5408 case NEON::BI__builtin_neon_vqtbx3q_v: 5409 case NEON::BI__builtin_neon_vtbx4_v: 5410 case NEON::BI__builtin_neon_vqtbx4_v: 5411 case NEON::BI__builtin_neon_vqtbx4q_v: 5412 break; 5413 } 5414 5415 assert(E->getNumArgs() >= 3); 5416 5417 // Get the last argument, which specifies the vector type. 5418 llvm::APSInt Result; 5419 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 5420 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) 5421 return nullptr; 5422 5423 // Determine the type of this overloaded NEON intrinsic. 5424 NeonTypeFlags Type(Result.getZExtValue()); 5425 llvm::VectorType *Ty = GetNeonType(&CGF, Type); 5426 if (!Ty) 5427 return nullptr; 5428 5429 CodeGen::CGBuilderTy &Builder = CGF.Builder; 5430 5431 // AArch64 scalar builtins are not overloaded, they do not have an extra 5432 // argument that specifies the vector type, need to handle each case. 5433 switch (BuiltinID) { 5434 case NEON::BI__builtin_neon_vtbl1_v: { 5435 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr, 5436 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1, 5437 "vtbl1"); 5438 } 5439 case NEON::BI__builtin_neon_vtbl2_v: { 5440 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr, 5441 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1, 5442 "vtbl1"); 5443 } 5444 case NEON::BI__builtin_neon_vtbl3_v: { 5445 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr, 5446 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2, 5447 "vtbl2"); 5448 } 5449 case NEON::BI__builtin_neon_vtbl4_v: { 5450 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr, 5451 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2, 5452 "vtbl2"); 5453 } 5454 case NEON::BI__builtin_neon_vtbx1_v: { 5455 Value *TblRes = 5456 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2], 5457 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1"); 5458 5459 llvm::Constant *EightV = ConstantInt::get(Ty, 8); 5460 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); 5461 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5462 5463 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5464 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5465 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5466 } 5467 case NEON::BI__builtin_neon_vtbx2_v: { 5468 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0], 5469 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1, 5470 "vtbx1"); 5471 } 5472 case NEON::BI__builtin_neon_vtbx3_v: { 5473 Value *TblRes = 5474 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4], 5475 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2"); 5476 5477 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24); 5478 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], 5479 TwentyFourV); 5480 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5481 5482 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5483 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5484 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5485 } 5486 case NEON::BI__builtin_neon_vtbx4_v: { 5487 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0], 5488 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2, 5489 "vtbx2"); 5490 } 5491 case NEON::BI__builtin_neon_vqtbl1_v: 5492 case NEON::BI__builtin_neon_vqtbl1q_v: 5493 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break; 5494 case NEON::BI__builtin_neon_vqtbl2_v: 5495 case NEON::BI__builtin_neon_vqtbl2q_v: { 5496 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break; 5497 case NEON::BI__builtin_neon_vqtbl3_v: 5498 case NEON::BI__builtin_neon_vqtbl3q_v: 5499 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break; 5500 case NEON::BI__builtin_neon_vqtbl4_v: 5501 case NEON::BI__builtin_neon_vqtbl4q_v: 5502 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break; 5503 case NEON::BI__builtin_neon_vqtbx1_v: 5504 case NEON::BI__builtin_neon_vqtbx1q_v: 5505 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break; 5506 case NEON::BI__builtin_neon_vqtbx2_v: 5507 case NEON::BI__builtin_neon_vqtbx2q_v: 5508 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break; 5509 case NEON::BI__builtin_neon_vqtbx3_v: 5510 case NEON::BI__builtin_neon_vqtbx3q_v: 5511 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break; 5512 case NEON::BI__builtin_neon_vqtbx4_v: 5513 case NEON::BI__builtin_neon_vqtbx4q_v: 5514 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break; 5515 } 5516 } 5517 5518 if (!Int) 5519 return nullptr; 5520 5521 Function *F = CGF.CGM.getIntrinsic(Int, Ty); 5522 return CGF.EmitNeonCall(F, Ops, s); 5523 } 5524 5525 Value *CodeGenFunction::vectorWrapScalar16(Value *Op) { 5526 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4); 5527 Op = Builder.CreateBitCast(Op, Int16Ty); 5528 Value *V = UndefValue::get(VTy); 5529 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 5530 Op = Builder.CreateInsertElement(V, Op, CI); 5531 return Op; 5532 } 5533 5534 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 5535 const CallExpr *E) { 5536 unsigned HintID = static_cast<unsigned>(-1); 5537 switch (BuiltinID) { 5538 default: break; 5539 case AArch64::BI__builtin_arm_nop: 5540 HintID = 0; 5541 break; 5542 case AArch64::BI__builtin_arm_yield: 5543 HintID = 1; 5544 break; 5545 case AArch64::BI__builtin_arm_wfe: 5546 HintID = 2; 5547 break; 5548 case AArch64::BI__builtin_arm_wfi: 5549 HintID = 3; 5550 break; 5551 case AArch64::BI__builtin_arm_sev: 5552 HintID = 4; 5553 break; 5554 case AArch64::BI__builtin_arm_sevl: 5555 HintID = 5; 5556 break; 5557 } 5558 5559 if (HintID != static_cast<unsigned>(-1)) { 5560 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint); 5561 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); 5562 } 5563 5564 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { 5565 Value *Address = EmitScalarExpr(E->getArg(0)); 5566 Value *RW = EmitScalarExpr(E->getArg(1)); 5567 Value *CacheLevel = EmitScalarExpr(E->getArg(2)); 5568 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3)); 5569 Value *IsData = EmitScalarExpr(E->getArg(4)); 5570 5571 Value *Locality = nullptr; 5572 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) { 5573 // Temporal fetch, needs to convert cache level to locality. 5574 Locality = llvm::ConstantInt::get(Int32Ty, 5575 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3); 5576 } else { 5577 // Streaming fetch. 5578 Locality = llvm::ConstantInt::get(Int32Ty, 0); 5579 } 5580 5581 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify 5582 // PLDL3STRM or PLDL2STRM. 5583 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 5584 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 5585 } 5586 5587 if (BuiltinID == AArch64::BI__builtin_arm_rbit) { 5588 assert((getContext().getTypeSize(E->getType()) == 32) && 5589 "rbit of unusual size!"); 5590 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5591 return Builder.CreateCall( 5592 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5593 } 5594 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) { 5595 assert((getContext().getTypeSize(E->getType()) == 64) && 5596 "rbit of unusual size!"); 5597 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5598 return Builder.CreateCall( 5599 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5600 } 5601 5602 if (BuiltinID == AArch64::BI__clear_cache) { 5603 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 5604 const FunctionDecl *FD = E->getDirectCallee(); 5605 Value *Ops[2]; 5606 for (unsigned i = 0; i < 2; i++) 5607 Ops[i] = EmitScalarExpr(E->getArg(i)); 5608 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 5609 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 5610 StringRef Name = FD->getName(); 5611 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 5612 } 5613 5614 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex || 5615 BuiltinID == AArch64::BI__builtin_arm_ldaex) && 5616 getContext().getTypeSize(E->getType()) == 128) { 5617 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5618 ? Intrinsic::aarch64_ldaxp 5619 : Intrinsic::aarch64_ldxp); 5620 5621 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 5622 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 5623 "ldxp"); 5624 5625 Value *Val0 = Builder.CreateExtractValue(Val, 1); 5626 Value *Val1 = Builder.CreateExtractValue(Val, 0); 5627 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 5628 Val0 = Builder.CreateZExt(Val0, Int128Ty); 5629 Val1 = Builder.CreateZExt(Val1, Int128Ty); 5630 5631 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64); 5632 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 5633 Val = Builder.CreateOr(Val, Val1); 5634 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 5635 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex || 5636 BuiltinID == AArch64::BI__builtin_arm_ldaex) { 5637 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 5638 5639 QualType Ty = E->getType(); 5640 llvm::Type *RealResTy = ConvertType(Ty); 5641 llvm::Type *PtrTy = llvm::IntegerType::get( 5642 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 5643 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 5644 5645 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5646 ? Intrinsic::aarch64_ldaxr 5647 : Intrinsic::aarch64_ldxr, 5648 PtrTy); 5649 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr"); 5650 5651 if (RealResTy->isPointerTy()) 5652 return Builder.CreateIntToPtr(Val, RealResTy); 5653 5654 llvm::Type *IntResTy = llvm::IntegerType::get( 5655 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 5656 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 5657 return Builder.CreateBitCast(Val, RealResTy); 5658 } 5659 5660 if ((BuiltinID == AArch64::BI__builtin_arm_strex || 5661 BuiltinID == AArch64::BI__builtin_arm_stlex) && 5662 getContext().getTypeSize(E->getArg(0)->getType()) == 128) { 5663 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5664 ? Intrinsic::aarch64_stlxp 5665 : Intrinsic::aarch64_stxp); 5666 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty); 5667 5668 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 5669 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true); 5670 5671 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy)); 5672 llvm::Value *Val = Builder.CreateLoad(Tmp); 5673 5674 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 5675 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 5676 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), 5677 Int8PtrTy); 5678 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp"); 5679 } 5680 5681 if (BuiltinID == AArch64::BI__builtin_arm_strex || 5682 BuiltinID == AArch64::BI__builtin_arm_stlex) { 5683 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 5684 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 5685 5686 QualType Ty = E->getArg(0)->getType(); 5687 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 5688 getContext().getTypeSize(Ty)); 5689 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 5690 5691 if (StoreVal->getType()->isPointerTy()) 5692 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty); 5693 else { 5694 llvm::Type *IntTy = llvm::IntegerType::get( 5695 getLLVMContext(), 5696 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 5697 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 5698 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty); 5699 } 5700 5701 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5702 ? Intrinsic::aarch64_stlxr 5703 : Intrinsic::aarch64_stxr, 5704 StoreAddr->getType()); 5705 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr"); 5706 } 5707 5708 if (BuiltinID == AArch64::BI__builtin_arm_clrex) { 5709 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex); 5710 return Builder.CreateCall(F); 5711 } 5712 5713 // CRC32 5714 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 5715 switch (BuiltinID) { 5716 case AArch64::BI__builtin_arm_crc32b: 5717 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break; 5718 case AArch64::BI__builtin_arm_crc32cb: 5719 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break; 5720 case AArch64::BI__builtin_arm_crc32h: 5721 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break; 5722 case AArch64::BI__builtin_arm_crc32ch: 5723 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break; 5724 case AArch64::BI__builtin_arm_crc32w: 5725 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break; 5726 case AArch64::BI__builtin_arm_crc32cw: 5727 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break; 5728 case AArch64::BI__builtin_arm_crc32d: 5729 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break; 5730 case AArch64::BI__builtin_arm_crc32cd: 5731 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break; 5732 } 5733 5734 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 5735 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 5736 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 5737 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 5738 5739 llvm::Type *DataTy = F->getFunctionType()->getParamType(1); 5740 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy); 5741 5742 return Builder.CreateCall(F, {Arg0, Arg1}); 5743 } 5744 5745 if (BuiltinID == AArch64::BI__builtin_arm_rsr || 5746 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5747 BuiltinID == AArch64::BI__builtin_arm_rsrp || 5748 BuiltinID == AArch64::BI__builtin_arm_wsr || 5749 BuiltinID == AArch64::BI__builtin_arm_wsr64 || 5750 BuiltinID == AArch64::BI__builtin_arm_wsrp) { 5751 5752 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr || 5753 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5754 BuiltinID == AArch64::BI__builtin_arm_rsrp; 5755 5756 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp || 5757 BuiltinID == AArch64::BI__builtin_arm_wsrp; 5758 5759 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr && 5760 BuiltinID != AArch64::BI__builtin_arm_wsr; 5761 5762 llvm::Type *ValueType; 5763 llvm::Type *RegisterType = Int64Ty; 5764 if (IsPointerBuiltin) { 5765 ValueType = VoidPtrTy; 5766 } else if (Is64Bit) { 5767 ValueType = Int64Ty; 5768 } else { 5769 ValueType = Int32Ty; 5770 } 5771 5772 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 5773 } 5774 5775 // Find out if any arguments are required to be integer constant 5776 // expressions. 5777 unsigned ICEArguments = 0; 5778 ASTContext::GetBuiltinTypeError Error; 5779 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 5780 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 5781 5782 llvm::SmallVector<Value*, 4> Ops; 5783 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 5784 if ((ICEArguments & (1 << i)) == 0) { 5785 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5786 } else { 5787 // If this is required to be a constant, constant fold it so that we know 5788 // that the generated intrinsic gets a ConstantInt. 5789 llvm::APSInt Result; 5790 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5791 assert(IsConst && "Constant arg isn't actually constant?"); 5792 (void)IsConst; 5793 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5794 } 5795 } 5796 5797 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap); 5798 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5799 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted); 5800 5801 if (Builtin) { 5802 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1))); 5803 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E); 5804 assert(Result && "SISD intrinsic should have been handled"); 5805 return Result; 5806 } 5807 5808 llvm::APSInt Result; 5809 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5810 NeonTypeFlags Type(0); 5811 if (Arg->isIntegerConstantExpr(Result, getContext())) 5812 // Determine the type of this overloaded NEON intrinsic. 5813 Type = NeonTypeFlags(Result.getZExtValue()); 5814 5815 bool usgn = Type.isUnsigned(); 5816 bool quad = Type.isQuad(); 5817 5818 // Handle non-overloaded intrinsics first. 5819 switch (BuiltinID) { 5820 default: break; 5821 case NEON::BI__builtin_neon_vldrq_p128: { 5822 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128); 5823 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0); 5824 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy); 5825 return Builder.CreateAlignedLoad(Int128Ty, Ptr, 5826 CharUnits::fromQuantity(16)); 5827 } 5828 case NEON::BI__builtin_neon_vstrq_p128: { 5829 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128); 5830 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy); 5831 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr); 5832 } 5833 case NEON::BI__builtin_neon_vcvts_u32_f32: 5834 case NEON::BI__builtin_neon_vcvtd_u64_f64: 5835 usgn = true; 5836 // FALL THROUGH 5837 case NEON::BI__builtin_neon_vcvts_s32_f32: 5838 case NEON::BI__builtin_neon_vcvtd_s64_f64: { 5839 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5840 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5841 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5842 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5843 Ops[0] = Builder.CreateBitCast(Ops[0], FTy); 5844 if (usgn) 5845 return Builder.CreateFPToUI(Ops[0], InTy); 5846 return Builder.CreateFPToSI(Ops[0], InTy); 5847 } 5848 case NEON::BI__builtin_neon_vcvts_f32_u32: 5849 case NEON::BI__builtin_neon_vcvtd_f64_u64: 5850 usgn = true; 5851 // FALL THROUGH 5852 case NEON::BI__builtin_neon_vcvts_f32_s32: 5853 case NEON::BI__builtin_neon_vcvtd_f64_s64: { 5854 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5855 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5856 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5857 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5858 Ops[0] = Builder.CreateBitCast(Ops[0], InTy); 5859 if (usgn) 5860 return Builder.CreateUIToFP(Ops[0], FTy); 5861 return Builder.CreateSIToFP(Ops[0], FTy); 5862 } 5863 case NEON::BI__builtin_neon_vpaddd_s64: { 5864 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2); 5865 Value *Vec = EmitScalarExpr(E->getArg(0)); 5866 // The vector is v2f64, so make sure it's bitcast to that. 5867 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64"); 5868 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5869 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5870 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5871 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5872 // Pairwise addition of a v2f64 into a scalar f64. 5873 return Builder.CreateAdd(Op0, Op1, "vpaddd"); 5874 } 5875 case NEON::BI__builtin_neon_vpaddd_f64: { 5876 llvm::Type *Ty = 5877 llvm::VectorType::get(DoubleTy, 2); 5878 Value *Vec = EmitScalarExpr(E->getArg(0)); 5879 // The vector is v2f64, so make sure it's bitcast to that. 5880 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64"); 5881 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5882 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5883 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5884 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5885 // Pairwise addition of a v2f64 into a scalar f64. 5886 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5887 } 5888 case NEON::BI__builtin_neon_vpadds_f32: { 5889 llvm::Type *Ty = 5890 llvm::VectorType::get(FloatTy, 2); 5891 Value *Vec = EmitScalarExpr(E->getArg(0)); 5892 // The vector is v2f32, so make sure it's bitcast to that. 5893 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32"); 5894 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5895 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5896 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5897 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5898 // Pairwise addition of a v2f32 into a scalar f32. 5899 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5900 } 5901 case NEON::BI__builtin_neon_vceqzd_s64: 5902 case NEON::BI__builtin_neon_vceqzd_f64: 5903 case NEON::BI__builtin_neon_vceqzs_f32: 5904 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5905 return EmitAArch64CompareBuiltinExpr( 5906 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5907 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz"); 5908 case NEON::BI__builtin_neon_vcgezd_s64: 5909 case NEON::BI__builtin_neon_vcgezd_f64: 5910 case NEON::BI__builtin_neon_vcgezs_f32: 5911 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5912 return EmitAArch64CompareBuiltinExpr( 5913 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5914 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez"); 5915 case NEON::BI__builtin_neon_vclezd_s64: 5916 case NEON::BI__builtin_neon_vclezd_f64: 5917 case NEON::BI__builtin_neon_vclezs_f32: 5918 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5919 return EmitAArch64CompareBuiltinExpr( 5920 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5921 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez"); 5922 case NEON::BI__builtin_neon_vcgtzd_s64: 5923 case NEON::BI__builtin_neon_vcgtzd_f64: 5924 case NEON::BI__builtin_neon_vcgtzs_f32: 5925 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5926 return EmitAArch64CompareBuiltinExpr( 5927 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5928 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz"); 5929 case NEON::BI__builtin_neon_vcltzd_s64: 5930 case NEON::BI__builtin_neon_vcltzd_f64: 5931 case NEON::BI__builtin_neon_vcltzs_f32: 5932 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5933 return EmitAArch64CompareBuiltinExpr( 5934 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5935 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz"); 5936 5937 case NEON::BI__builtin_neon_vceqzd_u64: { 5938 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5939 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 5940 Ops[0] = 5941 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty)); 5942 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd"); 5943 } 5944 case NEON::BI__builtin_neon_vceqd_f64: 5945 case NEON::BI__builtin_neon_vcled_f64: 5946 case NEON::BI__builtin_neon_vcltd_f64: 5947 case NEON::BI__builtin_neon_vcged_f64: 5948 case NEON::BI__builtin_neon_vcgtd_f64: { 5949 llvm::CmpInst::Predicate P; 5950 switch (BuiltinID) { 5951 default: llvm_unreachable("missing builtin ID in switch!"); 5952 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break; 5953 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break; 5954 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break; 5955 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break; 5956 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break; 5957 } 5958 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5959 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 5960 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 5961 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5962 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd"); 5963 } 5964 case NEON::BI__builtin_neon_vceqs_f32: 5965 case NEON::BI__builtin_neon_vcles_f32: 5966 case NEON::BI__builtin_neon_vclts_f32: 5967 case NEON::BI__builtin_neon_vcges_f32: 5968 case NEON::BI__builtin_neon_vcgts_f32: { 5969 llvm::CmpInst::Predicate P; 5970 switch (BuiltinID) { 5971 default: llvm_unreachable("missing builtin ID in switch!"); 5972 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break; 5973 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break; 5974 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break; 5975 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break; 5976 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break; 5977 } 5978 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5979 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 5980 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy); 5981 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5982 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd"); 5983 } 5984 case NEON::BI__builtin_neon_vceqd_s64: 5985 case NEON::BI__builtin_neon_vceqd_u64: 5986 case NEON::BI__builtin_neon_vcgtd_s64: 5987 case NEON::BI__builtin_neon_vcgtd_u64: 5988 case NEON::BI__builtin_neon_vcltd_s64: 5989 case NEON::BI__builtin_neon_vcltd_u64: 5990 case NEON::BI__builtin_neon_vcged_u64: 5991 case NEON::BI__builtin_neon_vcged_s64: 5992 case NEON::BI__builtin_neon_vcled_u64: 5993 case NEON::BI__builtin_neon_vcled_s64: { 5994 llvm::CmpInst::Predicate P; 5995 switch (BuiltinID) { 5996 default: llvm_unreachable("missing builtin ID in switch!"); 5997 case NEON::BI__builtin_neon_vceqd_s64: 5998 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break; 5999 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break; 6000 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break; 6001 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break; 6002 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break; 6003 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break; 6004 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break; 6005 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break; 6006 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break; 6007 } 6008 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6009 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6010 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6011 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]); 6012 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd"); 6013 } 6014 case NEON::BI__builtin_neon_vtstd_s64: 6015 case NEON::BI__builtin_neon_vtstd_u64: { 6016 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6017 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6018 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6019 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 6020 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 6021 llvm::Constant::getNullValue(Int64Ty)); 6022 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd"); 6023 } 6024 case NEON::BI__builtin_neon_vset_lane_i8: 6025 case NEON::BI__builtin_neon_vset_lane_i16: 6026 case NEON::BI__builtin_neon_vset_lane_i32: 6027 case NEON::BI__builtin_neon_vset_lane_i64: 6028 case NEON::BI__builtin_neon_vset_lane_f32: 6029 case NEON::BI__builtin_neon_vsetq_lane_i8: 6030 case NEON::BI__builtin_neon_vsetq_lane_i16: 6031 case NEON::BI__builtin_neon_vsetq_lane_i32: 6032 case NEON::BI__builtin_neon_vsetq_lane_i64: 6033 case NEON::BI__builtin_neon_vsetq_lane_f32: 6034 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6035 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6036 case NEON::BI__builtin_neon_vset_lane_f64: 6037 // The vector type needs a cast for the v1f64 variant. 6038 Ops[1] = Builder.CreateBitCast(Ops[1], 6039 llvm::VectorType::get(DoubleTy, 1)); 6040 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6041 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6042 case NEON::BI__builtin_neon_vsetq_lane_f64: 6043 // The vector type needs a cast for the v2f64 variant. 6044 Ops[1] = Builder.CreateBitCast(Ops[1], 6045 llvm::VectorType::get(DoubleTy, 2)); 6046 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6047 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6048 6049 case NEON::BI__builtin_neon_vget_lane_i8: 6050 case NEON::BI__builtin_neon_vdupb_lane_i8: 6051 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8)); 6052 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6053 "vget_lane"); 6054 case NEON::BI__builtin_neon_vgetq_lane_i8: 6055 case NEON::BI__builtin_neon_vdupb_laneq_i8: 6056 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16)); 6057 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6058 "vgetq_lane"); 6059 case NEON::BI__builtin_neon_vget_lane_i16: 6060 case NEON::BI__builtin_neon_vduph_lane_i16: 6061 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4)); 6062 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6063 "vget_lane"); 6064 case NEON::BI__builtin_neon_vgetq_lane_i16: 6065 case NEON::BI__builtin_neon_vduph_laneq_i16: 6066 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8)); 6067 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6068 "vgetq_lane"); 6069 case NEON::BI__builtin_neon_vget_lane_i32: 6070 case NEON::BI__builtin_neon_vdups_lane_i32: 6071 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2)); 6072 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6073 "vget_lane"); 6074 case NEON::BI__builtin_neon_vdups_lane_f32: 6075 Ops[0] = Builder.CreateBitCast(Ops[0], 6076 llvm::VectorType::get(FloatTy, 2)); 6077 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6078 "vdups_lane"); 6079 case NEON::BI__builtin_neon_vgetq_lane_i32: 6080 case NEON::BI__builtin_neon_vdups_laneq_i32: 6081 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 6082 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6083 "vgetq_lane"); 6084 case NEON::BI__builtin_neon_vget_lane_i64: 6085 case NEON::BI__builtin_neon_vdupd_lane_i64: 6086 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1)); 6087 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6088 "vget_lane"); 6089 case NEON::BI__builtin_neon_vdupd_lane_f64: 6090 Ops[0] = Builder.CreateBitCast(Ops[0], 6091 llvm::VectorType::get(DoubleTy, 1)); 6092 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6093 "vdupd_lane"); 6094 case NEON::BI__builtin_neon_vgetq_lane_i64: 6095 case NEON::BI__builtin_neon_vdupd_laneq_i64: 6096 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 6097 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6098 "vgetq_lane"); 6099 case NEON::BI__builtin_neon_vget_lane_f32: 6100 Ops[0] = Builder.CreateBitCast(Ops[0], 6101 llvm::VectorType::get(FloatTy, 2)); 6102 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6103 "vget_lane"); 6104 case NEON::BI__builtin_neon_vget_lane_f64: 6105 Ops[0] = Builder.CreateBitCast(Ops[0], 6106 llvm::VectorType::get(DoubleTy, 1)); 6107 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6108 "vget_lane"); 6109 case NEON::BI__builtin_neon_vgetq_lane_f32: 6110 case NEON::BI__builtin_neon_vdups_laneq_f32: 6111 Ops[0] = Builder.CreateBitCast(Ops[0], 6112 llvm::VectorType::get(FloatTy, 4)); 6113 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6114 "vgetq_lane"); 6115 case NEON::BI__builtin_neon_vgetq_lane_f64: 6116 case NEON::BI__builtin_neon_vdupd_laneq_f64: 6117 Ops[0] = Builder.CreateBitCast(Ops[0], 6118 llvm::VectorType::get(DoubleTy, 2)); 6119 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6120 "vgetq_lane"); 6121 case NEON::BI__builtin_neon_vaddd_s64: 6122 case NEON::BI__builtin_neon_vaddd_u64: 6123 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd"); 6124 case NEON::BI__builtin_neon_vsubd_s64: 6125 case NEON::BI__builtin_neon_vsubd_u64: 6126 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd"); 6127 case NEON::BI__builtin_neon_vqdmlalh_s16: 6128 case NEON::BI__builtin_neon_vqdmlslh_s16: { 6129 SmallVector<Value *, 2> ProductOps; 6130 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6131 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2)))); 6132 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6133 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6134 ProductOps, "vqdmlXl"); 6135 Constant *CI = ConstantInt::get(SizeTy, 0); 6136 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6137 6138 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16 6139 ? Intrinsic::aarch64_neon_sqadd 6140 : Intrinsic::aarch64_neon_sqsub; 6141 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl"); 6142 } 6143 case NEON::BI__builtin_neon_vqshlud_n_s64: { 6144 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6145 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6146 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty), 6147 Ops, "vqshlu_n"); 6148 } 6149 case NEON::BI__builtin_neon_vqshld_n_u64: 6150 case NEON::BI__builtin_neon_vqshld_n_s64: { 6151 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64 6152 ? Intrinsic::aarch64_neon_uqshl 6153 : Intrinsic::aarch64_neon_sqshl; 6154 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6155 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6156 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n"); 6157 } 6158 case NEON::BI__builtin_neon_vrshrd_n_u64: 6159 case NEON::BI__builtin_neon_vrshrd_n_s64: { 6160 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64 6161 ? Intrinsic::aarch64_neon_urshl 6162 : Intrinsic::aarch64_neon_srshl; 6163 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6164 int SV = cast<ConstantInt>(Ops[1])->getSExtValue(); 6165 Ops[1] = ConstantInt::get(Int64Ty, -SV); 6166 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n"); 6167 } 6168 case NEON::BI__builtin_neon_vrsrad_n_u64: 6169 case NEON::BI__builtin_neon_vrsrad_n_s64: { 6170 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64 6171 ? Intrinsic::aarch64_neon_urshl 6172 : Intrinsic::aarch64_neon_srshl; 6173 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6174 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2)))); 6175 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty), 6176 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)}); 6177 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty)); 6178 } 6179 case NEON::BI__builtin_neon_vshld_n_s64: 6180 case NEON::BI__builtin_neon_vshld_n_u64: { 6181 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6182 return Builder.CreateShl( 6183 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n"); 6184 } 6185 case NEON::BI__builtin_neon_vshrd_n_s64: { 6186 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6187 return Builder.CreateAShr( 6188 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6189 Amt->getZExtValue())), 6190 "shrd_n"); 6191 } 6192 case NEON::BI__builtin_neon_vshrd_n_u64: { 6193 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6194 uint64_t ShiftAmt = Amt->getZExtValue(); 6195 // Right-shifting an unsigned value by its size yields 0. 6196 if (ShiftAmt == 64) 6197 return ConstantInt::get(Int64Ty, 0); 6198 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt), 6199 "shrd_n"); 6200 } 6201 case NEON::BI__builtin_neon_vsrad_n_s64: { 6202 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6203 Ops[1] = Builder.CreateAShr( 6204 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6205 Amt->getZExtValue())), 6206 "shrd_n"); 6207 return Builder.CreateAdd(Ops[0], Ops[1]); 6208 } 6209 case NEON::BI__builtin_neon_vsrad_n_u64: { 6210 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6211 uint64_t ShiftAmt = Amt->getZExtValue(); 6212 // Right-shifting an unsigned value by its size yields 0. 6213 // As Op + 0 = Op, return Ops[0] directly. 6214 if (ShiftAmt == 64) 6215 return Ops[0]; 6216 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt), 6217 "shrd_n"); 6218 return Builder.CreateAdd(Ops[0], Ops[1]); 6219 } 6220 case NEON::BI__builtin_neon_vqdmlalh_lane_s16: 6221 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16: 6222 case NEON::BI__builtin_neon_vqdmlslh_lane_s16: 6223 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: { 6224 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6225 "lane"); 6226 SmallVector<Value *, 2> ProductOps; 6227 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6228 ProductOps.push_back(vectorWrapScalar16(Ops[2])); 6229 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6230 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6231 ProductOps, "vqdmlXl"); 6232 Constant *CI = ConstantInt::get(SizeTy, 0); 6233 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6234 Ops.pop_back(); 6235 6236 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 || 6237 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16) 6238 ? Intrinsic::aarch64_neon_sqadd 6239 : Intrinsic::aarch64_neon_sqsub; 6240 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl"); 6241 } 6242 case NEON::BI__builtin_neon_vqdmlals_s32: 6243 case NEON::BI__builtin_neon_vqdmlsls_s32: { 6244 SmallVector<Value *, 2> ProductOps; 6245 ProductOps.push_back(Ops[1]); 6246 ProductOps.push_back(EmitScalarExpr(E->getArg(2))); 6247 Ops[1] = 6248 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6249 ProductOps, "vqdmlXl"); 6250 6251 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32 6252 ? Intrinsic::aarch64_neon_sqadd 6253 : Intrinsic::aarch64_neon_sqsub; 6254 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl"); 6255 } 6256 case NEON::BI__builtin_neon_vqdmlals_lane_s32: 6257 case NEON::BI__builtin_neon_vqdmlals_laneq_s32: 6258 case NEON::BI__builtin_neon_vqdmlsls_lane_s32: 6259 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: { 6260 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6261 "lane"); 6262 SmallVector<Value *, 2> ProductOps; 6263 ProductOps.push_back(Ops[1]); 6264 ProductOps.push_back(Ops[2]); 6265 Ops[1] = 6266 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6267 ProductOps, "vqdmlXl"); 6268 Ops.pop_back(); 6269 6270 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 || 6271 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32) 6272 ? Intrinsic::aarch64_neon_sqadd 6273 : Intrinsic::aarch64_neon_sqsub; 6274 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl"); 6275 } 6276 } 6277 6278 llvm::VectorType *VTy = GetNeonType(this, Type); 6279 llvm::Type *Ty = VTy; 6280 if (!Ty) 6281 return nullptr; 6282 6283 // Not all intrinsics handled by the common case work for AArch64 yet, so only 6284 // defer to common code if it's been added to our special map. 6285 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID, 6286 AArch64SIMDIntrinsicsProvenSorted); 6287 6288 if (Builtin) 6289 return EmitCommonNeonBuiltinExpr( 6290 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 6291 Builtin->NameHint, Builtin->TypeModifier, E, Ops, 6292 /*never use addresses*/ Address::invalid(), Address::invalid()); 6293 6294 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops)) 6295 return V; 6296 6297 unsigned Int; 6298 switch (BuiltinID) { 6299 default: return nullptr; 6300 case NEON::BI__builtin_neon_vbsl_v: 6301 case NEON::BI__builtin_neon_vbslq_v: { 6302 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy); 6303 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl"); 6304 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl"); 6305 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl"); 6306 6307 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl"); 6308 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl"); 6309 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl"); 6310 return Builder.CreateBitCast(Ops[0], Ty); 6311 } 6312 case NEON::BI__builtin_neon_vfma_lane_v: 6313 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types 6314 // The ARM builtins (and instructions) have the addend as the first 6315 // operand, but the 'fma' intrinsics have it last. Swap it around here. 6316 Value *Addend = Ops[0]; 6317 Value *Multiplicand = Ops[1]; 6318 Value *LaneSource = Ops[2]; 6319 Ops[0] = Multiplicand; 6320 Ops[1] = LaneSource; 6321 Ops[2] = Addend; 6322 6323 // Now adjust things to handle the lane access. 6324 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ? 6325 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) : 6326 VTy; 6327 llvm::Constant *cst = cast<Constant>(Ops[3]); 6328 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst); 6329 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy); 6330 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane"); 6331 6332 Ops.pop_back(); 6333 Int = Intrinsic::fma; 6334 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla"); 6335 } 6336 case NEON::BI__builtin_neon_vfma_laneq_v: { 6337 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 6338 // v1f64 fma should be mapped to Neon scalar f64 fma 6339 if (VTy && VTy->getElementType() == DoubleTy) { 6340 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6341 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 6342 llvm::Type *VTy = GetNeonType(this, 6343 NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 6344 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 6345 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6346 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 6347 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6348 return Builder.CreateBitCast(Result, Ty); 6349 } 6350 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6351 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6352 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6353 6354 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 6355 VTy->getNumElements() * 2); 6356 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 6357 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 6358 cast<ConstantInt>(Ops[3])); 6359 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 6360 6361 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6362 } 6363 case NEON::BI__builtin_neon_vfmaq_laneq_v: { 6364 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6365 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6366 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6367 6368 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6369 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 6370 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6371 } 6372 case NEON::BI__builtin_neon_vfmas_lane_f32: 6373 case NEON::BI__builtin_neon_vfmas_laneq_f32: 6374 case NEON::BI__builtin_neon_vfmad_lane_f64: 6375 case NEON::BI__builtin_neon_vfmad_laneq_f64: { 6376 Ops.push_back(EmitScalarExpr(E->getArg(3))); 6377 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 6378 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6379 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6380 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6381 } 6382 case NEON::BI__builtin_neon_vmull_v: 6383 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6384 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull; 6385 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull; 6386 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 6387 case NEON::BI__builtin_neon_vmax_v: 6388 case NEON::BI__builtin_neon_vmaxq_v: 6389 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6390 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax; 6391 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax; 6392 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 6393 case NEON::BI__builtin_neon_vmin_v: 6394 case NEON::BI__builtin_neon_vminq_v: 6395 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6396 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin; 6397 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin; 6398 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 6399 case NEON::BI__builtin_neon_vabd_v: 6400 case NEON::BI__builtin_neon_vabdq_v: 6401 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6402 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd; 6403 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd; 6404 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 6405 case NEON::BI__builtin_neon_vpadal_v: 6406 case NEON::BI__builtin_neon_vpadalq_v: { 6407 unsigned ArgElts = VTy->getNumElements(); 6408 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType()); 6409 unsigned BitWidth = EltTy->getBitWidth(); 6410 llvm::Type *ArgTy = llvm::VectorType::get( 6411 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts); 6412 llvm::Type* Tys[2] = { VTy, ArgTy }; 6413 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp; 6414 SmallVector<llvm::Value*, 1> TmpOps; 6415 TmpOps.push_back(Ops[1]); 6416 Function *F = CGM.getIntrinsic(Int, Tys); 6417 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal"); 6418 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType()); 6419 return Builder.CreateAdd(tmp, addend); 6420 } 6421 case NEON::BI__builtin_neon_vpmin_v: 6422 case NEON::BI__builtin_neon_vpminq_v: 6423 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6424 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp; 6425 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp; 6426 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 6427 case NEON::BI__builtin_neon_vpmax_v: 6428 case NEON::BI__builtin_neon_vpmaxq_v: 6429 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6430 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp; 6431 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp; 6432 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 6433 case NEON::BI__builtin_neon_vminnm_v: 6434 case NEON::BI__builtin_neon_vminnmq_v: 6435 Int = Intrinsic::aarch64_neon_fminnm; 6436 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 6437 case NEON::BI__builtin_neon_vmaxnm_v: 6438 case NEON::BI__builtin_neon_vmaxnmq_v: 6439 Int = Intrinsic::aarch64_neon_fmaxnm; 6440 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 6441 case NEON::BI__builtin_neon_vrecpss_f32: { 6442 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6443 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy), 6444 Ops, "vrecps"); 6445 } 6446 case NEON::BI__builtin_neon_vrecpsd_f64: { 6447 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6448 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy), 6449 Ops, "vrecps"); 6450 } 6451 case NEON::BI__builtin_neon_vqshrun_n_v: 6452 Int = Intrinsic::aarch64_neon_sqshrun; 6453 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 6454 case NEON::BI__builtin_neon_vqrshrun_n_v: 6455 Int = Intrinsic::aarch64_neon_sqrshrun; 6456 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 6457 case NEON::BI__builtin_neon_vqshrn_n_v: 6458 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn; 6459 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 6460 case NEON::BI__builtin_neon_vrshrn_n_v: 6461 Int = Intrinsic::aarch64_neon_rshrn; 6462 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 6463 case NEON::BI__builtin_neon_vqrshrn_n_v: 6464 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn; 6465 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 6466 case NEON::BI__builtin_neon_vrnda_v: 6467 case NEON::BI__builtin_neon_vrndaq_v: { 6468 Int = Intrinsic::round; 6469 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); 6470 } 6471 case NEON::BI__builtin_neon_vrndi_v: 6472 case NEON::BI__builtin_neon_vrndiq_v: { 6473 Int = Intrinsic::nearbyint; 6474 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); 6475 } 6476 case NEON::BI__builtin_neon_vrndm_v: 6477 case NEON::BI__builtin_neon_vrndmq_v: { 6478 Int = Intrinsic::floor; 6479 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); 6480 } 6481 case NEON::BI__builtin_neon_vrndn_v: 6482 case NEON::BI__builtin_neon_vrndnq_v: { 6483 Int = Intrinsic::aarch64_neon_frintn; 6484 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); 6485 } 6486 case NEON::BI__builtin_neon_vrndp_v: 6487 case NEON::BI__builtin_neon_vrndpq_v: { 6488 Int = Intrinsic::ceil; 6489 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); 6490 } 6491 case NEON::BI__builtin_neon_vrndx_v: 6492 case NEON::BI__builtin_neon_vrndxq_v: { 6493 Int = Intrinsic::rint; 6494 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); 6495 } 6496 case NEON::BI__builtin_neon_vrnd_v: 6497 case NEON::BI__builtin_neon_vrndq_v: { 6498 Int = Intrinsic::trunc; 6499 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz"); 6500 } 6501 case NEON::BI__builtin_neon_vceqz_v: 6502 case NEON::BI__builtin_neon_vceqzq_v: 6503 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, 6504 ICmpInst::ICMP_EQ, "vceqz"); 6505 case NEON::BI__builtin_neon_vcgez_v: 6506 case NEON::BI__builtin_neon_vcgezq_v: 6507 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, 6508 ICmpInst::ICMP_SGE, "vcgez"); 6509 case NEON::BI__builtin_neon_vclez_v: 6510 case NEON::BI__builtin_neon_vclezq_v: 6511 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, 6512 ICmpInst::ICMP_SLE, "vclez"); 6513 case NEON::BI__builtin_neon_vcgtz_v: 6514 case NEON::BI__builtin_neon_vcgtzq_v: 6515 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, 6516 ICmpInst::ICMP_SGT, "vcgtz"); 6517 case NEON::BI__builtin_neon_vcltz_v: 6518 case NEON::BI__builtin_neon_vcltzq_v: 6519 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, 6520 ICmpInst::ICMP_SLT, "vcltz"); 6521 case NEON::BI__builtin_neon_vcvt_f64_v: 6522 case NEON::BI__builtin_neon_vcvtq_f64_v: 6523 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6524 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 6525 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 6526 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 6527 case NEON::BI__builtin_neon_vcvt_f64_f32: { 6528 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad && 6529 "unexpected vcvt_f64_f32 builtin"); 6530 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false); 6531 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6532 6533 return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); 6534 } 6535 case NEON::BI__builtin_neon_vcvt_f32_f64: { 6536 assert(Type.getEltType() == NeonTypeFlags::Float32 && 6537 "unexpected vcvt_f32_f64 builtin"); 6538 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); 6539 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6540 6541 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); 6542 } 6543 case NEON::BI__builtin_neon_vcvt_s32_v: 6544 case NEON::BI__builtin_neon_vcvt_u32_v: 6545 case NEON::BI__builtin_neon_vcvt_s64_v: 6546 case NEON::BI__builtin_neon_vcvt_u64_v: 6547 case NEON::BI__builtin_neon_vcvtq_s32_v: 6548 case NEON::BI__builtin_neon_vcvtq_u32_v: 6549 case NEON::BI__builtin_neon_vcvtq_s64_v: 6550 case NEON::BI__builtin_neon_vcvtq_u64_v: { 6551 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 6552 if (usgn) 6553 return Builder.CreateFPToUI(Ops[0], Ty); 6554 return Builder.CreateFPToSI(Ops[0], Ty); 6555 } 6556 case NEON::BI__builtin_neon_vcvta_s32_v: 6557 case NEON::BI__builtin_neon_vcvtaq_s32_v: 6558 case NEON::BI__builtin_neon_vcvta_u32_v: 6559 case NEON::BI__builtin_neon_vcvtaq_u32_v: 6560 case NEON::BI__builtin_neon_vcvta_s64_v: 6561 case NEON::BI__builtin_neon_vcvtaq_s64_v: 6562 case NEON::BI__builtin_neon_vcvta_u64_v: 6563 case NEON::BI__builtin_neon_vcvtaq_u64_v: { 6564 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas; 6565 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6566 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta"); 6567 } 6568 case NEON::BI__builtin_neon_vcvtm_s32_v: 6569 case NEON::BI__builtin_neon_vcvtmq_s32_v: 6570 case NEON::BI__builtin_neon_vcvtm_u32_v: 6571 case NEON::BI__builtin_neon_vcvtmq_u32_v: 6572 case NEON::BI__builtin_neon_vcvtm_s64_v: 6573 case NEON::BI__builtin_neon_vcvtmq_s64_v: 6574 case NEON::BI__builtin_neon_vcvtm_u64_v: 6575 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 6576 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms; 6577 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6578 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm"); 6579 } 6580 case NEON::BI__builtin_neon_vcvtn_s32_v: 6581 case NEON::BI__builtin_neon_vcvtnq_s32_v: 6582 case NEON::BI__builtin_neon_vcvtn_u32_v: 6583 case NEON::BI__builtin_neon_vcvtnq_u32_v: 6584 case NEON::BI__builtin_neon_vcvtn_s64_v: 6585 case NEON::BI__builtin_neon_vcvtnq_s64_v: 6586 case NEON::BI__builtin_neon_vcvtn_u64_v: 6587 case NEON::BI__builtin_neon_vcvtnq_u64_v: { 6588 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns; 6589 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6590 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn"); 6591 } 6592 case NEON::BI__builtin_neon_vcvtp_s32_v: 6593 case NEON::BI__builtin_neon_vcvtpq_s32_v: 6594 case NEON::BI__builtin_neon_vcvtp_u32_v: 6595 case NEON::BI__builtin_neon_vcvtpq_u32_v: 6596 case NEON::BI__builtin_neon_vcvtp_s64_v: 6597 case NEON::BI__builtin_neon_vcvtpq_s64_v: 6598 case NEON::BI__builtin_neon_vcvtp_u64_v: 6599 case NEON::BI__builtin_neon_vcvtpq_u64_v: { 6600 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps; 6601 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6602 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp"); 6603 } 6604 case NEON::BI__builtin_neon_vmulx_v: 6605 case NEON::BI__builtin_neon_vmulxq_v: { 6606 Int = Intrinsic::aarch64_neon_fmulx; 6607 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 6608 } 6609 case NEON::BI__builtin_neon_vmul_lane_v: 6610 case NEON::BI__builtin_neon_vmul_laneq_v: { 6611 // v1f64 vmul_lane should be mapped to Neon scalar mul lane 6612 bool Quad = false; 6613 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v) 6614 Quad = true; 6615 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6616 llvm::Type *VTy = GetNeonType(this, 6617 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); 6618 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 6619 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); 6620 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); 6621 return Builder.CreateBitCast(Result, Ty); 6622 } 6623 case NEON::BI__builtin_neon_vnegd_s64: 6624 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd"); 6625 case NEON::BI__builtin_neon_vpmaxnm_v: 6626 case NEON::BI__builtin_neon_vpmaxnmq_v: { 6627 Int = Intrinsic::aarch64_neon_fmaxnmp; 6628 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 6629 } 6630 case NEON::BI__builtin_neon_vpminnm_v: 6631 case NEON::BI__builtin_neon_vpminnmq_v: { 6632 Int = Intrinsic::aarch64_neon_fminnmp; 6633 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 6634 } 6635 case NEON::BI__builtin_neon_vsqrt_v: 6636 case NEON::BI__builtin_neon_vsqrtq_v: { 6637 Int = Intrinsic::sqrt; 6638 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6639 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); 6640 } 6641 case NEON::BI__builtin_neon_vrbit_v: 6642 case NEON::BI__builtin_neon_vrbitq_v: { 6643 Int = Intrinsic::aarch64_neon_rbit; 6644 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); 6645 } 6646 case NEON::BI__builtin_neon_vaddv_u8: 6647 // FIXME: These are handled by the AArch64 scalar code. 6648 usgn = true; 6649 // FALLTHROUGH 6650 case NEON::BI__builtin_neon_vaddv_s8: { 6651 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6652 Ty = Int32Ty; 6653 VTy = llvm::VectorType::get(Int8Ty, 8); 6654 llvm::Type *Tys[2] = { Ty, VTy }; 6655 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6656 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6657 return Builder.CreateTrunc(Ops[0], Int8Ty); 6658 } 6659 case NEON::BI__builtin_neon_vaddv_u16: 6660 usgn = true; 6661 // FALLTHROUGH 6662 case NEON::BI__builtin_neon_vaddv_s16: { 6663 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6664 Ty = Int32Ty; 6665 VTy = llvm::VectorType::get(Int16Ty, 4); 6666 llvm::Type *Tys[2] = { Ty, VTy }; 6667 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6668 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6669 return Builder.CreateTrunc(Ops[0], Int16Ty); 6670 } 6671 case NEON::BI__builtin_neon_vaddvq_u8: 6672 usgn = true; 6673 // FALLTHROUGH 6674 case NEON::BI__builtin_neon_vaddvq_s8: { 6675 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6676 Ty = Int32Ty; 6677 VTy = llvm::VectorType::get(Int8Ty, 16); 6678 llvm::Type *Tys[2] = { Ty, VTy }; 6679 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6680 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6681 return Builder.CreateTrunc(Ops[0], Int8Ty); 6682 } 6683 case NEON::BI__builtin_neon_vaddvq_u16: 6684 usgn = true; 6685 // FALLTHROUGH 6686 case NEON::BI__builtin_neon_vaddvq_s16: { 6687 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6688 Ty = Int32Ty; 6689 VTy = llvm::VectorType::get(Int16Ty, 8); 6690 llvm::Type *Tys[2] = { Ty, VTy }; 6691 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6692 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6693 return Builder.CreateTrunc(Ops[0], Int16Ty); 6694 } 6695 case NEON::BI__builtin_neon_vmaxv_u8: { 6696 Int = Intrinsic::aarch64_neon_umaxv; 6697 Ty = Int32Ty; 6698 VTy = llvm::VectorType::get(Int8Ty, 8); 6699 llvm::Type *Tys[2] = { Ty, VTy }; 6700 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6701 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6702 return Builder.CreateTrunc(Ops[0], Int8Ty); 6703 } 6704 case NEON::BI__builtin_neon_vmaxv_u16: { 6705 Int = Intrinsic::aarch64_neon_umaxv; 6706 Ty = Int32Ty; 6707 VTy = llvm::VectorType::get(Int16Ty, 4); 6708 llvm::Type *Tys[2] = { Ty, VTy }; 6709 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6710 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6711 return Builder.CreateTrunc(Ops[0], Int16Ty); 6712 } 6713 case NEON::BI__builtin_neon_vmaxvq_u8: { 6714 Int = Intrinsic::aarch64_neon_umaxv; 6715 Ty = Int32Ty; 6716 VTy = llvm::VectorType::get(Int8Ty, 16); 6717 llvm::Type *Tys[2] = { Ty, VTy }; 6718 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6719 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6720 return Builder.CreateTrunc(Ops[0], Int8Ty); 6721 } 6722 case NEON::BI__builtin_neon_vmaxvq_u16: { 6723 Int = Intrinsic::aarch64_neon_umaxv; 6724 Ty = Int32Ty; 6725 VTy = llvm::VectorType::get(Int16Ty, 8); 6726 llvm::Type *Tys[2] = { Ty, VTy }; 6727 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6728 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6729 return Builder.CreateTrunc(Ops[0], Int16Ty); 6730 } 6731 case NEON::BI__builtin_neon_vmaxv_s8: { 6732 Int = Intrinsic::aarch64_neon_smaxv; 6733 Ty = Int32Ty; 6734 VTy = llvm::VectorType::get(Int8Ty, 8); 6735 llvm::Type *Tys[2] = { Ty, VTy }; 6736 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6737 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6738 return Builder.CreateTrunc(Ops[0], Int8Ty); 6739 } 6740 case NEON::BI__builtin_neon_vmaxv_s16: { 6741 Int = Intrinsic::aarch64_neon_smaxv; 6742 Ty = Int32Ty; 6743 VTy = llvm::VectorType::get(Int16Ty, 4); 6744 llvm::Type *Tys[2] = { Ty, VTy }; 6745 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6746 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6747 return Builder.CreateTrunc(Ops[0], Int16Ty); 6748 } 6749 case NEON::BI__builtin_neon_vmaxvq_s8: { 6750 Int = Intrinsic::aarch64_neon_smaxv; 6751 Ty = Int32Ty; 6752 VTy = llvm::VectorType::get(Int8Ty, 16); 6753 llvm::Type *Tys[2] = { Ty, VTy }; 6754 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6755 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6756 return Builder.CreateTrunc(Ops[0], Int8Ty); 6757 } 6758 case NEON::BI__builtin_neon_vmaxvq_s16: { 6759 Int = Intrinsic::aarch64_neon_smaxv; 6760 Ty = Int32Ty; 6761 VTy = llvm::VectorType::get(Int16Ty, 8); 6762 llvm::Type *Tys[2] = { Ty, VTy }; 6763 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6764 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6765 return Builder.CreateTrunc(Ops[0], Int16Ty); 6766 } 6767 case NEON::BI__builtin_neon_vminv_u8: { 6768 Int = Intrinsic::aarch64_neon_uminv; 6769 Ty = Int32Ty; 6770 VTy = llvm::VectorType::get(Int8Ty, 8); 6771 llvm::Type *Tys[2] = { Ty, VTy }; 6772 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6773 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6774 return Builder.CreateTrunc(Ops[0], Int8Ty); 6775 } 6776 case NEON::BI__builtin_neon_vminv_u16: { 6777 Int = Intrinsic::aarch64_neon_uminv; 6778 Ty = Int32Ty; 6779 VTy = llvm::VectorType::get(Int16Ty, 4); 6780 llvm::Type *Tys[2] = { Ty, VTy }; 6781 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6782 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6783 return Builder.CreateTrunc(Ops[0], Int16Ty); 6784 } 6785 case NEON::BI__builtin_neon_vminvq_u8: { 6786 Int = Intrinsic::aarch64_neon_uminv; 6787 Ty = Int32Ty; 6788 VTy = llvm::VectorType::get(Int8Ty, 16); 6789 llvm::Type *Tys[2] = { Ty, VTy }; 6790 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6791 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6792 return Builder.CreateTrunc(Ops[0], Int8Ty); 6793 } 6794 case NEON::BI__builtin_neon_vminvq_u16: { 6795 Int = Intrinsic::aarch64_neon_uminv; 6796 Ty = Int32Ty; 6797 VTy = llvm::VectorType::get(Int16Ty, 8); 6798 llvm::Type *Tys[2] = { Ty, VTy }; 6799 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6800 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6801 return Builder.CreateTrunc(Ops[0], Int16Ty); 6802 } 6803 case NEON::BI__builtin_neon_vminv_s8: { 6804 Int = Intrinsic::aarch64_neon_sminv; 6805 Ty = Int32Ty; 6806 VTy = llvm::VectorType::get(Int8Ty, 8); 6807 llvm::Type *Tys[2] = { Ty, VTy }; 6808 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6809 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6810 return Builder.CreateTrunc(Ops[0], Int8Ty); 6811 } 6812 case NEON::BI__builtin_neon_vminv_s16: { 6813 Int = Intrinsic::aarch64_neon_sminv; 6814 Ty = Int32Ty; 6815 VTy = llvm::VectorType::get(Int16Ty, 4); 6816 llvm::Type *Tys[2] = { Ty, VTy }; 6817 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6818 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6819 return Builder.CreateTrunc(Ops[0], Int16Ty); 6820 } 6821 case NEON::BI__builtin_neon_vminvq_s8: { 6822 Int = Intrinsic::aarch64_neon_sminv; 6823 Ty = Int32Ty; 6824 VTy = llvm::VectorType::get(Int8Ty, 16); 6825 llvm::Type *Tys[2] = { Ty, VTy }; 6826 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6827 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6828 return Builder.CreateTrunc(Ops[0], Int8Ty); 6829 } 6830 case NEON::BI__builtin_neon_vminvq_s16: { 6831 Int = Intrinsic::aarch64_neon_sminv; 6832 Ty = Int32Ty; 6833 VTy = llvm::VectorType::get(Int16Ty, 8); 6834 llvm::Type *Tys[2] = { Ty, VTy }; 6835 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6836 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6837 return Builder.CreateTrunc(Ops[0], Int16Ty); 6838 } 6839 case NEON::BI__builtin_neon_vmul_n_f64: { 6840 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6841 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy); 6842 return Builder.CreateFMul(Ops[0], RHS); 6843 } 6844 case NEON::BI__builtin_neon_vaddlv_u8: { 6845 Int = Intrinsic::aarch64_neon_uaddlv; 6846 Ty = Int32Ty; 6847 VTy = llvm::VectorType::get(Int8Ty, 8); 6848 llvm::Type *Tys[2] = { Ty, VTy }; 6849 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6850 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6851 return Builder.CreateTrunc(Ops[0], Int16Ty); 6852 } 6853 case NEON::BI__builtin_neon_vaddlv_u16: { 6854 Int = Intrinsic::aarch64_neon_uaddlv; 6855 Ty = Int32Ty; 6856 VTy = llvm::VectorType::get(Int16Ty, 4); 6857 llvm::Type *Tys[2] = { Ty, VTy }; 6858 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6859 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6860 } 6861 case NEON::BI__builtin_neon_vaddlvq_u8: { 6862 Int = Intrinsic::aarch64_neon_uaddlv; 6863 Ty = Int32Ty; 6864 VTy = llvm::VectorType::get(Int8Ty, 16); 6865 llvm::Type *Tys[2] = { Ty, VTy }; 6866 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6867 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6868 return Builder.CreateTrunc(Ops[0], Int16Ty); 6869 } 6870 case NEON::BI__builtin_neon_vaddlvq_u16: { 6871 Int = Intrinsic::aarch64_neon_uaddlv; 6872 Ty = Int32Ty; 6873 VTy = llvm::VectorType::get(Int16Ty, 8); 6874 llvm::Type *Tys[2] = { Ty, VTy }; 6875 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6876 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6877 } 6878 case NEON::BI__builtin_neon_vaddlv_s8: { 6879 Int = Intrinsic::aarch64_neon_saddlv; 6880 Ty = Int32Ty; 6881 VTy = llvm::VectorType::get(Int8Ty, 8); 6882 llvm::Type *Tys[2] = { Ty, VTy }; 6883 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6884 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6885 return Builder.CreateTrunc(Ops[0], Int16Ty); 6886 } 6887 case NEON::BI__builtin_neon_vaddlv_s16: { 6888 Int = Intrinsic::aarch64_neon_saddlv; 6889 Ty = Int32Ty; 6890 VTy = llvm::VectorType::get(Int16Ty, 4); 6891 llvm::Type *Tys[2] = { Ty, VTy }; 6892 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6893 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6894 } 6895 case NEON::BI__builtin_neon_vaddlvq_s8: { 6896 Int = Intrinsic::aarch64_neon_saddlv; 6897 Ty = Int32Ty; 6898 VTy = llvm::VectorType::get(Int8Ty, 16); 6899 llvm::Type *Tys[2] = { Ty, VTy }; 6900 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6901 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6902 return Builder.CreateTrunc(Ops[0], Int16Ty); 6903 } 6904 case NEON::BI__builtin_neon_vaddlvq_s16: { 6905 Int = Intrinsic::aarch64_neon_saddlv; 6906 Ty = Int32Ty; 6907 VTy = llvm::VectorType::get(Int16Ty, 8); 6908 llvm::Type *Tys[2] = { Ty, VTy }; 6909 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6910 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6911 } 6912 case NEON::BI__builtin_neon_vsri_n_v: 6913 case NEON::BI__builtin_neon_vsriq_n_v: { 6914 Int = Intrinsic::aarch64_neon_vsri; 6915 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6916 return EmitNeonCall(Intrin, Ops, "vsri_n"); 6917 } 6918 case NEON::BI__builtin_neon_vsli_n_v: 6919 case NEON::BI__builtin_neon_vsliq_n_v: { 6920 Int = Intrinsic::aarch64_neon_vsli; 6921 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6922 return EmitNeonCall(Intrin, Ops, "vsli_n"); 6923 } 6924 case NEON::BI__builtin_neon_vsra_n_v: 6925 case NEON::BI__builtin_neon_vsraq_n_v: 6926 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6927 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 6928 return Builder.CreateAdd(Ops[0], Ops[1]); 6929 case NEON::BI__builtin_neon_vrsra_n_v: 6930 case NEON::BI__builtin_neon_vrsraq_n_v: { 6931 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl; 6932 SmallVector<llvm::Value*,2> TmpOps; 6933 TmpOps.push_back(Ops[1]); 6934 TmpOps.push_back(Ops[2]); 6935 Function* F = CGM.getIntrinsic(Int, Ty); 6936 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true); 6937 Ops[0] = Builder.CreateBitCast(Ops[0], VTy); 6938 return Builder.CreateAdd(Ops[0], tmp); 6939 } 6940 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence 6941 // of an Align parameter here. 6942 case NEON::BI__builtin_neon_vld1_x2_v: 6943 case NEON::BI__builtin_neon_vld1q_x2_v: 6944 case NEON::BI__builtin_neon_vld1_x3_v: 6945 case NEON::BI__builtin_neon_vld1q_x3_v: 6946 case NEON::BI__builtin_neon_vld1_x4_v: 6947 case NEON::BI__builtin_neon_vld1q_x4_v: { 6948 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6949 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6950 llvm::Type *Tys[2] = { VTy, PTy }; 6951 unsigned Int; 6952 switch (BuiltinID) { 6953 case NEON::BI__builtin_neon_vld1_x2_v: 6954 case NEON::BI__builtin_neon_vld1q_x2_v: 6955 Int = Intrinsic::aarch64_neon_ld1x2; 6956 break; 6957 case NEON::BI__builtin_neon_vld1_x3_v: 6958 case NEON::BI__builtin_neon_vld1q_x3_v: 6959 Int = Intrinsic::aarch64_neon_ld1x3; 6960 break; 6961 case NEON::BI__builtin_neon_vld1_x4_v: 6962 case NEON::BI__builtin_neon_vld1q_x4_v: 6963 Int = Intrinsic::aarch64_neon_ld1x4; 6964 break; 6965 } 6966 Function *F = CGM.getIntrinsic(Int, Tys); 6967 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN"); 6968 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6969 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6970 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6971 } 6972 case NEON::BI__builtin_neon_vst1_x2_v: 6973 case NEON::BI__builtin_neon_vst1q_x2_v: 6974 case NEON::BI__builtin_neon_vst1_x3_v: 6975 case NEON::BI__builtin_neon_vst1q_x3_v: 6976 case NEON::BI__builtin_neon_vst1_x4_v: 6977 case NEON::BI__builtin_neon_vst1q_x4_v: { 6978 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6979 llvm::Type *Tys[2] = { VTy, PTy }; 6980 unsigned Int; 6981 switch (BuiltinID) { 6982 case NEON::BI__builtin_neon_vst1_x2_v: 6983 case NEON::BI__builtin_neon_vst1q_x2_v: 6984 Int = Intrinsic::aarch64_neon_st1x2; 6985 break; 6986 case NEON::BI__builtin_neon_vst1_x3_v: 6987 case NEON::BI__builtin_neon_vst1q_x3_v: 6988 Int = Intrinsic::aarch64_neon_st1x3; 6989 break; 6990 case NEON::BI__builtin_neon_vst1_x4_v: 6991 case NEON::BI__builtin_neon_vst1q_x4_v: 6992 Int = Intrinsic::aarch64_neon_st1x4; 6993 break; 6994 } 6995 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end()); 6996 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 6997 } 6998 case NEON::BI__builtin_neon_vld1_v: 6999 case NEON::BI__builtin_neon_vld1q_v: { 7000 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 7001 auto Alignment = CharUnits::fromQuantity( 7002 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16); 7003 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment); 7004 } 7005 case NEON::BI__builtin_neon_vst1_v: 7006 case NEON::BI__builtin_neon_vst1q_v: 7007 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 7008 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 7009 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7010 case NEON::BI__builtin_neon_vld1_lane_v: 7011 case NEON::BI__builtin_neon_vld1q_lane_v: { 7012 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7013 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7014 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7015 auto Alignment = CharUnits::fromQuantity( 7016 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16); 7017 Ops[0] = 7018 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7019 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane"); 7020 } 7021 case NEON::BI__builtin_neon_vld1_dup_v: 7022 case NEON::BI__builtin_neon_vld1q_dup_v: { 7023 Value *V = UndefValue::get(Ty); 7024 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7025 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7026 auto Alignment = CharUnits::fromQuantity( 7027 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16); 7028 Ops[0] = 7029 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7030 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 7031 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI); 7032 return EmitNeonSplat(Ops[0], CI); 7033 } 7034 case NEON::BI__builtin_neon_vst1_lane_v: 7035 case NEON::BI__builtin_neon_vst1q_lane_v: 7036 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7037 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 7038 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7039 return Builder.CreateDefaultAlignedStore(Ops[1], 7040 Builder.CreateBitCast(Ops[0], Ty)); 7041 case NEON::BI__builtin_neon_vld2_v: 7042 case NEON::BI__builtin_neon_vld2q_v: { 7043 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7044 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7045 llvm::Type *Tys[2] = { VTy, PTy }; 7046 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys); 7047 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7048 Ops[0] = Builder.CreateBitCast(Ops[0], 7049 llvm::PointerType::getUnqual(Ops[1]->getType())); 7050 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7051 } 7052 case NEON::BI__builtin_neon_vld3_v: 7053 case NEON::BI__builtin_neon_vld3q_v: { 7054 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7055 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7056 llvm::Type *Tys[2] = { VTy, PTy }; 7057 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys); 7058 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7059 Ops[0] = Builder.CreateBitCast(Ops[0], 7060 llvm::PointerType::getUnqual(Ops[1]->getType())); 7061 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7062 } 7063 case NEON::BI__builtin_neon_vld4_v: 7064 case NEON::BI__builtin_neon_vld4q_v: { 7065 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7066 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7067 llvm::Type *Tys[2] = { VTy, PTy }; 7068 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys); 7069 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7070 Ops[0] = Builder.CreateBitCast(Ops[0], 7071 llvm::PointerType::getUnqual(Ops[1]->getType())); 7072 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7073 } 7074 case NEON::BI__builtin_neon_vld2_dup_v: 7075 case NEON::BI__builtin_neon_vld2q_dup_v: { 7076 llvm::Type *PTy = 7077 llvm::PointerType::getUnqual(VTy->getElementType()); 7078 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7079 llvm::Type *Tys[2] = { VTy, PTy }; 7080 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys); 7081 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7082 Ops[0] = Builder.CreateBitCast(Ops[0], 7083 llvm::PointerType::getUnqual(Ops[1]->getType())); 7084 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7085 } 7086 case NEON::BI__builtin_neon_vld3_dup_v: 7087 case NEON::BI__builtin_neon_vld3q_dup_v: { 7088 llvm::Type *PTy = 7089 llvm::PointerType::getUnqual(VTy->getElementType()); 7090 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7091 llvm::Type *Tys[2] = { VTy, PTy }; 7092 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys); 7093 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7094 Ops[0] = Builder.CreateBitCast(Ops[0], 7095 llvm::PointerType::getUnqual(Ops[1]->getType())); 7096 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7097 } 7098 case NEON::BI__builtin_neon_vld4_dup_v: 7099 case NEON::BI__builtin_neon_vld4q_dup_v: { 7100 llvm::Type *PTy = 7101 llvm::PointerType::getUnqual(VTy->getElementType()); 7102 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7103 llvm::Type *Tys[2] = { VTy, PTy }; 7104 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys); 7105 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7106 Ops[0] = Builder.CreateBitCast(Ops[0], 7107 llvm::PointerType::getUnqual(Ops[1]->getType())); 7108 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7109 } 7110 case NEON::BI__builtin_neon_vld2_lane_v: 7111 case NEON::BI__builtin_neon_vld2q_lane_v: { 7112 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7113 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys); 7114 Ops.push_back(Ops[1]); 7115 Ops.erase(Ops.begin()+1); 7116 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7117 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7118 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7119 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 7120 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7121 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7122 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7123 } 7124 case NEON::BI__builtin_neon_vld3_lane_v: 7125 case NEON::BI__builtin_neon_vld3q_lane_v: { 7126 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7127 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys); 7128 Ops.push_back(Ops[1]); 7129 Ops.erase(Ops.begin()+1); 7130 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7131 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7132 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7133 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7134 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 7135 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7136 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7137 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7138 } 7139 case NEON::BI__builtin_neon_vld4_lane_v: 7140 case NEON::BI__builtin_neon_vld4q_lane_v: { 7141 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7142 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys); 7143 Ops.push_back(Ops[1]); 7144 Ops.erase(Ops.begin()+1); 7145 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7146 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7147 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7148 Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 7149 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty); 7150 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane"); 7151 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7152 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7153 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7154 } 7155 case NEON::BI__builtin_neon_vst2_v: 7156 case NEON::BI__builtin_neon_vst2q_v: { 7157 Ops.push_back(Ops[0]); 7158 Ops.erase(Ops.begin()); 7159 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() }; 7160 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys), 7161 Ops, ""); 7162 } 7163 case NEON::BI__builtin_neon_vst2_lane_v: 7164 case NEON::BI__builtin_neon_vst2q_lane_v: { 7165 Ops.push_back(Ops[0]); 7166 Ops.erase(Ops.begin()); 7167 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty); 7168 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7169 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys), 7170 Ops, ""); 7171 } 7172 case NEON::BI__builtin_neon_vst3_v: 7173 case NEON::BI__builtin_neon_vst3q_v: { 7174 Ops.push_back(Ops[0]); 7175 Ops.erase(Ops.begin()); 7176 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7177 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys), 7178 Ops, ""); 7179 } 7180 case NEON::BI__builtin_neon_vst3_lane_v: 7181 case NEON::BI__builtin_neon_vst3q_lane_v: { 7182 Ops.push_back(Ops[0]); 7183 Ops.erase(Ops.begin()); 7184 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7185 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7186 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys), 7187 Ops, ""); 7188 } 7189 case NEON::BI__builtin_neon_vst4_v: 7190 case NEON::BI__builtin_neon_vst4q_v: { 7191 Ops.push_back(Ops[0]); 7192 Ops.erase(Ops.begin()); 7193 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7194 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys), 7195 Ops, ""); 7196 } 7197 case NEON::BI__builtin_neon_vst4_lane_v: 7198 case NEON::BI__builtin_neon_vst4q_lane_v: { 7199 Ops.push_back(Ops[0]); 7200 Ops.erase(Ops.begin()); 7201 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7202 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() }; 7203 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys), 7204 Ops, ""); 7205 } 7206 case NEON::BI__builtin_neon_vtrn_v: 7207 case NEON::BI__builtin_neon_vtrnq_v: { 7208 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7209 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7210 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7211 Value *SV = nullptr; 7212 7213 for (unsigned vi = 0; vi != 2; ++vi) { 7214 SmallVector<uint32_t, 16> Indices; 7215 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7216 Indices.push_back(i+vi); 7217 Indices.push_back(i+e+vi); 7218 } 7219 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7220 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 7221 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7222 } 7223 return SV; 7224 } 7225 case NEON::BI__builtin_neon_vuzp_v: 7226 case NEON::BI__builtin_neon_vuzpq_v: { 7227 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7228 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7229 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7230 Value *SV = nullptr; 7231 7232 for (unsigned vi = 0; vi != 2; ++vi) { 7233 SmallVector<uint32_t, 16> Indices; 7234 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 7235 Indices.push_back(2*i+vi); 7236 7237 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7238 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 7239 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7240 } 7241 return SV; 7242 } 7243 case NEON::BI__builtin_neon_vzip_v: 7244 case NEON::BI__builtin_neon_vzipq_v: { 7245 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7246 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7247 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7248 Value *SV = nullptr; 7249 7250 for (unsigned vi = 0; vi != 2; ++vi) { 7251 SmallVector<uint32_t, 16> Indices; 7252 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7253 Indices.push_back((i + vi*e) >> 1); 7254 Indices.push_back(((i + vi*e) >> 1)+e); 7255 } 7256 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7257 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 7258 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7259 } 7260 return SV; 7261 } 7262 case NEON::BI__builtin_neon_vqtbl1q_v: { 7263 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty), 7264 Ops, "vtbl1"); 7265 } 7266 case NEON::BI__builtin_neon_vqtbl2q_v: { 7267 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty), 7268 Ops, "vtbl2"); 7269 } 7270 case NEON::BI__builtin_neon_vqtbl3q_v: { 7271 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty), 7272 Ops, "vtbl3"); 7273 } 7274 case NEON::BI__builtin_neon_vqtbl4q_v: { 7275 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty), 7276 Ops, "vtbl4"); 7277 } 7278 case NEON::BI__builtin_neon_vqtbx1q_v: { 7279 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty), 7280 Ops, "vtbx1"); 7281 } 7282 case NEON::BI__builtin_neon_vqtbx2q_v: { 7283 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty), 7284 Ops, "vtbx2"); 7285 } 7286 case NEON::BI__builtin_neon_vqtbx3q_v: { 7287 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty), 7288 Ops, "vtbx3"); 7289 } 7290 case NEON::BI__builtin_neon_vqtbx4q_v: { 7291 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty), 7292 Ops, "vtbx4"); 7293 } 7294 case NEON::BI__builtin_neon_vsqadd_v: 7295 case NEON::BI__builtin_neon_vsqaddq_v: { 7296 Int = Intrinsic::aarch64_neon_usqadd; 7297 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); 7298 } 7299 case NEON::BI__builtin_neon_vuqadd_v: 7300 case NEON::BI__builtin_neon_vuqaddq_v: { 7301 Int = Intrinsic::aarch64_neon_suqadd; 7302 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); 7303 } 7304 } 7305 } 7306 7307 llvm::Value *CodeGenFunction:: 7308 BuildVector(ArrayRef<llvm::Value*> Ops) { 7309 assert((Ops.size() & (Ops.size() - 1)) == 0 && 7310 "Not a power-of-two sized vector!"); 7311 bool AllConstants = true; 7312 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 7313 AllConstants &= isa<Constant>(Ops[i]); 7314 7315 // If this is a constant vector, create a ConstantVector. 7316 if (AllConstants) { 7317 SmallVector<llvm::Constant*, 16> CstOps; 7318 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7319 CstOps.push_back(cast<Constant>(Ops[i])); 7320 return llvm::ConstantVector::get(CstOps); 7321 } 7322 7323 // Otherwise, insertelement the values to build the vector. 7324 Value *Result = 7325 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 7326 7327 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7328 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 7329 7330 return Result; 7331 } 7332 7333 // Convert the mask from an integer type to a vector of i1. 7334 static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask, 7335 unsigned NumElts) { 7336 7337 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(), 7338 cast<IntegerType>(Mask->getType())->getBitWidth()); 7339 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy); 7340 7341 // If we have less than 8 elements, then the starting mask was an i8 and 7342 // we need to extract down to the right number of elements. 7343 if (NumElts < 8) { 7344 uint32_t Indices[4]; 7345 for (unsigned i = 0; i != NumElts; ++i) 7346 Indices[i] = i; 7347 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec, 7348 makeArrayRef(Indices, NumElts), 7349 "extract"); 7350 } 7351 return MaskVec; 7352 } 7353 7354 static Value *EmitX86MaskedStore(CodeGenFunction &CGF, 7355 SmallVectorImpl<Value *> &Ops, 7356 unsigned Align) { 7357 // Cast the pointer to right type. 7358 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7359 llvm::PointerType::getUnqual(Ops[1]->getType())); 7360 7361 // If the mask is all ones just emit a regular store. 7362 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7363 if (C->isAllOnesValue()) 7364 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align); 7365 7366 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7367 Ops[1]->getType()->getVectorNumElements()); 7368 7369 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec); 7370 } 7371 7372 static Value *EmitX86MaskedLoad(CodeGenFunction &CGF, 7373 SmallVectorImpl<Value *> &Ops, unsigned Align) { 7374 // Cast the pointer to right type. 7375 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7376 llvm::PointerType::getUnqual(Ops[1]->getType())); 7377 7378 // If the mask is all ones just emit a regular store. 7379 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7380 if (C->isAllOnesValue()) 7381 return CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7382 7383 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7384 Ops[1]->getType()->getVectorNumElements()); 7385 7386 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]); 7387 } 7388 7389 static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF, 7390 SmallVectorImpl<Value *> &Ops, 7391 llvm::Type *DstTy, 7392 unsigned SrcSizeInBits, 7393 unsigned Align) { 7394 // Load the subvector. 7395 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7396 7397 // Create broadcast mask. 7398 unsigned NumDstElts = DstTy->getVectorNumElements(); 7399 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits(); 7400 7401 SmallVector<uint32_t, 8> Mask; 7402 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts) 7403 for (unsigned j = 0; j != NumSrcElts; ++j) 7404 Mask.push_back(j); 7405 7406 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst"); 7407 } 7408 7409 static Value *EmitX86Select(CodeGenFunction &CGF, 7410 Value *Mask, Value *Op0, Value *Op1) { 7411 7412 // If the mask is all ones just return first argument. 7413 if (const auto *C = dyn_cast<Constant>(Mask)) 7414 if (C->isAllOnesValue()) 7415 return Op0; 7416 7417 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements()); 7418 7419 return CGF.Builder.CreateSelect(Mask, Op0, Op1); 7420 } 7421 7422 static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC, 7423 bool Signed, SmallVectorImpl<Value *> &Ops) { 7424 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 7425 Value *Cmp; 7426 7427 if (CC == 3) { 7428 Cmp = Constant::getNullValue( 7429 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7430 } else if (CC == 7) { 7431 Cmp = Constant::getAllOnesValue( 7432 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7433 } else { 7434 ICmpInst::Predicate Pred; 7435 switch (CC) { 7436 default: llvm_unreachable("Unknown condition code"); 7437 case 0: Pred = ICmpInst::ICMP_EQ; break; 7438 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; 7439 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; 7440 case 4: Pred = ICmpInst::ICMP_NE; break; 7441 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; 7442 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; 7443 } 7444 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7445 } 7446 7447 const auto *C = dyn_cast<Constant>(Ops.back()); 7448 if (!C || !C->isAllOnesValue()) 7449 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts)); 7450 7451 if (NumElts < 8) { 7452 uint32_t Indices[8]; 7453 for (unsigned i = 0; i != NumElts; ++i) 7454 Indices[i] = i; 7455 for (unsigned i = NumElts; i != 8; ++i) 7456 Indices[i] = i % NumElts + NumElts; 7457 Cmp = CGF.Builder.CreateShuffleVector( 7458 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices); 7459 } 7460 return CGF.Builder.CreateBitCast(Cmp, 7461 IntegerType::get(CGF.getLLVMContext(), 7462 std::max(NumElts, 8U))); 7463 } 7464 7465 static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef<Value *> Ops) { 7466 7467 llvm::Type *Ty = Ops[0]->getType(); 7468 Value *Zero = llvm::Constant::getNullValue(Ty); 7469 Value *Sub = CGF.Builder.CreateSub(Zero, Ops[0]); 7470 Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Zero); 7471 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Sub); 7472 if (Ops.size() == 1) 7473 return Res; 7474 return EmitX86Select(CGF, Ops[2], Res, Ops[1]); 7475 } 7476 7477 static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred, 7478 ArrayRef<Value *> Ops) { 7479 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7480 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]); 7481 7482 if (Ops.size() == 2) 7483 return Res; 7484 7485 assert(Ops.size() == 4); 7486 return EmitX86Select(CGF, Ops[3], Res, Ops[2]); 7487 } 7488 7489 static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, 7490 llvm::Type *DstTy) { 7491 unsigned NumberOfElements = DstTy->getVectorNumElements(); 7492 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements); 7493 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); 7494 } 7495 7496 Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { 7497 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); 7498 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString(); 7499 return EmitX86CpuIs(CPUStr); 7500 } 7501 7502 Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { 7503 7504 // This enum contains the vendor, type, and subtype enums from the 7505 // runtime library concatenated together. The _START labels mark 7506 // the start and are used to adjust the value into the correct 7507 // encoding space. 7508 enum X86CPUs { 7509 INTEL = 1, 7510 AMD, 7511 CPU_TYPE_START, 7512 INTEL_BONNELL, 7513 INTEL_CORE2, 7514 INTEL_COREI7, 7515 AMDFAM10H, 7516 AMDFAM15H, 7517 INTEL_SILVERMONT, 7518 INTEL_KNL, 7519 AMD_BTVER1, 7520 AMD_BTVER2, 7521 AMDFAM17H, 7522 CPU_SUBTYPE_START, 7523 INTEL_COREI7_NEHALEM, 7524 INTEL_COREI7_WESTMERE, 7525 INTEL_COREI7_SANDYBRIDGE, 7526 AMDFAM10H_BARCELONA, 7527 AMDFAM10H_SHANGHAI, 7528 AMDFAM10H_ISTANBUL, 7529 AMDFAM15H_BDVER1, 7530 AMDFAM15H_BDVER2, 7531 AMDFAM15H_BDVER3, 7532 AMDFAM15H_BDVER4, 7533 AMDFAM17H_ZNVER1, 7534 INTEL_COREI7_IVYBRIDGE, 7535 INTEL_COREI7_HASWELL, 7536 INTEL_COREI7_BROADWELL, 7537 INTEL_COREI7_SKYLAKE, 7538 INTEL_COREI7_SKYLAKE_AVX512, 7539 }; 7540 7541 X86CPUs CPU = 7542 StringSwitch<X86CPUs>(CPUStr) 7543 .Case("amd", AMD) 7544 .Case("amdfam10h", AMDFAM10H) 7545 .Case("amdfam10", AMDFAM10H) 7546 .Case("amdfam15h", AMDFAM15H) 7547 .Case("amdfam15", AMDFAM15H) 7548 .Case("amdfam17h", AMDFAM17H) 7549 .Case("atom", INTEL_BONNELL) 7550 .Case("barcelona", AMDFAM10H_BARCELONA) 7551 .Case("bdver1", AMDFAM15H_BDVER1) 7552 .Case("bdver2", AMDFAM15H_BDVER2) 7553 .Case("bdver3", AMDFAM15H_BDVER3) 7554 .Case("bdver4", AMDFAM15H_BDVER4) 7555 .Case("bonnell", INTEL_BONNELL) 7556 .Case("broadwell", INTEL_COREI7_BROADWELL) 7557 .Case("btver1", AMD_BTVER1) 7558 .Case("btver2", AMD_BTVER2) 7559 .Case("core2", INTEL_CORE2) 7560 .Case("corei7", INTEL_COREI7) 7561 .Case("haswell", INTEL_COREI7_HASWELL) 7562 .Case("intel", INTEL) 7563 .Case("istanbul", AMDFAM10H_ISTANBUL) 7564 .Case("ivybridge", INTEL_COREI7_IVYBRIDGE) 7565 .Case("knl", INTEL_KNL) 7566 .Case("nehalem", INTEL_COREI7_NEHALEM) 7567 .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE) 7568 .Case("shanghai", AMDFAM10H_SHANGHAI) 7569 .Case("silvermont", INTEL_SILVERMONT) 7570 .Case("skylake", INTEL_COREI7_SKYLAKE) 7571 .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512) 7572 .Case("slm", INTEL_SILVERMONT) 7573 .Case("westmere", INTEL_COREI7_WESTMERE) 7574 .Case("znver1", AMDFAM17H_ZNVER1); 7575 7576 llvm::Type *Int32Ty = Builder.getInt32Ty(); 7577 7578 // Matching the struct layout from the compiler-rt/libgcc structure that is 7579 // filled in: 7580 // unsigned int __cpu_vendor; 7581 // unsigned int __cpu_type; 7582 // unsigned int __cpu_subtype; 7583 // unsigned int __cpu_features[1]; 7584 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7585 llvm::ArrayType::get(Int32Ty, 1)); 7586 7587 // Grab the global __cpu_model. 7588 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7589 7590 // Calculate the index needed to access the correct field based on the 7591 // range. Also adjust the expected value. 7592 unsigned Index; 7593 unsigned Value; 7594 if (CPU > CPU_SUBTYPE_START) { 7595 Index = 2; 7596 Value = CPU - CPU_SUBTYPE_START; 7597 } else if (CPU > CPU_TYPE_START) { 7598 Index = 1; 7599 Value = CPU - CPU_TYPE_START; 7600 } else { 7601 Index = 0; 7602 Value = CPU; 7603 } 7604 7605 // Grab the appropriate field from __cpu_model. 7606 llvm::Value *Idxs[] = { 7607 ConstantInt::get(Int32Ty, 0), 7608 ConstantInt::get(Int32Ty, Index) 7609 }; 7610 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); 7611 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); 7612 7613 // Check the value of the field against the requested value. 7614 return Builder.CreateICmpEQ(CpuValue, 7615 llvm::ConstantInt::get(Int32Ty, Value)); 7616 } 7617 7618 Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { 7619 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); 7620 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString(); 7621 return EmitX86CpuSupports(FeatureStr); 7622 } 7623 7624 Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) { 7625 // TODO: When/if this becomes more than x86 specific then use a TargetInfo 7626 // based mapping. 7627 // Processor features and mapping to processor feature value. 7628 enum X86Features { 7629 CMOV = 0, 7630 MMX, 7631 POPCNT, 7632 SSE, 7633 SSE2, 7634 SSE3, 7635 SSSE3, 7636 SSE4_1, 7637 SSE4_2, 7638 AVX, 7639 AVX2, 7640 SSE4_A, 7641 FMA4, 7642 XOP, 7643 FMA, 7644 AVX512F, 7645 BMI, 7646 BMI2, 7647 AES, 7648 PCLMUL, 7649 AVX512VL, 7650 AVX512BW, 7651 AVX512DQ, 7652 AVX512CD, 7653 AVX512ER, 7654 AVX512PF, 7655 AVX512VBMI, 7656 AVX512IFMA, 7657 AVX5124VNNIW, 7658 AVX5124FMAPS, 7659 AVX512VPOPCNTDQ, 7660 MAX 7661 }; 7662 7663 uint32_t FeaturesMask = 0; 7664 7665 for (const StringRef &FeatureStr : FeatureStrs) { 7666 X86Features Feature = 7667 StringSwitch<X86Features>(FeatureStr) 7668 .Case("cmov", X86Features::CMOV) 7669 .Case("mmx", X86Features::MMX) 7670 .Case("popcnt", X86Features::POPCNT) 7671 .Case("sse", X86Features::SSE) 7672 .Case("sse2", X86Features::SSE2) 7673 .Case("sse3", X86Features::SSE3) 7674 .Case("ssse3", X86Features::SSSE3) 7675 .Case("sse4.1", X86Features::SSE4_1) 7676 .Case("sse4.2", X86Features::SSE4_2) 7677 .Case("avx", X86Features::AVX) 7678 .Case("avx2", X86Features::AVX2) 7679 .Case("sse4a", X86Features::SSE4_A) 7680 .Case("fma4", X86Features::FMA4) 7681 .Case("xop", X86Features::XOP) 7682 .Case("fma", X86Features::FMA) 7683 .Case("avx512f", X86Features::AVX512F) 7684 .Case("bmi", X86Features::BMI) 7685 .Case("bmi2", X86Features::BMI2) 7686 .Case("aes", X86Features::AES) 7687 .Case("pclmul", X86Features::PCLMUL) 7688 .Case("avx512vl", X86Features::AVX512VL) 7689 .Case("avx512bw", X86Features::AVX512BW) 7690 .Case("avx512dq", X86Features::AVX512DQ) 7691 .Case("avx512cd", X86Features::AVX512CD) 7692 .Case("avx512er", X86Features::AVX512ER) 7693 .Case("avx512pf", X86Features::AVX512PF) 7694 .Case("avx512vbmi", X86Features::AVX512VBMI) 7695 .Case("avx512ifma", X86Features::AVX512IFMA) 7696 .Case("avx5124vnniw", X86Features::AVX5124VNNIW) 7697 .Case("avx5124fmaps", X86Features::AVX5124FMAPS) 7698 .Case("avx512vpopcntdq", X86Features::AVX512VPOPCNTDQ) 7699 .Default(X86Features::MAX); 7700 assert(Feature != X86Features::MAX && "Invalid feature!"); 7701 FeaturesMask |= (1U << Feature); 7702 } 7703 7704 // Matching the struct layout from the compiler-rt/libgcc structure that is 7705 // filled in: 7706 // unsigned int __cpu_vendor; 7707 // unsigned int __cpu_type; 7708 // unsigned int __cpu_subtype; 7709 // unsigned int __cpu_features[1]; 7710 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7711 llvm::ArrayType::get(Int32Ty, 1)); 7712 7713 // Grab the global __cpu_model. 7714 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7715 7716 // Grab the first (0th) element from the field __cpu_features off of the 7717 // global in the struct STy. 7718 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3), 7719 ConstantInt::get(Int32Ty, 0)}; 7720 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs); 7721 Value *Features = 7722 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4)); 7723 7724 // Check the value of the bit corresponding to the feature requested. 7725 Value *Bitset = Builder.CreateAnd( 7726 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask)); 7727 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0)); 7728 } 7729 7730 Value *CodeGenFunction::EmitX86CpuInit() { 7731 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, 7732 /*Variadic*/ false); 7733 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init"); 7734 return Builder.CreateCall(Func); 7735 } 7736 7737 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 7738 const CallExpr *E) { 7739 if (BuiltinID == X86::BI__builtin_cpu_is) 7740 return EmitX86CpuIs(E); 7741 if (BuiltinID == X86::BI__builtin_cpu_supports) 7742 return EmitX86CpuSupports(E); 7743 if (BuiltinID == X86::BI__builtin_cpu_init) 7744 return EmitX86CpuInit(); 7745 7746 SmallVector<Value*, 4> Ops; 7747 7748 // Find out if any arguments are required to be integer constant expressions. 7749 unsigned ICEArguments = 0; 7750 ASTContext::GetBuiltinTypeError Error; 7751 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 7752 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 7753 7754 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 7755 // If this is a normal argument, just emit it as a scalar. 7756 if ((ICEArguments & (1 << i)) == 0) { 7757 Ops.push_back(EmitScalarExpr(E->getArg(i))); 7758 continue; 7759 } 7760 7761 // If this is required to be a constant, constant fold it so that we know 7762 // that the generated intrinsic gets a ConstantInt. 7763 llvm::APSInt Result; 7764 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 7765 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 7766 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 7767 } 7768 7769 // These exist so that the builtin that takes an immediate can be bounds 7770 // checked by clang to avoid passing bad immediates to the backend. Since 7771 // AVX has a larger immediate than SSE we would need separate builtins to 7772 // do the different bounds checking. Rather than create a clang specific 7773 // SSE only builtin, this implements eight separate builtins to match gcc 7774 // implementation. 7775 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) { 7776 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm)); 7777 llvm::Function *F = CGM.getIntrinsic(ID); 7778 return Builder.CreateCall(F, Ops); 7779 }; 7780 7781 // For the vector forms of FP comparisons, translate the builtins directly to 7782 // IR. 7783 // TODO: The builtins could be removed if the SSE header files used vector 7784 // extension comparisons directly (vector ordered/unordered may need 7785 // additional support via __builtin_isnan()). 7786 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) { 7787 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]); 7788 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType()); 7789 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy); 7790 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy); 7791 return Builder.CreateBitCast(Sext, FPVecTy); 7792 }; 7793 7794 switch (BuiltinID) { 7795 default: return nullptr; 7796 case X86::BI_mm_prefetch: { 7797 Value *Address = Ops[0]; 7798 Value *RW = ConstantInt::get(Int32Ty, 0); 7799 Value *Locality = Ops[1]; 7800 Value *Data = ConstantInt::get(Int32Ty, 1); 7801 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 7802 return Builder.CreateCall(F, {Address, RW, Locality, Data}); 7803 } 7804 case X86::BI_mm_clflush: { 7805 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush), 7806 Ops[0]); 7807 } 7808 case X86::BI_mm_lfence: { 7809 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence)); 7810 } 7811 case X86::BI_mm_mfence: { 7812 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence)); 7813 } 7814 case X86::BI_mm_sfence: { 7815 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence)); 7816 } 7817 case X86::BI_mm_pause: { 7818 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause)); 7819 } 7820 case X86::BI__rdtsc: { 7821 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc)); 7822 } 7823 case X86::BI__builtin_ia32_undef128: 7824 case X86::BI__builtin_ia32_undef256: 7825 case X86::BI__builtin_ia32_undef512: 7826 // The x86 definition of "undef" is not the same as the LLVM definition 7827 // (PR32176). We leave optimizing away an unnecessary zero constant to the 7828 // IR optimizer and backend. 7829 // TODO: If we had a "freeze" IR instruction to generate a fixed undef 7830 // value, we should use that here instead of a zero. 7831 return llvm::Constant::getNullValue(ConvertType(E->getType())); 7832 case X86::BI__builtin_ia32_vec_init_v8qi: 7833 case X86::BI__builtin_ia32_vec_init_v4hi: 7834 case X86::BI__builtin_ia32_vec_init_v2si: 7835 return Builder.CreateBitCast(BuildVector(Ops), 7836 llvm::Type::getX86_MMXTy(getLLVMContext())); 7837 case X86::BI__builtin_ia32_vec_ext_v2si: 7838 return Builder.CreateExtractElement(Ops[0], 7839 llvm::ConstantInt::get(Ops[1]->getType(), 0)); 7840 case X86::BI_mm_setcsr: 7841 case X86::BI__builtin_ia32_ldmxcsr: { 7842 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 7843 Builder.CreateStore(Ops[0], Tmp); 7844 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 7845 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7846 } 7847 case X86::BI_mm_getcsr: 7848 case X86::BI__builtin_ia32_stmxcsr: { 7849 Address Tmp = CreateMemTemp(E->getType()); 7850 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 7851 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7852 return Builder.CreateLoad(Tmp, "stmxcsr"); 7853 } 7854 case X86::BI__builtin_ia32_xsave: 7855 case X86::BI__builtin_ia32_xsave64: 7856 case X86::BI__builtin_ia32_xrstor: 7857 case X86::BI__builtin_ia32_xrstor64: 7858 case X86::BI__builtin_ia32_xsaveopt: 7859 case X86::BI__builtin_ia32_xsaveopt64: 7860 case X86::BI__builtin_ia32_xrstors: 7861 case X86::BI__builtin_ia32_xrstors64: 7862 case X86::BI__builtin_ia32_xsavec: 7863 case X86::BI__builtin_ia32_xsavec64: 7864 case X86::BI__builtin_ia32_xsaves: 7865 case X86::BI__builtin_ia32_xsaves64: { 7866 Intrinsic::ID ID; 7867 #define INTRINSIC_X86_XSAVE_ID(NAME) \ 7868 case X86::BI__builtin_ia32_##NAME: \ 7869 ID = Intrinsic::x86_##NAME; \ 7870 break 7871 switch (BuiltinID) { 7872 default: llvm_unreachable("Unsupported intrinsic!"); 7873 INTRINSIC_X86_XSAVE_ID(xsave); 7874 INTRINSIC_X86_XSAVE_ID(xsave64); 7875 INTRINSIC_X86_XSAVE_ID(xrstor); 7876 INTRINSIC_X86_XSAVE_ID(xrstor64); 7877 INTRINSIC_X86_XSAVE_ID(xsaveopt); 7878 INTRINSIC_X86_XSAVE_ID(xsaveopt64); 7879 INTRINSIC_X86_XSAVE_ID(xrstors); 7880 INTRINSIC_X86_XSAVE_ID(xrstors64); 7881 INTRINSIC_X86_XSAVE_ID(xsavec); 7882 INTRINSIC_X86_XSAVE_ID(xsavec64); 7883 INTRINSIC_X86_XSAVE_ID(xsaves); 7884 INTRINSIC_X86_XSAVE_ID(xsaves64); 7885 } 7886 #undef INTRINSIC_X86_XSAVE_ID 7887 Value *Mhi = Builder.CreateTrunc( 7888 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty); 7889 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty); 7890 Ops[1] = Mhi; 7891 Ops.push_back(Mlo); 7892 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 7893 } 7894 case X86::BI__builtin_ia32_storedqudi128_mask: 7895 case X86::BI__builtin_ia32_storedqusi128_mask: 7896 case X86::BI__builtin_ia32_storedquhi128_mask: 7897 case X86::BI__builtin_ia32_storedquqi128_mask: 7898 case X86::BI__builtin_ia32_storeupd128_mask: 7899 case X86::BI__builtin_ia32_storeups128_mask: 7900 case X86::BI__builtin_ia32_storedqudi256_mask: 7901 case X86::BI__builtin_ia32_storedqusi256_mask: 7902 case X86::BI__builtin_ia32_storedquhi256_mask: 7903 case X86::BI__builtin_ia32_storedquqi256_mask: 7904 case X86::BI__builtin_ia32_storeupd256_mask: 7905 case X86::BI__builtin_ia32_storeups256_mask: 7906 case X86::BI__builtin_ia32_storedqudi512_mask: 7907 case X86::BI__builtin_ia32_storedqusi512_mask: 7908 case X86::BI__builtin_ia32_storedquhi512_mask: 7909 case X86::BI__builtin_ia32_storedquqi512_mask: 7910 case X86::BI__builtin_ia32_storeupd512_mask: 7911 case X86::BI__builtin_ia32_storeups512_mask: 7912 return EmitX86MaskedStore(*this, Ops, 1); 7913 7914 case X86::BI__builtin_ia32_storess128_mask: 7915 case X86::BI__builtin_ia32_storesd128_mask: { 7916 return EmitX86MaskedStore(*this, Ops, 16); 7917 } 7918 case X86::BI__builtin_ia32_vpopcntd_512: 7919 case X86::BI__builtin_ia32_vpopcntq_512: { 7920 llvm::Type *ResultType = ConvertType(E->getType()); 7921 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 7922 return Builder.CreateCall(F, Ops); 7923 } 7924 case X86::BI__builtin_ia32_cvtmask2b128: 7925 case X86::BI__builtin_ia32_cvtmask2b256: 7926 case X86::BI__builtin_ia32_cvtmask2b512: 7927 case X86::BI__builtin_ia32_cvtmask2w128: 7928 case X86::BI__builtin_ia32_cvtmask2w256: 7929 case X86::BI__builtin_ia32_cvtmask2w512: 7930 case X86::BI__builtin_ia32_cvtmask2d128: 7931 case X86::BI__builtin_ia32_cvtmask2d256: 7932 case X86::BI__builtin_ia32_cvtmask2d512: 7933 case X86::BI__builtin_ia32_cvtmask2q128: 7934 case X86::BI__builtin_ia32_cvtmask2q256: 7935 case X86::BI__builtin_ia32_cvtmask2q512: 7936 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType())); 7937 7938 case X86::BI__builtin_ia32_movdqa32store128_mask: 7939 case X86::BI__builtin_ia32_movdqa64store128_mask: 7940 case X86::BI__builtin_ia32_storeaps128_mask: 7941 case X86::BI__builtin_ia32_storeapd128_mask: 7942 case X86::BI__builtin_ia32_movdqa32store256_mask: 7943 case X86::BI__builtin_ia32_movdqa64store256_mask: 7944 case X86::BI__builtin_ia32_storeaps256_mask: 7945 case X86::BI__builtin_ia32_storeapd256_mask: 7946 case X86::BI__builtin_ia32_movdqa32store512_mask: 7947 case X86::BI__builtin_ia32_movdqa64store512_mask: 7948 case X86::BI__builtin_ia32_storeaps512_mask: 7949 case X86::BI__builtin_ia32_storeapd512_mask: { 7950 unsigned Align = 7951 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7952 return EmitX86MaskedStore(*this, Ops, Align); 7953 } 7954 case X86::BI__builtin_ia32_loadups128_mask: 7955 case X86::BI__builtin_ia32_loadups256_mask: 7956 case X86::BI__builtin_ia32_loadups512_mask: 7957 case X86::BI__builtin_ia32_loadupd128_mask: 7958 case X86::BI__builtin_ia32_loadupd256_mask: 7959 case X86::BI__builtin_ia32_loadupd512_mask: 7960 case X86::BI__builtin_ia32_loaddquqi128_mask: 7961 case X86::BI__builtin_ia32_loaddquqi256_mask: 7962 case X86::BI__builtin_ia32_loaddquqi512_mask: 7963 case X86::BI__builtin_ia32_loaddquhi128_mask: 7964 case X86::BI__builtin_ia32_loaddquhi256_mask: 7965 case X86::BI__builtin_ia32_loaddquhi512_mask: 7966 case X86::BI__builtin_ia32_loaddqusi128_mask: 7967 case X86::BI__builtin_ia32_loaddqusi256_mask: 7968 case X86::BI__builtin_ia32_loaddqusi512_mask: 7969 case X86::BI__builtin_ia32_loaddqudi128_mask: 7970 case X86::BI__builtin_ia32_loaddqudi256_mask: 7971 case X86::BI__builtin_ia32_loaddqudi512_mask: 7972 return EmitX86MaskedLoad(*this, Ops, 1); 7973 7974 case X86::BI__builtin_ia32_loadss128_mask: 7975 case X86::BI__builtin_ia32_loadsd128_mask: 7976 return EmitX86MaskedLoad(*this, Ops, 16); 7977 7978 case X86::BI__builtin_ia32_loadaps128_mask: 7979 case X86::BI__builtin_ia32_loadaps256_mask: 7980 case X86::BI__builtin_ia32_loadaps512_mask: 7981 case X86::BI__builtin_ia32_loadapd128_mask: 7982 case X86::BI__builtin_ia32_loadapd256_mask: 7983 case X86::BI__builtin_ia32_loadapd512_mask: 7984 case X86::BI__builtin_ia32_movdqa32load128_mask: 7985 case X86::BI__builtin_ia32_movdqa32load256_mask: 7986 case X86::BI__builtin_ia32_movdqa32load512_mask: 7987 case X86::BI__builtin_ia32_movdqa64load128_mask: 7988 case X86::BI__builtin_ia32_movdqa64load256_mask: 7989 case X86::BI__builtin_ia32_movdqa64load512_mask: { 7990 unsigned Align = 7991 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7992 return EmitX86MaskedLoad(*this, Ops, Align); 7993 } 7994 7995 case X86::BI__builtin_ia32_vbroadcastf128_pd256: 7996 case X86::BI__builtin_ia32_vbroadcastf128_ps256: { 7997 llvm::Type *DstTy = ConvertType(E->getType()); 7998 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1); 7999 } 8000 8001 case X86::BI__builtin_ia32_storehps: 8002 case X86::BI__builtin_ia32_storelps: { 8003 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 8004 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 8005 8006 // cast val v2i64 8007 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 8008 8009 // extract (0, 1) 8010 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 8011 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index); 8012 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 8013 8014 // cast pointer to i64 & store 8015 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 8016 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 8017 } 8018 case X86::BI__builtin_ia32_palignr128: 8019 case X86::BI__builtin_ia32_palignr256: 8020 case X86::BI__builtin_ia32_palignr512_mask: { 8021 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8022 8023 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 8024 assert(NumElts % 16 == 0); 8025 8026 // If palignr is shifting the pair of vectors more than the size of two 8027 // lanes, emit zero. 8028 if (ShiftVal >= 32) 8029 return llvm::Constant::getNullValue(ConvertType(E->getType())); 8030 8031 // If palignr is shifting the pair of input vectors more than one lane, 8032 // but less than two lanes, convert to shifting in zeroes. 8033 if (ShiftVal > 16) { 8034 ShiftVal -= 16; 8035 Ops[1] = Ops[0]; 8036 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType()); 8037 } 8038 8039 uint32_t Indices[64]; 8040 // 256-bit palignr operates on 128-bit lanes so we need to handle that 8041 for (unsigned l = 0; l != NumElts; l += 16) { 8042 for (unsigned i = 0; i != 16; ++i) { 8043 unsigned Idx = ShiftVal + i; 8044 if (Idx >= 16) 8045 Idx += NumElts - 16; // End of lane, switch operand. 8046 Indices[l + i] = Idx + l; 8047 } 8048 } 8049 8050 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0], 8051 makeArrayRef(Indices, NumElts), 8052 "palignr"); 8053 8054 // If this isn't a masked builtin, just return the align operation. 8055 if (Ops.size() == 3) 8056 return Align; 8057 8058 return EmitX86Select(*this, Ops[4], Align, Ops[3]); 8059 } 8060 8061 case X86::BI__builtin_ia32_vperm2f128_pd256: 8062 case X86::BI__builtin_ia32_vperm2f128_ps256: 8063 case X86::BI__builtin_ia32_vperm2f128_si256: 8064 case X86::BI__builtin_ia32_permti256: { 8065 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8066 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 8067 8068 // This takes a very simple approach since there are two lanes and a 8069 // shuffle can have 2 inputs. So we reserve the first input for the first 8070 // lane and the second input for the second lane. This may result in 8071 // duplicate sources, but this can be dealt with in the backend. 8072 8073 Value *OutOps[2]; 8074 uint32_t Indices[8]; 8075 for (unsigned l = 0; l != 2; ++l) { 8076 // Determine the source for this lane. 8077 if (Imm & (1 << ((l * 4) + 3))) 8078 OutOps[l] = llvm::ConstantAggregateZero::get(Ops[0]->getType()); 8079 else if (Imm & (1 << ((l * 4) + 1))) 8080 OutOps[l] = Ops[1]; 8081 else 8082 OutOps[l] = Ops[0]; 8083 8084 for (unsigned i = 0; i != NumElts/2; ++i) { 8085 // Start with ith element of the source for this lane. 8086 unsigned Idx = (l * NumElts) + i; 8087 // If bit 0 of the immediate half is set, switch to the high half of 8088 // the source. 8089 if (Imm & (1 << (l * 4))) 8090 Idx += NumElts/2; 8091 Indices[(l * (NumElts/2)) + i] = Idx; 8092 } 8093 } 8094 8095 return Builder.CreateShuffleVector(OutOps[0], OutOps[1], 8096 makeArrayRef(Indices, NumElts), 8097 "vperm"); 8098 } 8099 8100 case X86::BI__builtin_ia32_movnti: 8101 case X86::BI__builtin_ia32_movnti64: 8102 case X86::BI__builtin_ia32_movntsd: 8103 case X86::BI__builtin_ia32_movntss: { 8104 llvm::MDNode *Node = llvm::MDNode::get( 8105 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); 8106 8107 Value *Ptr = Ops[0]; 8108 Value *Src = Ops[1]; 8109 8110 // Extract the 0'th element of the source vector. 8111 if (BuiltinID == X86::BI__builtin_ia32_movntsd || 8112 BuiltinID == X86::BI__builtin_ia32_movntss) 8113 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract"); 8114 8115 // Convert the type of the pointer to a pointer to the stored type. 8116 Value *BC = Builder.CreateBitCast( 8117 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast"); 8118 8119 // Unaligned nontemporal store of the scalar value. 8120 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC); 8121 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 8122 SI->setAlignment(1); 8123 return SI; 8124 } 8125 8126 case X86::BI__builtin_ia32_selectb_128: 8127 case X86::BI__builtin_ia32_selectb_256: 8128 case X86::BI__builtin_ia32_selectb_512: 8129 case X86::BI__builtin_ia32_selectw_128: 8130 case X86::BI__builtin_ia32_selectw_256: 8131 case X86::BI__builtin_ia32_selectw_512: 8132 case X86::BI__builtin_ia32_selectd_128: 8133 case X86::BI__builtin_ia32_selectd_256: 8134 case X86::BI__builtin_ia32_selectd_512: 8135 case X86::BI__builtin_ia32_selectq_128: 8136 case X86::BI__builtin_ia32_selectq_256: 8137 case X86::BI__builtin_ia32_selectq_512: 8138 case X86::BI__builtin_ia32_selectps_128: 8139 case X86::BI__builtin_ia32_selectps_256: 8140 case X86::BI__builtin_ia32_selectps_512: 8141 case X86::BI__builtin_ia32_selectpd_128: 8142 case X86::BI__builtin_ia32_selectpd_256: 8143 case X86::BI__builtin_ia32_selectpd_512: 8144 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]); 8145 case X86::BI__builtin_ia32_cmpb128_mask: 8146 case X86::BI__builtin_ia32_cmpb256_mask: 8147 case X86::BI__builtin_ia32_cmpb512_mask: 8148 case X86::BI__builtin_ia32_cmpw128_mask: 8149 case X86::BI__builtin_ia32_cmpw256_mask: 8150 case X86::BI__builtin_ia32_cmpw512_mask: 8151 case X86::BI__builtin_ia32_cmpd128_mask: 8152 case X86::BI__builtin_ia32_cmpd256_mask: 8153 case X86::BI__builtin_ia32_cmpd512_mask: 8154 case X86::BI__builtin_ia32_cmpq128_mask: 8155 case X86::BI__builtin_ia32_cmpq256_mask: 8156 case X86::BI__builtin_ia32_cmpq512_mask: { 8157 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8158 return EmitX86MaskedCompare(*this, CC, true, Ops); 8159 } 8160 case X86::BI__builtin_ia32_ucmpb128_mask: 8161 case X86::BI__builtin_ia32_ucmpb256_mask: 8162 case X86::BI__builtin_ia32_ucmpb512_mask: 8163 case X86::BI__builtin_ia32_ucmpw128_mask: 8164 case X86::BI__builtin_ia32_ucmpw256_mask: 8165 case X86::BI__builtin_ia32_ucmpw512_mask: 8166 case X86::BI__builtin_ia32_ucmpd128_mask: 8167 case X86::BI__builtin_ia32_ucmpd256_mask: 8168 case X86::BI__builtin_ia32_ucmpd512_mask: 8169 case X86::BI__builtin_ia32_ucmpq128_mask: 8170 case X86::BI__builtin_ia32_ucmpq256_mask: 8171 case X86::BI__builtin_ia32_ucmpq512_mask: { 8172 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8173 return EmitX86MaskedCompare(*this, CC, false, Ops); 8174 } 8175 8176 case X86::BI__builtin_ia32_vplzcntd_128_mask: 8177 case X86::BI__builtin_ia32_vplzcntd_256_mask: 8178 case X86::BI__builtin_ia32_vplzcntd_512_mask: 8179 case X86::BI__builtin_ia32_vplzcntq_128_mask: 8180 case X86::BI__builtin_ia32_vplzcntq_256_mask: 8181 case X86::BI__builtin_ia32_vplzcntq_512_mask: { 8182 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType()); 8183 return EmitX86Select(*this, Ops[2], 8184 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}), 8185 Ops[1]); 8186 } 8187 8188 case X86::BI__builtin_ia32_pabsb128: 8189 case X86::BI__builtin_ia32_pabsw128: 8190 case X86::BI__builtin_ia32_pabsd128: 8191 case X86::BI__builtin_ia32_pabsb256: 8192 case X86::BI__builtin_ia32_pabsw256: 8193 case X86::BI__builtin_ia32_pabsd256: 8194 case X86::BI__builtin_ia32_pabsq128_mask: 8195 case X86::BI__builtin_ia32_pabsq256_mask: 8196 case X86::BI__builtin_ia32_pabsb512_mask: 8197 case X86::BI__builtin_ia32_pabsw512_mask: 8198 case X86::BI__builtin_ia32_pabsd512_mask: 8199 case X86::BI__builtin_ia32_pabsq512_mask: 8200 return EmitX86Abs(*this, Ops); 8201 8202 case X86::BI__builtin_ia32_pmaxsb128: 8203 case X86::BI__builtin_ia32_pmaxsw128: 8204 case X86::BI__builtin_ia32_pmaxsd128: 8205 case X86::BI__builtin_ia32_pmaxsq128_mask: 8206 case X86::BI__builtin_ia32_pmaxsb256: 8207 case X86::BI__builtin_ia32_pmaxsw256: 8208 case X86::BI__builtin_ia32_pmaxsd256: 8209 case X86::BI__builtin_ia32_pmaxsq256_mask: 8210 case X86::BI__builtin_ia32_pmaxsb512_mask: 8211 case X86::BI__builtin_ia32_pmaxsw512_mask: 8212 case X86::BI__builtin_ia32_pmaxsd512_mask: 8213 case X86::BI__builtin_ia32_pmaxsq512_mask: 8214 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops); 8215 case X86::BI__builtin_ia32_pmaxub128: 8216 case X86::BI__builtin_ia32_pmaxuw128: 8217 case X86::BI__builtin_ia32_pmaxud128: 8218 case X86::BI__builtin_ia32_pmaxuq128_mask: 8219 case X86::BI__builtin_ia32_pmaxub256: 8220 case X86::BI__builtin_ia32_pmaxuw256: 8221 case X86::BI__builtin_ia32_pmaxud256: 8222 case X86::BI__builtin_ia32_pmaxuq256_mask: 8223 case X86::BI__builtin_ia32_pmaxub512_mask: 8224 case X86::BI__builtin_ia32_pmaxuw512_mask: 8225 case X86::BI__builtin_ia32_pmaxud512_mask: 8226 case X86::BI__builtin_ia32_pmaxuq512_mask: 8227 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops); 8228 case X86::BI__builtin_ia32_pminsb128: 8229 case X86::BI__builtin_ia32_pminsw128: 8230 case X86::BI__builtin_ia32_pminsd128: 8231 case X86::BI__builtin_ia32_pminsq128_mask: 8232 case X86::BI__builtin_ia32_pminsb256: 8233 case X86::BI__builtin_ia32_pminsw256: 8234 case X86::BI__builtin_ia32_pminsd256: 8235 case X86::BI__builtin_ia32_pminsq256_mask: 8236 case X86::BI__builtin_ia32_pminsb512_mask: 8237 case X86::BI__builtin_ia32_pminsw512_mask: 8238 case X86::BI__builtin_ia32_pminsd512_mask: 8239 case X86::BI__builtin_ia32_pminsq512_mask: 8240 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops); 8241 case X86::BI__builtin_ia32_pminub128: 8242 case X86::BI__builtin_ia32_pminuw128: 8243 case X86::BI__builtin_ia32_pminud128: 8244 case X86::BI__builtin_ia32_pminuq128_mask: 8245 case X86::BI__builtin_ia32_pminub256: 8246 case X86::BI__builtin_ia32_pminuw256: 8247 case X86::BI__builtin_ia32_pminud256: 8248 case X86::BI__builtin_ia32_pminuq256_mask: 8249 case X86::BI__builtin_ia32_pminub512_mask: 8250 case X86::BI__builtin_ia32_pminuw512_mask: 8251 case X86::BI__builtin_ia32_pminud512_mask: 8252 case X86::BI__builtin_ia32_pminuq512_mask: 8253 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops); 8254 8255 // 3DNow! 8256 case X86::BI__builtin_ia32_pswapdsf: 8257 case X86::BI__builtin_ia32_pswapdsi: { 8258 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 8259 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 8260 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd); 8261 return Builder.CreateCall(F, Ops, "pswapd"); 8262 } 8263 case X86::BI__builtin_ia32_rdrand16_step: 8264 case X86::BI__builtin_ia32_rdrand32_step: 8265 case X86::BI__builtin_ia32_rdrand64_step: 8266 case X86::BI__builtin_ia32_rdseed16_step: 8267 case X86::BI__builtin_ia32_rdseed32_step: 8268 case X86::BI__builtin_ia32_rdseed64_step: { 8269 Intrinsic::ID ID; 8270 switch (BuiltinID) { 8271 default: llvm_unreachable("Unsupported intrinsic!"); 8272 case X86::BI__builtin_ia32_rdrand16_step: 8273 ID = Intrinsic::x86_rdrand_16; 8274 break; 8275 case X86::BI__builtin_ia32_rdrand32_step: 8276 ID = Intrinsic::x86_rdrand_32; 8277 break; 8278 case X86::BI__builtin_ia32_rdrand64_step: 8279 ID = Intrinsic::x86_rdrand_64; 8280 break; 8281 case X86::BI__builtin_ia32_rdseed16_step: 8282 ID = Intrinsic::x86_rdseed_16; 8283 break; 8284 case X86::BI__builtin_ia32_rdseed32_step: 8285 ID = Intrinsic::x86_rdseed_32; 8286 break; 8287 case X86::BI__builtin_ia32_rdseed64_step: 8288 ID = Intrinsic::x86_rdseed_64; 8289 break; 8290 } 8291 8292 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 8293 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0), 8294 Ops[0]); 8295 return Builder.CreateExtractValue(Call, 1); 8296 } 8297 8298 // SSE packed comparison intrinsics 8299 case X86::BI__builtin_ia32_cmpeqps: 8300 case X86::BI__builtin_ia32_cmpeqpd: 8301 return getVectorFCmpIR(CmpInst::FCMP_OEQ); 8302 case X86::BI__builtin_ia32_cmpltps: 8303 case X86::BI__builtin_ia32_cmpltpd: 8304 return getVectorFCmpIR(CmpInst::FCMP_OLT); 8305 case X86::BI__builtin_ia32_cmpleps: 8306 case X86::BI__builtin_ia32_cmplepd: 8307 return getVectorFCmpIR(CmpInst::FCMP_OLE); 8308 case X86::BI__builtin_ia32_cmpunordps: 8309 case X86::BI__builtin_ia32_cmpunordpd: 8310 return getVectorFCmpIR(CmpInst::FCMP_UNO); 8311 case X86::BI__builtin_ia32_cmpneqps: 8312 case X86::BI__builtin_ia32_cmpneqpd: 8313 return getVectorFCmpIR(CmpInst::FCMP_UNE); 8314 case X86::BI__builtin_ia32_cmpnltps: 8315 case X86::BI__builtin_ia32_cmpnltpd: 8316 return getVectorFCmpIR(CmpInst::FCMP_UGE); 8317 case X86::BI__builtin_ia32_cmpnleps: 8318 case X86::BI__builtin_ia32_cmpnlepd: 8319 return getVectorFCmpIR(CmpInst::FCMP_UGT); 8320 case X86::BI__builtin_ia32_cmpordps: 8321 case X86::BI__builtin_ia32_cmpordpd: 8322 return getVectorFCmpIR(CmpInst::FCMP_ORD); 8323 case X86::BI__builtin_ia32_cmpps: 8324 case X86::BI__builtin_ia32_cmpps256: 8325 case X86::BI__builtin_ia32_cmppd: 8326 case X86::BI__builtin_ia32_cmppd256: { 8327 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8328 // If this one of the SSE immediates, we can use native IR. 8329 if (CC < 8) { 8330 FCmpInst::Predicate Pred; 8331 switch (CC) { 8332 case 0: Pred = FCmpInst::FCMP_OEQ; break; 8333 case 1: Pred = FCmpInst::FCMP_OLT; break; 8334 case 2: Pred = FCmpInst::FCMP_OLE; break; 8335 case 3: Pred = FCmpInst::FCMP_UNO; break; 8336 case 4: Pred = FCmpInst::FCMP_UNE; break; 8337 case 5: Pred = FCmpInst::FCMP_UGE; break; 8338 case 6: Pred = FCmpInst::FCMP_UGT; break; 8339 case 7: Pred = FCmpInst::FCMP_ORD; break; 8340 } 8341 return getVectorFCmpIR(Pred); 8342 } 8343 8344 // We can't handle 8-31 immediates with native IR, use the intrinsic. 8345 // Except for predicates that create constants. 8346 Intrinsic::ID ID; 8347 switch (BuiltinID) { 8348 default: llvm_unreachable("Unsupported intrinsic!"); 8349 case X86::BI__builtin_ia32_cmpps: 8350 ID = Intrinsic::x86_sse_cmp_ps; 8351 break; 8352 case X86::BI__builtin_ia32_cmpps256: 8353 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8354 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8355 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8356 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8357 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) : 8358 llvm::Constant::getNullValue(Builder.getInt32Ty()); 8359 Value *Vec = Builder.CreateVectorSplat( 8360 Ops[0]->getType()->getVectorNumElements(), Constant); 8361 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8362 } 8363 ID = Intrinsic::x86_avx_cmp_ps_256; 8364 break; 8365 case X86::BI__builtin_ia32_cmppd: 8366 ID = Intrinsic::x86_sse2_cmp_pd; 8367 break; 8368 case X86::BI__builtin_ia32_cmppd256: 8369 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8370 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8371 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8372 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8373 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) : 8374 llvm::Constant::getNullValue(Builder.getInt64Ty()); 8375 Value *Vec = Builder.CreateVectorSplat( 8376 Ops[0]->getType()->getVectorNumElements(), Constant); 8377 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8378 } 8379 ID = Intrinsic::x86_avx_cmp_pd_256; 8380 break; 8381 } 8382 8383 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 8384 } 8385 8386 // SSE scalar comparison intrinsics 8387 case X86::BI__builtin_ia32_cmpeqss: 8388 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0); 8389 case X86::BI__builtin_ia32_cmpltss: 8390 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1); 8391 case X86::BI__builtin_ia32_cmpless: 8392 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2); 8393 case X86::BI__builtin_ia32_cmpunordss: 8394 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3); 8395 case X86::BI__builtin_ia32_cmpneqss: 8396 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4); 8397 case X86::BI__builtin_ia32_cmpnltss: 8398 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5); 8399 case X86::BI__builtin_ia32_cmpnless: 8400 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6); 8401 case X86::BI__builtin_ia32_cmpordss: 8402 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7); 8403 case X86::BI__builtin_ia32_cmpeqsd: 8404 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0); 8405 case X86::BI__builtin_ia32_cmpltsd: 8406 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1); 8407 case X86::BI__builtin_ia32_cmplesd: 8408 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2); 8409 case X86::BI__builtin_ia32_cmpunordsd: 8410 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3); 8411 case X86::BI__builtin_ia32_cmpneqsd: 8412 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4); 8413 case X86::BI__builtin_ia32_cmpnltsd: 8414 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5); 8415 case X86::BI__builtin_ia32_cmpnlesd: 8416 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); 8417 case X86::BI__builtin_ia32_cmpordsd: 8418 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); 8419 8420 case X86::BI__emul: 8421 case X86::BI__emulu: { 8422 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64); 8423 bool isSigned = (BuiltinID == X86::BI__emul); 8424 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned); 8425 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned); 8426 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned); 8427 } 8428 case X86::BI__mulh: 8429 case X86::BI__umulh: 8430 case X86::BI_mul128: 8431 case X86::BI_umul128: { 8432 llvm::Type *ResType = ConvertType(E->getType()); 8433 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 8434 8435 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128); 8436 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned); 8437 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned); 8438 8439 Value *MulResult, *HigherBits; 8440 if (IsSigned) { 8441 MulResult = Builder.CreateNSWMul(LHS, RHS); 8442 HigherBits = Builder.CreateAShr(MulResult, 64); 8443 } else { 8444 MulResult = Builder.CreateNUWMul(LHS, RHS); 8445 HigherBits = Builder.CreateLShr(MulResult, 64); 8446 } 8447 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); 8448 8449 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh) 8450 return HigherBits; 8451 8452 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2)); 8453 Builder.CreateStore(HigherBits, HighBitsAddress); 8454 return Builder.CreateIntCast(MulResult, ResType, IsSigned); 8455 } 8456 8457 case X86::BI__faststorefence: { 8458 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8459 llvm::SyncScope::System); 8460 } 8461 case X86::BI_ReadWriteBarrier: 8462 case X86::BI_ReadBarrier: 8463 case X86::BI_WriteBarrier: { 8464 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8465 llvm::SyncScope::SingleThread); 8466 } 8467 case X86::BI_BitScanForward: 8468 case X86::BI_BitScanForward64: 8469 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 8470 case X86::BI_BitScanReverse: 8471 case X86::BI_BitScanReverse64: 8472 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 8473 8474 case X86::BI_InterlockedAnd64: 8475 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 8476 case X86::BI_InterlockedExchange64: 8477 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 8478 case X86::BI_InterlockedExchangeAdd64: 8479 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 8480 case X86::BI_InterlockedExchangeSub64: 8481 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 8482 case X86::BI_InterlockedOr64: 8483 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 8484 case X86::BI_InterlockedXor64: 8485 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 8486 case X86::BI_InterlockedDecrement64: 8487 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 8488 case X86::BI_InterlockedIncrement64: 8489 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 8490 8491 case X86::BI_AddressOfReturnAddress: { 8492 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); 8493 return Builder.CreateCall(F); 8494 } 8495 case X86::BI__stosb: { 8496 // We treat __stosb as a volatile memset - it may not generate "rep stosb" 8497 // instruction, but it will create a memset that won't be optimized away. 8498 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); 8499 } 8500 case X86::BI__ud2: 8501 // llvm.trap makes a ud2a instruction on x86. 8502 return EmitTrapCall(Intrinsic::trap); 8503 case X86::BI__int2c: { 8504 // This syscall signals a driver assertion failure in x86 NT kernels. 8505 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 8506 llvm::InlineAsm *IA = 8507 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true); 8508 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get( 8509 getLLVMContext(), llvm::AttributeList::FunctionIndex, 8510 llvm::Attribute::NoReturn); 8511 CallSite CS = Builder.CreateCall(IA); 8512 CS.setAttributes(NoReturnAttr); 8513 return CS.getInstruction(); 8514 } 8515 case X86::BI__readfsbyte: 8516 case X86::BI__readfsword: 8517 case X86::BI__readfsdword: 8518 case X86::BI__readfsqword: { 8519 llvm::Type *IntTy = ConvertType(E->getType()); 8520 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8521 llvm::PointerType::get(IntTy, 257)); 8522 LoadInst *Load = Builder.CreateAlignedLoad( 8523 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8524 Load->setVolatile(true); 8525 return Load; 8526 } 8527 case X86::BI__readgsbyte: 8528 case X86::BI__readgsword: 8529 case X86::BI__readgsdword: 8530 case X86::BI__readgsqword: { 8531 llvm::Type *IntTy = ConvertType(E->getType()); 8532 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8533 llvm::PointerType::get(IntTy, 256)); 8534 LoadInst *Load = Builder.CreateAlignedLoad( 8535 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8536 Load->setVolatile(true); 8537 return Load; 8538 } 8539 } 8540 } 8541 8542 8543 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 8544 const CallExpr *E) { 8545 SmallVector<Value*, 4> Ops; 8546 8547 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 8548 Ops.push_back(EmitScalarExpr(E->getArg(i))); 8549 8550 Intrinsic::ID ID = Intrinsic::not_intrinsic; 8551 8552 switch (BuiltinID) { 8553 default: return nullptr; 8554 8555 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we 8556 // call __builtin_readcyclecounter. 8557 case PPC::BI__builtin_ppc_get_timebase: 8558 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter)); 8559 8560 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr 8561 case PPC::BI__builtin_altivec_lvx: 8562 case PPC::BI__builtin_altivec_lvxl: 8563 case PPC::BI__builtin_altivec_lvebx: 8564 case PPC::BI__builtin_altivec_lvehx: 8565 case PPC::BI__builtin_altivec_lvewx: 8566 case PPC::BI__builtin_altivec_lvsl: 8567 case PPC::BI__builtin_altivec_lvsr: 8568 case PPC::BI__builtin_vsx_lxvd2x: 8569 case PPC::BI__builtin_vsx_lxvw4x: 8570 case PPC::BI__builtin_vsx_lxvd2x_be: 8571 case PPC::BI__builtin_vsx_lxvw4x_be: 8572 case PPC::BI__builtin_vsx_lxvl: 8573 case PPC::BI__builtin_vsx_lxvll: 8574 { 8575 if(BuiltinID == PPC::BI__builtin_vsx_lxvl || 8576 BuiltinID == PPC::BI__builtin_vsx_lxvll){ 8577 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy); 8578 }else { 8579 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8580 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 8581 Ops.pop_back(); 8582 } 8583 8584 switch (BuiltinID) { 8585 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 8586 case PPC::BI__builtin_altivec_lvx: 8587 ID = Intrinsic::ppc_altivec_lvx; 8588 break; 8589 case PPC::BI__builtin_altivec_lvxl: 8590 ID = Intrinsic::ppc_altivec_lvxl; 8591 break; 8592 case PPC::BI__builtin_altivec_lvebx: 8593 ID = Intrinsic::ppc_altivec_lvebx; 8594 break; 8595 case PPC::BI__builtin_altivec_lvehx: 8596 ID = Intrinsic::ppc_altivec_lvehx; 8597 break; 8598 case PPC::BI__builtin_altivec_lvewx: 8599 ID = Intrinsic::ppc_altivec_lvewx; 8600 break; 8601 case PPC::BI__builtin_altivec_lvsl: 8602 ID = Intrinsic::ppc_altivec_lvsl; 8603 break; 8604 case PPC::BI__builtin_altivec_lvsr: 8605 ID = Intrinsic::ppc_altivec_lvsr; 8606 break; 8607 case PPC::BI__builtin_vsx_lxvd2x: 8608 ID = Intrinsic::ppc_vsx_lxvd2x; 8609 break; 8610 case PPC::BI__builtin_vsx_lxvw4x: 8611 ID = Intrinsic::ppc_vsx_lxvw4x; 8612 break; 8613 case PPC::BI__builtin_vsx_lxvd2x_be: 8614 ID = Intrinsic::ppc_vsx_lxvd2x_be; 8615 break; 8616 case PPC::BI__builtin_vsx_lxvw4x_be: 8617 ID = Intrinsic::ppc_vsx_lxvw4x_be; 8618 break; 8619 case PPC::BI__builtin_vsx_lxvl: 8620 ID = Intrinsic::ppc_vsx_lxvl; 8621 break; 8622 case PPC::BI__builtin_vsx_lxvll: 8623 ID = Intrinsic::ppc_vsx_lxvll; 8624 break; 8625 } 8626 llvm::Function *F = CGM.getIntrinsic(ID); 8627 return Builder.CreateCall(F, Ops, ""); 8628 } 8629 8630 // vec_st, vec_xst_be 8631 case PPC::BI__builtin_altivec_stvx: 8632 case PPC::BI__builtin_altivec_stvxl: 8633 case PPC::BI__builtin_altivec_stvebx: 8634 case PPC::BI__builtin_altivec_stvehx: 8635 case PPC::BI__builtin_altivec_stvewx: 8636 case PPC::BI__builtin_vsx_stxvd2x: 8637 case PPC::BI__builtin_vsx_stxvw4x: 8638 case PPC::BI__builtin_vsx_stxvd2x_be: 8639 case PPC::BI__builtin_vsx_stxvw4x_be: 8640 case PPC::BI__builtin_vsx_stxvl: 8641 case PPC::BI__builtin_vsx_stxvll: 8642 { 8643 if(BuiltinID == PPC::BI__builtin_vsx_stxvl || 8644 BuiltinID == PPC::BI__builtin_vsx_stxvll ){ 8645 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8646 }else { 8647 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 8648 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 8649 Ops.pop_back(); 8650 } 8651 8652 switch (BuiltinID) { 8653 default: llvm_unreachable("Unsupported st intrinsic!"); 8654 case PPC::BI__builtin_altivec_stvx: 8655 ID = Intrinsic::ppc_altivec_stvx; 8656 break; 8657 case PPC::BI__builtin_altivec_stvxl: 8658 ID = Intrinsic::ppc_altivec_stvxl; 8659 break; 8660 case PPC::BI__builtin_altivec_stvebx: 8661 ID = Intrinsic::ppc_altivec_stvebx; 8662 break; 8663 case PPC::BI__builtin_altivec_stvehx: 8664 ID = Intrinsic::ppc_altivec_stvehx; 8665 break; 8666 case PPC::BI__builtin_altivec_stvewx: 8667 ID = Intrinsic::ppc_altivec_stvewx; 8668 break; 8669 case PPC::BI__builtin_vsx_stxvd2x: 8670 ID = Intrinsic::ppc_vsx_stxvd2x; 8671 break; 8672 case PPC::BI__builtin_vsx_stxvw4x: 8673 ID = Intrinsic::ppc_vsx_stxvw4x; 8674 break; 8675 case PPC::BI__builtin_vsx_stxvd2x_be: 8676 ID = Intrinsic::ppc_vsx_stxvd2x_be; 8677 break; 8678 case PPC::BI__builtin_vsx_stxvw4x_be: 8679 ID = Intrinsic::ppc_vsx_stxvw4x_be; 8680 break; 8681 case PPC::BI__builtin_vsx_stxvl: 8682 ID = Intrinsic::ppc_vsx_stxvl; 8683 break; 8684 case PPC::BI__builtin_vsx_stxvll: 8685 ID = Intrinsic::ppc_vsx_stxvll; 8686 break; 8687 } 8688 llvm::Function *F = CGM.getIntrinsic(ID); 8689 return Builder.CreateCall(F, Ops, ""); 8690 } 8691 // Square root 8692 case PPC::BI__builtin_vsx_xvsqrtsp: 8693 case PPC::BI__builtin_vsx_xvsqrtdp: { 8694 llvm::Type *ResultType = ConvertType(E->getType()); 8695 Value *X = EmitScalarExpr(E->getArg(0)); 8696 ID = Intrinsic::sqrt; 8697 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8698 return Builder.CreateCall(F, X); 8699 } 8700 // Count leading zeros 8701 case PPC::BI__builtin_altivec_vclzb: 8702 case PPC::BI__builtin_altivec_vclzh: 8703 case PPC::BI__builtin_altivec_vclzw: 8704 case PPC::BI__builtin_altivec_vclzd: { 8705 llvm::Type *ResultType = ConvertType(E->getType()); 8706 Value *X = EmitScalarExpr(E->getArg(0)); 8707 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8708 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 8709 return Builder.CreateCall(F, {X, Undef}); 8710 } 8711 case PPC::BI__builtin_altivec_vctzb: 8712 case PPC::BI__builtin_altivec_vctzh: 8713 case PPC::BI__builtin_altivec_vctzw: 8714 case PPC::BI__builtin_altivec_vctzd: { 8715 llvm::Type *ResultType = ConvertType(E->getType()); 8716 Value *X = EmitScalarExpr(E->getArg(0)); 8717 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8718 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 8719 return Builder.CreateCall(F, {X, Undef}); 8720 } 8721 case PPC::BI__builtin_altivec_vpopcntb: 8722 case PPC::BI__builtin_altivec_vpopcnth: 8723 case PPC::BI__builtin_altivec_vpopcntw: 8724 case PPC::BI__builtin_altivec_vpopcntd: { 8725 llvm::Type *ResultType = ConvertType(E->getType()); 8726 Value *X = EmitScalarExpr(E->getArg(0)); 8727 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 8728 return Builder.CreateCall(F, X); 8729 } 8730 // Copy sign 8731 case PPC::BI__builtin_vsx_xvcpsgnsp: 8732 case PPC::BI__builtin_vsx_xvcpsgndp: { 8733 llvm::Type *ResultType = ConvertType(E->getType()); 8734 Value *X = EmitScalarExpr(E->getArg(0)); 8735 Value *Y = EmitScalarExpr(E->getArg(1)); 8736 ID = Intrinsic::copysign; 8737 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8738 return Builder.CreateCall(F, {X, Y}); 8739 } 8740 // Rounding/truncation 8741 case PPC::BI__builtin_vsx_xvrspip: 8742 case PPC::BI__builtin_vsx_xvrdpip: 8743 case PPC::BI__builtin_vsx_xvrdpim: 8744 case PPC::BI__builtin_vsx_xvrspim: 8745 case PPC::BI__builtin_vsx_xvrdpi: 8746 case PPC::BI__builtin_vsx_xvrspi: 8747 case PPC::BI__builtin_vsx_xvrdpic: 8748 case PPC::BI__builtin_vsx_xvrspic: 8749 case PPC::BI__builtin_vsx_xvrdpiz: 8750 case PPC::BI__builtin_vsx_xvrspiz: { 8751 llvm::Type *ResultType = ConvertType(E->getType()); 8752 Value *X = EmitScalarExpr(E->getArg(0)); 8753 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim || 8754 BuiltinID == PPC::BI__builtin_vsx_xvrspim) 8755 ID = Intrinsic::floor; 8756 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi || 8757 BuiltinID == PPC::BI__builtin_vsx_xvrspi) 8758 ID = Intrinsic::round; 8759 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic || 8760 BuiltinID == PPC::BI__builtin_vsx_xvrspic) 8761 ID = Intrinsic::nearbyint; 8762 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip || 8763 BuiltinID == PPC::BI__builtin_vsx_xvrspip) 8764 ID = Intrinsic::ceil; 8765 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz || 8766 BuiltinID == PPC::BI__builtin_vsx_xvrspiz) 8767 ID = Intrinsic::trunc; 8768 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8769 return Builder.CreateCall(F, X); 8770 } 8771 8772 // Absolute value 8773 case PPC::BI__builtin_vsx_xvabsdp: 8774 case PPC::BI__builtin_vsx_xvabssp: { 8775 llvm::Type *ResultType = ConvertType(E->getType()); 8776 Value *X = EmitScalarExpr(E->getArg(0)); 8777 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 8778 return Builder.CreateCall(F, X); 8779 } 8780 8781 // FMA variations 8782 case PPC::BI__builtin_vsx_xvmaddadp: 8783 case PPC::BI__builtin_vsx_xvmaddasp: 8784 case PPC::BI__builtin_vsx_xvnmaddadp: 8785 case PPC::BI__builtin_vsx_xvnmaddasp: 8786 case PPC::BI__builtin_vsx_xvmsubadp: 8787 case PPC::BI__builtin_vsx_xvmsubasp: 8788 case PPC::BI__builtin_vsx_xvnmsubadp: 8789 case PPC::BI__builtin_vsx_xvnmsubasp: { 8790 llvm::Type *ResultType = ConvertType(E->getType()); 8791 Value *X = EmitScalarExpr(E->getArg(0)); 8792 Value *Y = EmitScalarExpr(E->getArg(1)); 8793 Value *Z = EmitScalarExpr(E->getArg(2)); 8794 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 8795 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 8796 switch (BuiltinID) { 8797 case PPC::BI__builtin_vsx_xvmaddadp: 8798 case PPC::BI__builtin_vsx_xvmaddasp: 8799 return Builder.CreateCall(F, {X, Y, Z}); 8800 case PPC::BI__builtin_vsx_xvnmaddadp: 8801 case PPC::BI__builtin_vsx_xvnmaddasp: 8802 return Builder.CreateFSub(Zero, 8803 Builder.CreateCall(F, {X, Y, Z}), "sub"); 8804 case PPC::BI__builtin_vsx_xvmsubadp: 8805 case PPC::BI__builtin_vsx_xvmsubasp: 8806 return Builder.CreateCall(F, 8807 {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8808 case PPC::BI__builtin_vsx_xvnmsubadp: 8809 case PPC::BI__builtin_vsx_xvnmsubasp: 8810 Value *FsubRes = 8811 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8812 return Builder.CreateFSub(Zero, FsubRes, "sub"); 8813 } 8814 llvm_unreachable("Unknown FMA operation"); 8815 return nullptr; // Suppress no-return warning 8816 } 8817 8818 case PPC::BI__builtin_vsx_insertword: { 8819 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw); 8820 8821 // Third argument is a compile time constant int. It must be clamped to 8822 // to the range [0, 12]. 8823 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8824 assert(ArgCI && 8825 "Third arg to xxinsertw intrinsic must be constant integer"); 8826 const int64_t MaxIndex = 12; 8827 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8828 8829 // The builtin semantics don't exactly match the xxinsertw instructions 8830 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the 8831 // word from the first argument, and inserts it in the second argument. The 8832 // instruction extracts the word from its second input register and inserts 8833 // it into its first input register, so swap the first and second arguments. 8834 std::swap(Ops[0], Ops[1]); 8835 8836 // Need to cast the second argument from a vector of unsigned int to a 8837 // vector of long long. 8838 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8839 8840 if (getTarget().isLittleEndian()) { 8841 // Create a shuffle mask of (1, 0) 8842 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8843 ConstantInt::get(Int32Ty, 0) 8844 }; 8845 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8846 8847 // Reverse the double words in the vector we will extract from. 8848 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8849 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask); 8850 8851 // Reverse the index. 8852 Index = MaxIndex - Index; 8853 } 8854 8855 // Intrinsic expects the first arg to be a vector of int. 8856 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8857 Ops[2] = ConstantInt::getSigned(Int32Ty, Index); 8858 return Builder.CreateCall(F, Ops); 8859 } 8860 8861 case PPC::BI__builtin_vsx_extractuword: { 8862 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw); 8863 8864 // Intrinsic expects the first argument to be a vector of doublewords. 8865 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8866 8867 // The second argument is a compile time constant int that needs to 8868 // be clamped to the range [0, 12]. 8869 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]); 8870 assert(ArgCI && 8871 "Second Arg to xxextractuw intrinsic must be a constant integer!"); 8872 const int64_t MaxIndex = 12; 8873 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8874 8875 if (getTarget().isLittleEndian()) { 8876 // Reverse the index. 8877 Index = MaxIndex - Index; 8878 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8879 8880 // Emit the call, then reverse the double words of the results vector. 8881 Value *Call = Builder.CreateCall(F, Ops); 8882 8883 // Create a shuffle mask of (1, 0) 8884 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8885 ConstantInt::get(Int32Ty, 0) 8886 }; 8887 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8888 8889 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask); 8890 return ShuffleCall; 8891 } else { 8892 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8893 return Builder.CreateCall(F, Ops); 8894 } 8895 } 8896 8897 case PPC::BI__builtin_vsx_xxpermdi: { 8898 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8899 assert(ArgCI && "Third arg must be constant integer!"); 8900 8901 unsigned Index = ArgCI->getZExtValue(); 8902 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8903 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8904 8905 // Element zero comes from the first input vector and element one comes from 8906 // the second. The element indices within each vector are numbered in big 8907 // endian order so the shuffle mask must be adjusted for this on little 8908 // endian platforms (i.e. index is complemented and source vector reversed). 8909 unsigned ElemIdx0; 8910 unsigned ElemIdx1; 8911 if (getTarget().isLittleEndian()) { 8912 ElemIdx0 = (~Index & 1) + 2; 8913 ElemIdx1 = (~Index & 2) >> 1; 8914 } else { // BigEndian 8915 ElemIdx0 = (Index & 2) >> 1; 8916 ElemIdx1 = 2 + (Index & 1); 8917 } 8918 8919 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0), 8920 ConstantInt::get(Int32Ty, ElemIdx1)}; 8921 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8922 8923 Value *ShuffleCall = 8924 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8925 QualType BIRetType = E->getType(); 8926 auto RetTy = ConvertType(BIRetType); 8927 return Builder.CreateBitCast(ShuffleCall, RetTy); 8928 } 8929 8930 case PPC::BI__builtin_vsx_xxsldwi: { 8931 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8932 assert(ArgCI && "Third argument must be a compile time constant"); 8933 unsigned Index = ArgCI->getZExtValue() & 0x3; 8934 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8935 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4)); 8936 8937 // Create a shuffle mask 8938 unsigned ElemIdx0; 8939 unsigned ElemIdx1; 8940 unsigned ElemIdx2; 8941 unsigned ElemIdx3; 8942 if (getTarget().isLittleEndian()) { 8943 // Little endian element N comes from element 8+N-Index of the 8944 // concatenated wide vector (of course, using modulo arithmetic on 8945 // the total number of elements). 8946 ElemIdx0 = (8 - Index) % 8; 8947 ElemIdx1 = (9 - Index) % 8; 8948 ElemIdx2 = (10 - Index) % 8; 8949 ElemIdx3 = (11 - Index) % 8; 8950 } else { 8951 // Big endian ElemIdx<N> = Index + N 8952 ElemIdx0 = Index; 8953 ElemIdx1 = Index + 1; 8954 ElemIdx2 = Index + 2; 8955 ElemIdx3 = Index + 3; 8956 } 8957 8958 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0), 8959 ConstantInt::get(Int32Ty, ElemIdx1), 8960 ConstantInt::get(Int32Ty, ElemIdx2), 8961 ConstantInt::get(Int32Ty, ElemIdx3)}; 8962 8963 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8964 Value *ShuffleCall = 8965 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8966 QualType BIRetType = E->getType(); 8967 auto RetTy = ConvertType(BIRetType); 8968 return Builder.CreateBitCast(ShuffleCall, RetTy); 8969 } 8970 } 8971 } 8972 8973 Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, 8974 const CallExpr *E) { 8975 switch (BuiltinID) { 8976 case AMDGPU::BI__builtin_amdgcn_div_scale: 8977 case AMDGPU::BI__builtin_amdgcn_div_scalef: { 8978 // Translate from the intrinsics's struct return to the builtin's out 8979 // argument. 8980 8981 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3)); 8982 8983 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 8984 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 8985 llvm::Value *Z = EmitScalarExpr(E->getArg(2)); 8986 8987 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale, 8988 X->getType()); 8989 8990 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z}); 8991 8992 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0); 8993 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1); 8994 8995 llvm::Type *RealFlagType 8996 = FlagOutPtr.getPointer()->getType()->getPointerElementType(); 8997 8998 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType); 8999 Builder.CreateStore(FlagExt, FlagOutPtr); 9000 return Result; 9001 } 9002 case AMDGPU::BI__builtin_amdgcn_div_fmas: 9003 case AMDGPU::BI__builtin_amdgcn_div_fmasf: { 9004 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0)); 9005 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1)); 9006 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2)); 9007 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3)); 9008 9009 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas, 9010 Src0->getType()); 9011 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3); 9012 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool}); 9013 } 9014 9015 case AMDGPU::BI__builtin_amdgcn_ds_swizzle: 9016 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle); 9017 case AMDGPU::BI__builtin_amdgcn_mov_dpp: { 9018 llvm::SmallVector<llvm::Value *, 5> Args; 9019 for (unsigned I = 0; I != 5; ++I) 9020 Args.push_back(EmitScalarExpr(E->getArg(I))); 9021 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp, 9022 Args[0]->getType()); 9023 return Builder.CreateCall(F, Args); 9024 } 9025 case AMDGPU::BI__builtin_amdgcn_div_fixup: 9026 case AMDGPU::BI__builtin_amdgcn_div_fixupf: 9027 case AMDGPU::BI__builtin_amdgcn_div_fixuph: 9028 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup); 9029 case AMDGPU::BI__builtin_amdgcn_trig_preop: 9030 case AMDGPU::BI__builtin_amdgcn_trig_preopf: 9031 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop); 9032 case AMDGPU::BI__builtin_amdgcn_rcp: 9033 case AMDGPU::BI__builtin_amdgcn_rcpf: 9034 case AMDGPU::BI__builtin_amdgcn_rcph: 9035 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp); 9036 case AMDGPU::BI__builtin_amdgcn_rsq: 9037 case AMDGPU::BI__builtin_amdgcn_rsqf: 9038 case AMDGPU::BI__builtin_amdgcn_rsqh: 9039 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq); 9040 case AMDGPU::BI__builtin_amdgcn_rsq_clamp: 9041 case AMDGPU::BI__builtin_amdgcn_rsq_clampf: 9042 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp); 9043 case AMDGPU::BI__builtin_amdgcn_sinf: 9044 case AMDGPU::BI__builtin_amdgcn_sinh: 9045 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin); 9046 case AMDGPU::BI__builtin_amdgcn_cosf: 9047 case AMDGPU::BI__builtin_amdgcn_cosh: 9048 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos); 9049 case AMDGPU::BI__builtin_amdgcn_log_clampf: 9050 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp); 9051 case AMDGPU::BI__builtin_amdgcn_ldexp: 9052 case AMDGPU::BI__builtin_amdgcn_ldexpf: 9053 case AMDGPU::BI__builtin_amdgcn_ldexph: 9054 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp); 9055 case AMDGPU::BI__builtin_amdgcn_frexp_mant: 9056 case AMDGPU::BI__builtin_amdgcn_frexp_mantf: 9057 case AMDGPU::BI__builtin_amdgcn_frexp_manth: 9058 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant); 9059 case AMDGPU::BI__builtin_amdgcn_frexp_exp: 9060 case AMDGPU::BI__builtin_amdgcn_frexp_expf: { 9061 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9062 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9063 { Builder.getInt32Ty(), Src0->getType() }); 9064 return Builder.CreateCall(F, Src0); 9065 } 9066 case AMDGPU::BI__builtin_amdgcn_frexp_exph: { 9067 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9068 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9069 { Builder.getInt16Ty(), Src0->getType() }); 9070 return Builder.CreateCall(F, Src0); 9071 } 9072 case AMDGPU::BI__builtin_amdgcn_fract: 9073 case AMDGPU::BI__builtin_amdgcn_fractf: 9074 case AMDGPU::BI__builtin_amdgcn_fracth: 9075 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract); 9076 case AMDGPU::BI__builtin_amdgcn_lerp: 9077 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp); 9078 case AMDGPU::BI__builtin_amdgcn_uicmp: 9079 case AMDGPU::BI__builtin_amdgcn_uicmpl: 9080 case AMDGPU::BI__builtin_amdgcn_sicmp: 9081 case AMDGPU::BI__builtin_amdgcn_sicmpl: 9082 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp); 9083 case AMDGPU::BI__builtin_amdgcn_fcmp: 9084 case AMDGPU::BI__builtin_amdgcn_fcmpf: 9085 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp); 9086 case AMDGPU::BI__builtin_amdgcn_class: 9087 case AMDGPU::BI__builtin_amdgcn_classf: 9088 case AMDGPU::BI__builtin_amdgcn_classh: 9089 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class); 9090 case AMDGPU::BI__builtin_amdgcn_fmed3f: 9091 case AMDGPU::BI__builtin_amdgcn_fmed3h: 9092 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3); 9093 case AMDGPU::BI__builtin_amdgcn_read_exec: { 9094 CallInst *CI = cast<CallInst>( 9095 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec")); 9096 CI->setConvergent(); 9097 return CI; 9098 } 9099 case AMDGPU::BI__builtin_amdgcn_read_exec_lo: 9100 case AMDGPU::BI__builtin_amdgcn_read_exec_hi: { 9101 StringRef RegName = BuiltinID == AMDGPU::BI__builtin_amdgcn_read_exec_lo ? 9102 "exec_lo" : "exec_hi"; 9103 CallInst *CI = cast<CallInst>( 9104 EmitSpecialRegisterBuiltin(*this, E, Int32Ty, Int32Ty, true, RegName)); 9105 CI->setConvergent(); 9106 return CI; 9107 } 9108 9109 // amdgcn workitem 9110 case AMDGPU::BI__builtin_amdgcn_workitem_id_x: 9111 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024); 9112 case AMDGPU::BI__builtin_amdgcn_workitem_id_y: 9113 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024); 9114 case AMDGPU::BI__builtin_amdgcn_workitem_id_z: 9115 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024); 9116 9117 // r600 intrinsics 9118 case AMDGPU::BI__builtin_r600_recipsqrt_ieee: 9119 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef: 9120 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee); 9121 case AMDGPU::BI__builtin_r600_read_tidig_x: 9122 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024); 9123 case AMDGPU::BI__builtin_r600_read_tidig_y: 9124 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024); 9125 case AMDGPU::BI__builtin_r600_read_tidig_z: 9126 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024); 9127 default: 9128 return nullptr; 9129 } 9130 } 9131 9132 /// Handle a SystemZ function in which the final argument is a pointer 9133 /// to an int that receives the post-instruction CC value. At the LLVM level 9134 /// this is represented as a function that returns a {result, cc} pair. 9135 static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF, 9136 unsigned IntrinsicID, 9137 const CallExpr *E) { 9138 unsigned NumArgs = E->getNumArgs() - 1; 9139 SmallVector<Value *, 8> Args(NumArgs); 9140 for (unsigned I = 0; I < NumArgs; ++I) 9141 Args[I] = CGF.EmitScalarExpr(E->getArg(I)); 9142 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs)); 9143 Value *F = CGF.CGM.getIntrinsic(IntrinsicID); 9144 Value *Call = CGF.Builder.CreateCall(F, Args); 9145 Value *CC = CGF.Builder.CreateExtractValue(Call, 1); 9146 CGF.Builder.CreateStore(CC, CCPtr); 9147 return CGF.Builder.CreateExtractValue(Call, 0); 9148 } 9149 9150 Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, 9151 const CallExpr *E) { 9152 switch (BuiltinID) { 9153 case SystemZ::BI__builtin_tbegin: { 9154 Value *TDB = EmitScalarExpr(E->getArg(0)); 9155 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9156 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin); 9157 return Builder.CreateCall(F, {TDB, Control}); 9158 } 9159 case SystemZ::BI__builtin_tbegin_nofloat: { 9160 Value *TDB = EmitScalarExpr(E->getArg(0)); 9161 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9162 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat); 9163 return Builder.CreateCall(F, {TDB, Control}); 9164 } 9165 case SystemZ::BI__builtin_tbeginc: { 9166 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy); 9167 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08); 9168 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc); 9169 return Builder.CreateCall(F, {TDB, Control}); 9170 } 9171 case SystemZ::BI__builtin_tabort: { 9172 Value *Data = EmitScalarExpr(E->getArg(0)); 9173 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort); 9174 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort")); 9175 } 9176 case SystemZ::BI__builtin_non_tx_store: { 9177 Value *Address = EmitScalarExpr(E->getArg(0)); 9178 Value *Data = EmitScalarExpr(E->getArg(1)); 9179 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); 9180 return Builder.CreateCall(F, {Data, Address}); 9181 } 9182 9183 // Vector builtins. Note that most vector builtins are mapped automatically 9184 // to target-specific LLVM intrinsics. The ones handled specially here can 9185 // be represented via standard LLVM IR, which is preferable to enable common 9186 // LLVM optimizations. 9187 9188 case SystemZ::BI__builtin_s390_vpopctb: 9189 case SystemZ::BI__builtin_s390_vpopcth: 9190 case SystemZ::BI__builtin_s390_vpopctf: 9191 case SystemZ::BI__builtin_s390_vpopctg: { 9192 llvm::Type *ResultType = ConvertType(E->getType()); 9193 Value *X = EmitScalarExpr(E->getArg(0)); 9194 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 9195 return Builder.CreateCall(F, X); 9196 } 9197 9198 case SystemZ::BI__builtin_s390_vclzb: 9199 case SystemZ::BI__builtin_s390_vclzh: 9200 case SystemZ::BI__builtin_s390_vclzf: 9201 case SystemZ::BI__builtin_s390_vclzg: { 9202 llvm::Type *ResultType = ConvertType(E->getType()); 9203 Value *X = EmitScalarExpr(E->getArg(0)); 9204 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9205 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 9206 return Builder.CreateCall(F, {X, Undef}); 9207 } 9208 9209 case SystemZ::BI__builtin_s390_vctzb: 9210 case SystemZ::BI__builtin_s390_vctzh: 9211 case SystemZ::BI__builtin_s390_vctzf: 9212 case SystemZ::BI__builtin_s390_vctzg: { 9213 llvm::Type *ResultType = ConvertType(E->getType()); 9214 Value *X = EmitScalarExpr(E->getArg(0)); 9215 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9216 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 9217 return Builder.CreateCall(F, {X, Undef}); 9218 } 9219 9220 case SystemZ::BI__builtin_s390_vfsqsb: 9221 case SystemZ::BI__builtin_s390_vfsqdb: { 9222 llvm::Type *ResultType = ConvertType(E->getType()); 9223 Value *X = EmitScalarExpr(E->getArg(0)); 9224 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType); 9225 return Builder.CreateCall(F, X); 9226 } 9227 case SystemZ::BI__builtin_s390_vfmasb: 9228 case SystemZ::BI__builtin_s390_vfmadb: { 9229 llvm::Type *ResultType = ConvertType(E->getType()); 9230 Value *X = EmitScalarExpr(E->getArg(0)); 9231 Value *Y = EmitScalarExpr(E->getArg(1)); 9232 Value *Z = EmitScalarExpr(E->getArg(2)); 9233 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9234 return Builder.CreateCall(F, {X, Y, Z}); 9235 } 9236 case SystemZ::BI__builtin_s390_vfmssb: 9237 case SystemZ::BI__builtin_s390_vfmsdb: { 9238 llvm::Type *ResultType = ConvertType(E->getType()); 9239 Value *X = EmitScalarExpr(E->getArg(0)); 9240 Value *Y = EmitScalarExpr(E->getArg(1)); 9241 Value *Z = EmitScalarExpr(E->getArg(2)); 9242 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9243 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9244 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 9245 } 9246 case SystemZ::BI__builtin_s390_vfnmasb: 9247 case SystemZ::BI__builtin_s390_vfnmadb: { 9248 llvm::Type *ResultType = ConvertType(E->getType()); 9249 Value *X = EmitScalarExpr(E->getArg(0)); 9250 Value *Y = EmitScalarExpr(E->getArg(1)); 9251 Value *Z = EmitScalarExpr(E->getArg(2)); 9252 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9253 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9254 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub"); 9255 } 9256 case SystemZ::BI__builtin_s390_vfnmssb: 9257 case SystemZ::BI__builtin_s390_vfnmsdb: { 9258 llvm::Type *ResultType = ConvertType(E->getType()); 9259 Value *X = EmitScalarExpr(E->getArg(0)); 9260 Value *Y = EmitScalarExpr(E->getArg(1)); 9261 Value *Z = EmitScalarExpr(E->getArg(2)); 9262 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9263 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9264 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub"); 9265 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ})); 9266 } 9267 case SystemZ::BI__builtin_s390_vflpsb: 9268 case SystemZ::BI__builtin_s390_vflpdb: { 9269 llvm::Type *ResultType = ConvertType(E->getType()); 9270 Value *X = EmitScalarExpr(E->getArg(0)); 9271 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9272 return Builder.CreateCall(F, X); 9273 } 9274 case SystemZ::BI__builtin_s390_vflnsb: 9275 case SystemZ::BI__builtin_s390_vflndb: { 9276 llvm::Type *ResultType = ConvertType(E->getType()); 9277 Value *X = EmitScalarExpr(E->getArg(0)); 9278 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9279 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9280 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub"); 9281 } 9282 case SystemZ::BI__builtin_s390_vfisb: 9283 case SystemZ::BI__builtin_s390_vfidb: { 9284 llvm::Type *ResultType = ConvertType(E->getType()); 9285 Value *X = EmitScalarExpr(E->getArg(0)); 9286 // Constant-fold the M4 and M5 mask arguments. 9287 llvm::APSInt M4, M5; 9288 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext()); 9289 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext()); 9290 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?"); 9291 (void)IsConstM4; (void)IsConstM5; 9292 // Check whether this instance can be represented via a LLVM standard 9293 // intrinsic. We only support some combinations of M4 and M5. 9294 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9295 switch (M4.getZExtValue()) { 9296 default: break; 9297 case 0: // IEEE-inexact exception allowed 9298 switch (M5.getZExtValue()) { 9299 default: break; 9300 case 0: ID = Intrinsic::rint; break; 9301 } 9302 break; 9303 case 4: // IEEE-inexact exception suppressed 9304 switch (M5.getZExtValue()) { 9305 default: break; 9306 case 0: ID = Intrinsic::nearbyint; break; 9307 case 1: ID = Intrinsic::round; break; 9308 case 5: ID = Intrinsic::trunc; break; 9309 case 6: ID = Intrinsic::ceil; break; 9310 case 7: ID = Intrinsic::floor; break; 9311 } 9312 break; 9313 } 9314 if (ID != Intrinsic::not_intrinsic) { 9315 Function *F = CGM.getIntrinsic(ID, ResultType); 9316 return Builder.CreateCall(F, X); 9317 } 9318 switch (BuiltinID) { 9319 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break; 9320 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break; 9321 default: llvm_unreachable("Unknown BuiltinID"); 9322 } 9323 Function *F = CGM.getIntrinsic(ID); 9324 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9325 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5); 9326 return Builder.CreateCall(F, {X, M4Value, M5Value}); 9327 } 9328 case SystemZ::BI__builtin_s390_vfmaxsb: 9329 case SystemZ::BI__builtin_s390_vfmaxdb: { 9330 llvm::Type *ResultType = ConvertType(E->getType()); 9331 Value *X = EmitScalarExpr(E->getArg(0)); 9332 Value *Y = EmitScalarExpr(E->getArg(1)); 9333 // Constant-fold the M4 mask argument. 9334 llvm::APSInt M4; 9335 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9336 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9337 (void)IsConstM4; 9338 // Check whether this instance can be represented via a LLVM standard 9339 // intrinsic. We only support some values of M4. 9340 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9341 switch (M4.getZExtValue()) { 9342 default: break; 9343 case 4: ID = Intrinsic::maxnum; break; 9344 } 9345 if (ID != Intrinsic::not_intrinsic) { 9346 Function *F = CGM.getIntrinsic(ID, ResultType); 9347 return Builder.CreateCall(F, {X, Y}); 9348 } 9349 switch (BuiltinID) { 9350 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break; 9351 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break; 9352 default: llvm_unreachable("Unknown BuiltinID"); 9353 } 9354 Function *F = CGM.getIntrinsic(ID); 9355 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9356 return Builder.CreateCall(F, {X, Y, M4Value}); 9357 } 9358 case SystemZ::BI__builtin_s390_vfminsb: 9359 case SystemZ::BI__builtin_s390_vfmindb: { 9360 llvm::Type *ResultType = ConvertType(E->getType()); 9361 Value *X = EmitScalarExpr(E->getArg(0)); 9362 Value *Y = EmitScalarExpr(E->getArg(1)); 9363 // Constant-fold the M4 mask argument. 9364 llvm::APSInt M4; 9365 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9366 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9367 (void)IsConstM4; 9368 // Check whether this instance can be represented via a LLVM standard 9369 // intrinsic. We only support some values of M4. 9370 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9371 switch (M4.getZExtValue()) { 9372 default: break; 9373 case 4: ID = Intrinsic::minnum; break; 9374 } 9375 if (ID != Intrinsic::not_intrinsic) { 9376 Function *F = CGM.getIntrinsic(ID, ResultType); 9377 return Builder.CreateCall(F, {X, Y}); 9378 } 9379 switch (BuiltinID) { 9380 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break; 9381 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break; 9382 default: llvm_unreachable("Unknown BuiltinID"); 9383 } 9384 Function *F = CGM.getIntrinsic(ID); 9385 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9386 return Builder.CreateCall(F, {X, Y, M4Value}); 9387 } 9388 9389 // Vector intrisincs that output the post-instruction CC value. 9390 9391 #define INTRINSIC_WITH_CC(NAME) \ 9392 case SystemZ::BI__builtin_##NAME: \ 9393 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E) 9394 9395 INTRINSIC_WITH_CC(s390_vpkshs); 9396 INTRINSIC_WITH_CC(s390_vpksfs); 9397 INTRINSIC_WITH_CC(s390_vpksgs); 9398 9399 INTRINSIC_WITH_CC(s390_vpklshs); 9400 INTRINSIC_WITH_CC(s390_vpklsfs); 9401 INTRINSIC_WITH_CC(s390_vpklsgs); 9402 9403 INTRINSIC_WITH_CC(s390_vceqbs); 9404 INTRINSIC_WITH_CC(s390_vceqhs); 9405 INTRINSIC_WITH_CC(s390_vceqfs); 9406 INTRINSIC_WITH_CC(s390_vceqgs); 9407 9408 INTRINSIC_WITH_CC(s390_vchbs); 9409 INTRINSIC_WITH_CC(s390_vchhs); 9410 INTRINSIC_WITH_CC(s390_vchfs); 9411 INTRINSIC_WITH_CC(s390_vchgs); 9412 9413 INTRINSIC_WITH_CC(s390_vchlbs); 9414 INTRINSIC_WITH_CC(s390_vchlhs); 9415 INTRINSIC_WITH_CC(s390_vchlfs); 9416 INTRINSIC_WITH_CC(s390_vchlgs); 9417 9418 INTRINSIC_WITH_CC(s390_vfaebs); 9419 INTRINSIC_WITH_CC(s390_vfaehs); 9420 INTRINSIC_WITH_CC(s390_vfaefs); 9421 9422 INTRINSIC_WITH_CC(s390_vfaezbs); 9423 INTRINSIC_WITH_CC(s390_vfaezhs); 9424 INTRINSIC_WITH_CC(s390_vfaezfs); 9425 9426 INTRINSIC_WITH_CC(s390_vfeebs); 9427 INTRINSIC_WITH_CC(s390_vfeehs); 9428 INTRINSIC_WITH_CC(s390_vfeefs); 9429 9430 INTRINSIC_WITH_CC(s390_vfeezbs); 9431 INTRINSIC_WITH_CC(s390_vfeezhs); 9432 INTRINSIC_WITH_CC(s390_vfeezfs); 9433 9434 INTRINSIC_WITH_CC(s390_vfenebs); 9435 INTRINSIC_WITH_CC(s390_vfenehs); 9436 INTRINSIC_WITH_CC(s390_vfenefs); 9437 9438 INTRINSIC_WITH_CC(s390_vfenezbs); 9439 INTRINSIC_WITH_CC(s390_vfenezhs); 9440 INTRINSIC_WITH_CC(s390_vfenezfs); 9441 9442 INTRINSIC_WITH_CC(s390_vistrbs); 9443 INTRINSIC_WITH_CC(s390_vistrhs); 9444 INTRINSIC_WITH_CC(s390_vistrfs); 9445 9446 INTRINSIC_WITH_CC(s390_vstrcbs); 9447 INTRINSIC_WITH_CC(s390_vstrchs); 9448 INTRINSIC_WITH_CC(s390_vstrcfs); 9449 9450 INTRINSIC_WITH_CC(s390_vstrczbs); 9451 INTRINSIC_WITH_CC(s390_vstrczhs); 9452 INTRINSIC_WITH_CC(s390_vstrczfs); 9453 9454 INTRINSIC_WITH_CC(s390_vfcesbs); 9455 INTRINSIC_WITH_CC(s390_vfcedbs); 9456 INTRINSIC_WITH_CC(s390_vfchsbs); 9457 INTRINSIC_WITH_CC(s390_vfchdbs); 9458 INTRINSIC_WITH_CC(s390_vfchesbs); 9459 INTRINSIC_WITH_CC(s390_vfchedbs); 9460 9461 INTRINSIC_WITH_CC(s390_vftcisb); 9462 INTRINSIC_WITH_CC(s390_vftcidb); 9463 9464 #undef INTRINSIC_WITH_CC 9465 9466 default: 9467 return nullptr; 9468 } 9469 } 9470 9471 Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, 9472 const CallExpr *E) { 9473 auto MakeLdg = [&](unsigned IntrinsicID) { 9474 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9475 clang::CharUnits Align = 9476 getNaturalPointeeTypeAlignment(E->getArg(0)->getType()); 9477 return Builder.CreateCall( 9478 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9479 Ptr->getType()}), 9480 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())}); 9481 }; 9482 auto MakeScopedAtomic = [&](unsigned IntrinsicID) { 9483 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9484 return Builder.CreateCall( 9485 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9486 Ptr->getType()}), 9487 {Ptr, EmitScalarExpr(E->getArg(1))}); 9488 }; 9489 switch (BuiltinID) { 9490 case NVPTX::BI__nvvm_atom_add_gen_i: 9491 case NVPTX::BI__nvvm_atom_add_gen_l: 9492 case NVPTX::BI__nvvm_atom_add_gen_ll: 9493 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E); 9494 9495 case NVPTX::BI__nvvm_atom_sub_gen_i: 9496 case NVPTX::BI__nvvm_atom_sub_gen_l: 9497 case NVPTX::BI__nvvm_atom_sub_gen_ll: 9498 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E); 9499 9500 case NVPTX::BI__nvvm_atom_and_gen_i: 9501 case NVPTX::BI__nvvm_atom_and_gen_l: 9502 case NVPTX::BI__nvvm_atom_and_gen_ll: 9503 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E); 9504 9505 case NVPTX::BI__nvvm_atom_or_gen_i: 9506 case NVPTX::BI__nvvm_atom_or_gen_l: 9507 case NVPTX::BI__nvvm_atom_or_gen_ll: 9508 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E); 9509 9510 case NVPTX::BI__nvvm_atom_xor_gen_i: 9511 case NVPTX::BI__nvvm_atom_xor_gen_l: 9512 case NVPTX::BI__nvvm_atom_xor_gen_ll: 9513 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E); 9514 9515 case NVPTX::BI__nvvm_atom_xchg_gen_i: 9516 case NVPTX::BI__nvvm_atom_xchg_gen_l: 9517 case NVPTX::BI__nvvm_atom_xchg_gen_ll: 9518 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E); 9519 9520 case NVPTX::BI__nvvm_atom_max_gen_i: 9521 case NVPTX::BI__nvvm_atom_max_gen_l: 9522 case NVPTX::BI__nvvm_atom_max_gen_ll: 9523 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E); 9524 9525 case NVPTX::BI__nvvm_atom_max_gen_ui: 9526 case NVPTX::BI__nvvm_atom_max_gen_ul: 9527 case NVPTX::BI__nvvm_atom_max_gen_ull: 9528 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E); 9529 9530 case NVPTX::BI__nvvm_atom_min_gen_i: 9531 case NVPTX::BI__nvvm_atom_min_gen_l: 9532 case NVPTX::BI__nvvm_atom_min_gen_ll: 9533 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E); 9534 9535 case NVPTX::BI__nvvm_atom_min_gen_ui: 9536 case NVPTX::BI__nvvm_atom_min_gen_ul: 9537 case NVPTX::BI__nvvm_atom_min_gen_ull: 9538 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E); 9539 9540 case NVPTX::BI__nvvm_atom_cas_gen_i: 9541 case NVPTX::BI__nvvm_atom_cas_gen_l: 9542 case NVPTX::BI__nvvm_atom_cas_gen_ll: 9543 // __nvvm_atom_cas_gen_* should return the old value rather than the 9544 // success flag. 9545 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false); 9546 9547 case NVPTX::BI__nvvm_atom_add_gen_f: { 9548 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9549 Value *Val = EmitScalarExpr(E->getArg(1)); 9550 // atomicrmw only deals with integer arguments so we need to use 9551 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that. 9552 Value *FnALAF32 = 9553 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType()); 9554 return Builder.CreateCall(FnALAF32, {Ptr, Val}); 9555 } 9556 9557 case NVPTX::BI__nvvm_atom_inc_gen_ui: { 9558 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9559 Value *Val = EmitScalarExpr(E->getArg(1)); 9560 Value *FnALI32 = 9561 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType()); 9562 return Builder.CreateCall(FnALI32, {Ptr, Val}); 9563 } 9564 9565 case NVPTX::BI__nvvm_atom_dec_gen_ui: { 9566 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9567 Value *Val = EmitScalarExpr(E->getArg(1)); 9568 Value *FnALD32 = 9569 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType()); 9570 return Builder.CreateCall(FnALD32, {Ptr, Val}); 9571 } 9572 9573 case NVPTX::BI__nvvm_ldg_c: 9574 case NVPTX::BI__nvvm_ldg_c2: 9575 case NVPTX::BI__nvvm_ldg_c4: 9576 case NVPTX::BI__nvvm_ldg_s: 9577 case NVPTX::BI__nvvm_ldg_s2: 9578 case NVPTX::BI__nvvm_ldg_s4: 9579 case NVPTX::BI__nvvm_ldg_i: 9580 case NVPTX::BI__nvvm_ldg_i2: 9581 case NVPTX::BI__nvvm_ldg_i4: 9582 case NVPTX::BI__nvvm_ldg_l: 9583 case NVPTX::BI__nvvm_ldg_ll: 9584 case NVPTX::BI__nvvm_ldg_ll2: 9585 case NVPTX::BI__nvvm_ldg_uc: 9586 case NVPTX::BI__nvvm_ldg_uc2: 9587 case NVPTX::BI__nvvm_ldg_uc4: 9588 case NVPTX::BI__nvvm_ldg_us: 9589 case NVPTX::BI__nvvm_ldg_us2: 9590 case NVPTX::BI__nvvm_ldg_us4: 9591 case NVPTX::BI__nvvm_ldg_ui: 9592 case NVPTX::BI__nvvm_ldg_ui2: 9593 case NVPTX::BI__nvvm_ldg_ui4: 9594 case NVPTX::BI__nvvm_ldg_ul: 9595 case NVPTX::BI__nvvm_ldg_ull: 9596 case NVPTX::BI__nvvm_ldg_ull2: 9597 // PTX Interoperability section 2.2: "For a vector with an even number of 9598 // elements, its alignment is set to number of elements times the alignment 9599 // of its member: n*alignof(t)." 9600 return MakeLdg(Intrinsic::nvvm_ldg_global_i); 9601 case NVPTX::BI__nvvm_ldg_f: 9602 case NVPTX::BI__nvvm_ldg_f2: 9603 case NVPTX::BI__nvvm_ldg_f4: 9604 case NVPTX::BI__nvvm_ldg_d: 9605 case NVPTX::BI__nvvm_ldg_d2: 9606 return MakeLdg(Intrinsic::nvvm_ldg_global_f); 9607 9608 case NVPTX::BI__nvvm_atom_cta_add_gen_i: 9609 case NVPTX::BI__nvvm_atom_cta_add_gen_l: 9610 case NVPTX::BI__nvvm_atom_cta_add_gen_ll: 9611 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta); 9612 case NVPTX::BI__nvvm_atom_sys_add_gen_i: 9613 case NVPTX::BI__nvvm_atom_sys_add_gen_l: 9614 case NVPTX::BI__nvvm_atom_sys_add_gen_ll: 9615 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys); 9616 case NVPTX::BI__nvvm_atom_cta_add_gen_f: 9617 case NVPTX::BI__nvvm_atom_cta_add_gen_d: 9618 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta); 9619 case NVPTX::BI__nvvm_atom_sys_add_gen_f: 9620 case NVPTX::BI__nvvm_atom_sys_add_gen_d: 9621 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys); 9622 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i: 9623 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l: 9624 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll: 9625 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta); 9626 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i: 9627 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l: 9628 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll: 9629 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys); 9630 case NVPTX::BI__nvvm_atom_cta_max_gen_i: 9631 case NVPTX::BI__nvvm_atom_cta_max_gen_ui: 9632 case NVPTX::BI__nvvm_atom_cta_max_gen_l: 9633 case NVPTX::BI__nvvm_atom_cta_max_gen_ul: 9634 case NVPTX::BI__nvvm_atom_cta_max_gen_ll: 9635 case NVPTX::BI__nvvm_atom_cta_max_gen_ull: 9636 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta); 9637 case NVPTX::BI__nvvm_atom_sys_max_gen_i: 9638 case NVPTX::BI__nvvm_atom_sys_max_gen_ui: 9639 case NVPTX::BI__nvvm_atom_sys_max_gen_l: 9640 case NVPTX::BI__nvvm_atom_sys_max_gen_ul: 9641 case NVPTX::BI__nvvm_atom_sys_max_gen_ll: 9642 case NVPTX::BI__nvvm_atom_sys_max_gen_ull: 9643 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys); 9644 case NVPTX::BI__nvvm_atom_cta_min_gen_i: 9645 case NVPTX::BI__nvvm_atom_cta_min_gen_ui: 9646 case NVPTX::BI__nvvm_atom_cta_min_gen_l: 9647 case NVPTX::BI__nvvm_atom_cta_min_gen_ul: 9648 case NVPTX::BI__nvvm_atom_cta_min_gen_ll: 9649 case NVPTX::BI__nvvm_atom_cta_min_gen_ull: 9650 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta); 9651 case NVPTX::BI__nvvm_atom_sys_min_gen_i: 9652 case NVPTX::BI__nvvm_atom_sys_min_gen_ui: 9653 case NVPTX::BI__nvvm_atom_sys_min_gen_l: 9654 case NVPTX::BI__nvvm_atom_sys_min_gen_ul: 9655 case NVPTX::BI__nvvm_atom_sys_min_gen_ll: 9656 case NVPTX::BI__nvvm_atom_sys_min_gen_ull: 9657 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys); 9658 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui: 9659 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta); 9660 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui: 9661 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta); 9662 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui: 9663 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys); 9664 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui: 9665 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys); 9666 case NVPTX::BI__nvvm_atom_cta_and_gen_i: 9667 case NVPTX::BI__nvvm_atom_cta_and_gen_l: 9668 case NVPTX::BI__nvvm_atom_cta_and_gen_ll: 9669 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta); 9670 case NVPTX::BI__nvvm_atom_sys_and_gen_i: 9671 case NVPTX::BI__nvvm_atom_sys_and_gen_l: 9672 case NVPTX::BI__nvvm_atom_sys_and_gen_ll: 9673 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys); 9674 case NVPTX::BI__nvvm_atom_cta_or_gen_i: 9675 case NVPTX::BI__nvvm_atom_cta_or_gen_l: 9676 case NVPTX::BI__nvvm_atom_cta_or_gen_ll: 9677 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta); 9678 case NVPTX::BI__nvvm_atom_sys_or_gen_i: 9679 case NVPTX::BI__nvvm_atom_sys_or_gen_l: 9680 case NVPTX::BI__nvvm_atom_sys_or_gen_ll: 9681 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys); 9682 case NVPTX::BI__nvvm_atom_cta_xor_gen_i: 9683 case NVPTX::BI__nvvm_atom_cta_xor_gen_l: 9684 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll: 9685 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta); 9686 case NVPTX::BI__nvvm_atom_sys_xor_gen_i: 9687 case NVPTX::BI__nvvm_atom_sys_xor_gen_l: 9688 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll: 9689 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys); 9690 case NVPTX::BI__nvvm_atom_cta_cas_gen_i: 9691 case NVPTX::BI__nvvm_atom_cta_cas_gen_l: 9692 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: { 9693 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9694 return Builder.CreateCall( 9695 CGM.getIntrinsic( 9696 Intrinsic::nvvm_atomic_cas_gen_i_cta, 9697 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9698 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9699 } 9700 case NVPTX::BI__nvvm_atom_sys_cas_gen_i: 9701 case NVPTX::BI__nvvm_atom_sys_cas_gen_l: 9702 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: { 9703 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9704 return Builder.CreateCall( 9705 CGM.getIntrinsic( 9706 Intrinsic::nvvm_atomic_cas_gen_i_sys, 9707 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9708 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9709 } 9710 case NVPTX::BI__nvvm_match_all_sync_i32p: 9711 case NVPTX::BI__nvvm_match_all_sync_i64p: { 9712 Value *Mask = EmitScalarExpr(E->getArg(0)); 9713 Value *Val = EmitScalarExpr(E->getArg(1)); 9714 Address PredOutPtr = EmitPointerWithAlignment(E->getArg(2)); 9715 Value *ResultPair = Builder.CreateCall( 9716 CGM.getIntrinsic(BuiltinID == NVPTX::BI__nvvm_match_all_sync_i32p 9717 ? Intrinsic::nvvm_match_all_sync_i32p 9718 : Intrinsic::nvvm_match_all_sync_i64p), 9719 {Mask, Val}); 9720 Value *Pred = Builder.CreateZExt(Builder.CreateExtractValue(ResultPair, 1), 9721 PredOutPtr.getElementType()); 9722 Builder.CreateStore(Pred, PredOutPtr); 9723 return Builder.CreateExtractValue(ResultPair, 0); 9724 } 9725 case NVPTX::BI__hmma_m16n16k16_ld_a: 9726 case NVPTX::BI__hmma_m16n16k16_ld_b: 9727 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9728 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: { 9729 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9730 Value *Src = EmitScalarExpr(E->getArg(1)); 9731 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9732 llvm::APSInt isColMajorArg; 9733 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9734 return nullptr; 9735 bool isColMajor = isColMajorArg.getSExtValue(); 9736 unsigned IID; 9737 unsigned NumResults; 9738 switch (BuiltinID) { 9739 case NVPTX::BI__hmma_m16n16k16_ld_a: 9740 IID = isColMajor ? Intrinsic::nvvm_wmma_load_a_f16_col_stride 9741 : Intrinsic::nvvm_wmma_load_a_f16_row_stride; 9742 NumResults = 8; 9743 break; 9744 case NVPTX::BI__hmma_m16n16k16_ld_b: 9745 IID = isColMajor ? Intrinsic::nvvm_wmma_load_b_f16_col_stride 9746 : Intrinsic::nvvm_wmma_load_b_f16_row_stride; 9747 NumResults = 8; 9748 break; 9749 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9750 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f16_col_stride 9751 : Intrinsic::nvvm_wmma_load_c_f16_row_stride; 9752 NumResults = 4; 9753 break; 9754 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: 9755 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f32_col_stride 9756 : Intrinsic::nvvm_wmma_load_c_f32_row_stride; 9757 NumResults = 8; 9758 break; 9759 default: 9760 llvm_unreachable("Unexpected builtin ID."); 9761 } 9762 Value *Result = 9763 Builder.CreateCall(CGM.getIntrinsic(IID), 9764 {Builder.CreatePointerCast(Src, VoidPtrTy), Ldm}); 9765 9766 // Save returned values. 9767 for (unsigned i = 0; i < NumResults; ++i) { 9768 Builder.CreateAlignedStore( 9769 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), 9770 Dst.getElementType()), 9771 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9772 CharUnits::fromQuantity(4)); 9773 } 9774 return Result; 9775 } 9776 9777 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9778 case NVPTX::BI__hmma_m16n16k16_st_c_f32: { 9779 Value *Dst = EmitScalarExpr(E->getArg(0)); 9780 Address Src = EmitPointerWithAlignment(E->getArg(1)); 9781 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9782 llvm::APSInt isColMajorArg; 9783 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9784 return nullptr; 9785 bool isColMajor = isColMajorArg.getSExtValue(); 9786 unsigned IID; 9787 unsigned NumResults = 8; 9788 // PTX Instructions (and LLVM instrinsics) are defined for slice _d_, yet 9789 // for some reason nvcc builtins use _c_. 9790 switch (BuiltinID) { 9791 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9792 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f16_col_stride 9793 : Intrinsic::nvvm_wmma_store_d_f16_row_stride; 9794 NumResults = 4; 9795 break; 9796 case NVPTX::BI__hmma_m16n16k16_st_c_f32: 9797 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f32_col_stride 9798 : Intrinsic::nvvm_wmma_store_d_f32_row_stride; 9799 break; 9800 default: 9801 llvm_unreachable("Unexpected builtin ID."); 9802 } 9803 Function *Intrinsic = CGM.getIntrinsic(IID); 9804 llvm::Type *ParamType = Intrinsic->getFunctionType()->getParamType(1); 9805 SmallVector<Value *, 10> Values; 9806 Values.push_back(Builder.CreatePointerCast(Dst, VoidPtrTy)); 9807 for (unsigned i = 0; i < NumResults; ++i) { 9808 Value *V = Builder.CreateAlignedLoad( 9809 Builder.CreateGEP(Src.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9810 CharUnits::fromQuantity(4)); 9811 Values.push_back(Builder.CreateBitCast(V, ParamType)); 9812 } 9813 Values.push_back(Ldm); 9814 Value *Result = Builder.CreateCall(Intrinsic, Values); 9815 return Result; 9816 } 9817 9818 // BI__hmma_m16n16k16_mma_<Dtype><CType>(d, a, b, c, layout, satf) 9819 // --> Intrinsic::nvvm_wmma_mma_sync<layout A,B><DType><CType><Satf> 9820 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9821 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9822 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9823 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: { 9824 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9825 Address SrcA = EmitPointerWithAlignment(E->getArg(1)); 9826 Address SrcB = EmitPointerWithAlignment(E->getArg(2)); 9827 Address SrcC = EmitPointerWithAlignment(E->getArg(3)); 9828 llvm::APSInt LayoutArg; 9829 if (!E->getArg(4)->isIntegerConstantExpr(LayoutArg, getContext())) 9830 return nullptr; 9831 int Layout = LayoutArg.getSExtValue(); 9832 if (Layout < 0 || Layout > 3) 9833 return nullptr; 9834 llvm::APSInt SatfArg; 9835 if (!E->getArg(5)->isIntegerConstantExpr(SatfArg, getContext())) 9836 return nullptr; 9837 bool Satf = SatfArg.getSExtValue(); 9838 9839 // clang-format off 9840 #define MMA_VARIANTS(type) {{ \ 9841 Intrinsic::nvvm_wmma_mma_sync_row_row_##type, \ 9842 Intrinsic::nvvm_wmma_mma_sync_row_row_##type##_satfinite, \ 9843 Intrinsic::nvvm_wmma_mma_sync_row_col_##type, \ 9844 Intrinsic::nvvm_wmma_mma_sync_row_col_##type##_satfinite, \ 9845 Intrinsic::nvvm_wmma_mma_sync_col_row_##type, \ 9846 Intrinsic::nvvm_wmma_mma_sync_col_row_##type##_satfinite, \ 9847 Intrinsic::nvvm_wmma_mma_sync_col_col_##type, \ 9848 Intrinsic::nvvm_wmma_mma_sync_col_col_##type##_satfinite \ 9849 }} 9850 // clang-format on 9851 9852 auto getMMAIntrinsic = [Layout, Satf](std::array<unsigned, 8> Variants) { 9853 unsigned Index = Layout * 2 + Satf; 9854 assert(Index < 8); 9855 return Variants[Index]; 9856 }; 9857 unsigned IID; 9858 unsigned NumEltsC; 9859 unsigned NumEltsD; 9860 switch (BuiltinID) { 9861 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9862 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f16)); 9863 NumEltsC = 4; 9864 NumEltsD = 4; 9865 break; 9866 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9867 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f16)); 9868 NumEltsC = 4; 9869 NumEltsD = 8; 9870 break; 9871 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: 9872 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f32)); 9873 NumEltsC = 8; 9874 NumEltsD = 4; 9875 break; 9876 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9877 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f32)); 9878 NumEltsC = 8; 9879 NumEltsD = 8; 9880 break; 9881 default: 9882 llvm_unreachable("Unexpected builtin ID."); 9883 } 9884 #undef MMA_VARIANTS 9885 9886 SmallVector<Value *, 24> Values; 9887 Function *Intrinsic = CGM.getIntrinsic(IID); 9888 llvm::Type *ABType = Intrinsic->getFunctionType()->getParamType(0); 9889 // Load A 9890 for (unsigned i = 0; i < 8; ++i) { 9891 Value *V = Builder.CreateAlignedLoad( 9892 Builder.CreateGEP(SrcA.getPointer(), 9893 llvm::ConstantInt::get(IntTy, i)), 9894 CharUnits::fromQuantity(4)); 9895 Values.push_back(Builder.CreateBitCast(V, ABType)); 9896 } 9897 // Load B 9898 for (unsigned i = 0; i < 8; ++i) { 9899 Value *V = Builder.CreateAlignedLoad( 9900 Builder.CreateGEP(SrcB.getPointer(), 9901 llvm::ConstantInt::get(IntTy, i)), 9902 CharUnits::fromQuantity(4)); 9903 Values.push_back(Builder.CreateBitCast(V, ABType)); 9904 } 9905 // Load C 9906 llvm::Type *CType = Intrinsic->getFunctionType()->getParamType(16); 9907 for (unsigned i = 0; i < NumEltsC; ++i) { 9908 Value *V = Builder.CreateAlignedLoad( 9909 Builder.CreateGEP(SrcC.getPointer(), 9910 llvm::ConstantInt::get(IntTy, i)), 9911 CharUnits::fromQuantity(4)); 9912 Values.push_back(Builder.CreateBitCast(V, CType)); 9913 } 9914 Value *Result = Builder.CreateCall(Intrinsic, Values); 9915 llvm::Type *DType = Dst.getElementType(); 9916 for (unsigned i = 0; i < NumEltsD; ++i) 9917 Builder.CreateAlignedStore( 9918 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType), 9919 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9920 CharUnits::fromQuantity(4)); 9921 return Result; 9922 } 9923 default: 9924 return nullptr; 9925 } 9926 } 9927 9928 Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 9929 const CallExpr *E) { 9930 switch (BuiltinID) { 9931 case WebAssembly::BI__builtin_wasm_current_memory: { 9932 llvm::Type *ResultType = ConvertType(E->getType()); 9933 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType); 9934 return Builder.CreateCall(Callee); 9935 } 9936 case WebAssembly::BI__builtin_wasm_grow_memory: { 9937 Value *X = EmitScalarExpr(E->getArg(0)); 9938 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType()); 9939 return Builder.CreateCall(Callee, X); 9940 } 9941 case WebAssembly::BI__builtin_wasm_throw: { 9942 Value *Tag = EmitScalarExpr(E->getArg(0)); 9943 Value *Obj = EmitScalarExpr(E->getArg(1)); 9944 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw); 9945 return Builder.CreateCall(Callee, {Tag, Obj}); 9946 } 9947 case WebAssembly::BI__builtin_wasm_rethrow: { 9948 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow); 9949 return Builder.CreateCall(Callee); 9950 } 9951 9952 default: 9953 return nullptr; 9954 } 9955 } 9956