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(nullptr); 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 // A constant libcall or builtin is equivalent to the LLVM intrinsic. 2114 if (FD->hasAttr<ConstAttr>()) 2115 return RValue::get(emitTernaryBuiltin(*this, E, Intrinsic::fma)); 2116 break; 2117 2118 case Builtin::BI__builtin_signbit: 2119 case Builtin::BI__builtin_signbitf: 2120 case Builtin::BI__builtin_signbitl: { 2121 return RValue::get( 2122 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))), 2123 ConvertType(E->getType()))); 2124 } 2125 case Builtin::BI__annotation: { 2126 // Re-encode each wide string to UTF8 and make an MDString. 2127 SmallVector<Metadata *, 1> Strings; 2128 for (const Expr *Arg : E->arguments()) { 2129 const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts()); 2130 assert(Str->getCharByteWidth() == 2); 2131 StringRef WideBytes = Str->getBytes(); 2132 std::string StrUtf8; 2133 if (!convertUTF16ToUTF8String( 2134 makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) { 2135 CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument"); 2136 continue; 2137 } 2138 Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8)); 2139 } 2140 2141 // Build and MDTuple of MDStrings and emit the intrinsic call. 2142 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {}); 2143 MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings); 2144 Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple)); 2145 return RValue::getIgnored(); 2146 } 2147 case Builtin::BI__builtin_annotation: { 2148 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 2149 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 2150 AnnVal->getType()); 2151 2152 // Get the annotation string, go through casts. Sema requires this to be a 2153 // non-wide string literal, potentially casted, so the cast<> is safe. 2154 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 2155 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 2156 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 2157 } 2158 case Builtin::BI__builtin_addcb: 2159 case Builtin::BI__builtin_addcs: 2160 case Builtin::BI__builtin_addc: 2161 case Builtin::BI__builtin_addcl: 2162 case Builtin::BI__builtin_addcll: 2163 case Builtin::BI__builtin_subcb: 2164 case Builtin::BI__builtin_subcs: 2165 case Builtin::BI__builtin_subc: 2166 case Builtin::BI__builtin_subcl: 2167 case Builtin::BI__builtin_subcll: { 2168 2169 // We translate all of these builtins from expressions of the form: 2170 // int x = ..., y = ..., carryin = ..., carryout, result; 2171 // result = __builtin_addc(x, y, carryin, &carryout); 2172 // 2173 // to LLVM IR of the form: 2174 // 2175 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 2176 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 2177 // %carry1 = extractvalue {i32, i1} %tmp1, 1 2178 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 2179 // i32 %carryin) 2180 // %result = extractvalue {i32, i1} %tmp2, 0 2181 // %carry2 = extractvalue {i32, i1} %tmp2, 1 2182 // %tmp3 = or i1 %carry1, %carry2 2183 // %tmp4 = zext i1 %tmp3 to i32 2184 // store i32 %tmp4, i32* %carryout 2185 2186 // Scalarize our inputs. 2187 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2188 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2189 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 2190 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3)); 2191 2192 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 2193 llvm::Intrinsic::ID IntrinsicId; 2194 switch (BuiltinID) { 2195 default: llvm_unreachable("Unknown multiprecision builtin id."); 2196 case Builtin::BI__builtin_addcb: 2197 case Builtin::BI__builtin_addcs: 2198 case Builtin::BI__builtin_addc: 2199 case Builtin::BI__builtin_addcl: 2200 case Builtin::BI__builtin_addcll: 2201 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2202 break; 2203 case Builtin::BI__builtin_subcb: 2204 case Builtin::BI__builtin_subcs: 2205 case Builtin::BI__builtin_subc: 2206 case Builtin::BI__builtin_subcl: 2207 case Builtin::BI__builtin_subcll: 2208 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2209 break; 2210 } 2211 2212 // Construct our resulting LLVM IR expression. 2213 llvm::Value *Carry1; 2214 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 2215 X, Y, Carry1); 2216 llvm::Value *Carry2; 2217 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 2218 Sum1, Carryin, Carry2); 2219 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 2220 X->getType()); 2221 Builder.CreateStore(CarryOut, CarryOutPtr); 2222 return RValue::get(Sum2); 2223 } 2224 2225 case Builtin::BI__builtin_add_overflow: 2226 case Builtin::BI__builtin_sub_overflow: 2227 case Builtin::BI__builtin_mul_overflow: { 2228 const clang::Expr *LeftArg = E->getArg(0); 2229 const clang::Expr *RightArg = E->getArg(1); 2230 const clang::Expr *ResultArg = E->getArg(2); 2231 2232 clang::QualType ResultQTy = 2233 ResultArg->getType()->castAs<PointerType>()->getPointeeType(); 2234 2235 WidthAndSignedness LeftInfo = 2236 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType()); 2237 WidthAndSignedness RightInfo = 2238 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType()); 2239 WidthAndSignedness ResultInfo = 2240 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy); 2241 WidthAndSignedness EncompassingInfo = 2242 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo}); 2243 2244 llvm::Type *EncompassingLLVMTy = 2245 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width); 2246 2247 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy); 2248 2249 llvm::Intrinsic::ID IntrinsicId; 2250 switch (BuiltinID) { 2251 default: 2252 llvm_unreachable("Unknown overflow builtin id."); 2253 case Builtin::BI__builtin_add_overflow: 2254 IntrinsicId = EncompassingInfo.Signed 2255 ? llvm::Intrinsic::sadd_with_overflow 2256 : llvm::Intrinsic::uadd_with_overflow; 2257 break; 2258 case Builtin::BI__builtin_sub_overflow: 2259 IntrinsicId = EncompassingInfo.Signed 2260 ? llvm::Intrinsic::ssub_with_overflow 2261 : llvm::Intrinsic::usub_with_overflow; 2262 break; 2263 case Builtin::BI__builtin_mul_overflow: 2264 IntrinsicId = EncompassingInfo.Signed 2265 ? llvm::Intrinsic::smul_with_overflow 2266 : llvm::Intrinsic::umul_with_overflow; 2267 break; 2268 } 2269 2270 llvm::Value *Left = EmitScalarExpr(LeftArg); 2271 llvm::Value *Right = EmitScalarExpr(RightArg); 2272 Address ResultPtr = EmitPointerWithAlignment(ResultArg); 2273 2274 // Extend each operand to the encompassing type. 2275 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed); 2276 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed); 2277 2278 // Perform the operation on the extended values. 2279 llvm::Value *Overflow, *Result; 2280 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow); 2281 2282 if (EncompassingInfo.Width > ResultInfo.Width) { 2283 // The encompassing type is wider than the result type, so we need to 2284 // truncate it. 2285 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy); 2286 2287 // To see if the truncation caused an overflow, we will extend 2288 // the result and then compare it to the original result. 2289 llvm::Value *ResultTruncExt = Builder.CreateIntCast( 2290 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed); 2291 llvm::Value *TruncationOverflow = 2292 Builder.CreateICmpNE(Result, ResultTruncExt); 2293 2294 Overflow = Builder.CreateOr(Overflow, TruncationOverflow); 2295 Result = ResultTrunc; 2296 } 2297 2298 // Finally, store the result using the pointer. 2299 bool isVolatile = 2300 ResultArg->getType()->getPointeeType().isVolatileQualified(); 2301 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile); 2302 2303 return RValue::get(Overflow); 2304 } 2305 2306 case Builtin::BI__builtin_uadd_overflow: 2307 case Builtin::BI__builtin_uaddl_overflow: 2308 case Builtin::BI__builtin_uaddll_overflow: 2309 case Builtin::BI__builtin_usub_overflow: 2310 case Builtin::BI__builtin_usubl_overflow: 2311 case Builtin::BI__builtin_usubll_overflow: 2312 case Builtin::BI__builtin_umul_overflow: 2313 case Builtin::BI__builtin_umull_overflow: 2314 case Builtin::BI__builtin_umulll_overflow: 2315 case Builtin::BI__builtin_sadd_overflow: 2316 case Builtin::BI__builtin_saddl_overflow: 2317 case Builtin::BI__builtin_saddll_overflow: 2318 case Builtin::BI__builtin_ssub_overflow: 2319 case Builtin::BI__builtin_ssubl_overflow: 2320 case Builtin::BI__builtin_ssubll_overflow: 2321 case Builtin::BI__builtin_smul_overflow: 2322 case Builtin::BI__builtin_smull_overflow: 2323 case Builtin::BI__builtin_smulll_overflow: { 2324 2325 // We translate all of these builtins directly to the relevant llvm IR node. 2326 2327 // Scalarize our inputs. 2328 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2329 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2330 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2)); 2331 2332 // Decide which of the overflow intrinsics we are lowering to: 2333 llvm::Intrinsic::ID IntrinsicId; 2334 switch (BuiltinID) { 2335 default: llvm_unreachable("Unknown overflow builtin id."); 2336 case Builtin::BI__builtin_uadd_overflow: 2337 case Builtin::BI__builtin_uaddl_overflow: 2338 case Builtin::BI__builtin_uaddll_overflow: 2339 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2340 break; 2341 case Builtin::BI__builtin_usub_overflow: 2342 case Builtin::BI__builtin_usubl_overflow: 2343 case Builtin::BI__builtin_usubll_overflow: 2344 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2345 break; 2346 case Builtin::BI__builtin_umul_overflow: 2347 case Builtin::BI__builtin_umull_overflow: 2348 case Builtin::BI__builtin_umulll_overflow: 2349 IntrinsicId = llvm::Intrinsic::umul_with_overflow; 2350 break; 2351 case Builtin::BI__builtin_sadd_overflow: 2352 case Builtin::BI__builtin_saddl_overflow: 2353 case Builtin::BI__builtin_saddll_overflow: 2354 IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 2355 break; 2356 case Builtin::BI__builtin_ssub_overflow: 2357 case Builtin::BI__builtin_ssubl_overflow: 2358 case Builtin::BI__builtin_ssubll_overflow: 2359 IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 2360 break; 2361 case Builtin::BI__builtin_smul_overflow: 2362 case Builtin::BI__builtin_smull_overflow: 2363 case Builtin::BI__builtin_smulll_overflow: 2364 IntrinsicId = llvm::Intrinsic::smul_with_overflow; 2365 break; 2366 } 2367 2368 2369 llvm::Value *Carry; 2370 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 2371 Builder.CreateStore(Sum, SumOutPtr); 2372 2373 return RValue::get(Carry); 2374 } 2375 case Builtin::BI__builtin_addressof: 2376 return RValue::get(EmitLValue(E->getArg(0)).getPointer()); 2377 case Builtin::BI__builtin_operator_new: 2378 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2379 E->getArg(0), false); 2380 case Builtin::BI__builtin_operator_delete: 2381 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2382 E->getArg(0), true); 2383 case Builtin::BI__noop: 2384 // __noop always evaluates to an integer literal zero. 2385 return RValue::get(ConstantInt::get(IntTy, 0)); 2386 case Builtin::BI__builtin_call_with_static_chain: { 2387 const CallExpr *Call = cast<CallExpr>(E->getArg(0)); 2388 const Expr *Chain = E->getArg(1); 2389 return EmitCall(Call->getCallee()->getType(), 2390 EmitCallee(Call->getCallee()), Call, ReturnValue, 2391 EmitScalarExpr(Chain)); 2392 } 2393 case Builtin::BI_InterlockedExchange8: 2394 case Builtin::BI_InterlockedExchange16: 2395 case Builtin::BI_InterlockedExchange: 2396 case Builtin::BI_InterlockedExchangePointer: 2397 return RValue::get( 2398 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E)); 2399 case Builtin::BI_InterlockedCompareExchangePointer: { 2400 llvm::Type *RTy; 2401 llvm::IntegerType *IntType = 2402 IntegerType::get(getLLVMContext(), 2403 getContext().getTypeSize(E->getType())); 2404 llvm::Type *IntPtrType = IntType->getPointerTo(); 2405 2406 llvm::Value *Destination = 2407 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType); 2408 2409 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1)); 2410 RTy = Exchange->getType(); 2411 Exchange = Builder.CreatePtrToInt(Exchange, IntType); 2412 2413 llvm::Value *Comparand = 2414 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType); 2415 2416 auto Result = 2417 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange, 2418 AtomicOrdering::SequentiallyConsistent, 2419 AtomicOrdering::SequentiallyConsistent); 2420 Result->setVolatile(true); 2421 2422 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result, 2423 0), 2424 RTy)); 2425 } 2426 case Builtin::BI_InterlockedCompareExchange8: 2427 case Builtin::BI_InterlockedCompareExchange16: 2428 case Builtin::BI_InterlockedCompareExchange: 2429 case Builtin::BI_InterlockedCompareExchange64: { 2430 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg( 2431 EmitScalarExpr(E->getArg(0)), 2432 EmitScalarExpr(E->getArg(2)), 2433 EmitScalarExpr(E->getArg(1)), 2434 AtomicOrdering::SequentiallyConsistent, 2435 AtomicOrdering::SequentiallyConsistent); 2436 CXI->setVolatile(true); 2437 return RValue::get(Builder.CreateExtractValue(CXI, 0)); 2438 } 2439 case Builtin::BI_InterlockedIncrement16: 2440 case Builtin::BI_InterlockedIncrement: 2441 return RValue::get( 2442 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E)); 2443 case Builtin::BI_InterlockedDecrement16: 2444 case Builtin::BI_InterlockedDecrement: 2445 return RValue::get( 2446 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E)); 2447 case Builtin::BI_InterlockedAnd8: 2448 case Builtin::BI_InterlockedAnd16: 2449 case Builtin::BI_InterlockedAnd: 2450 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E)); 2451 case Builtin::BI_InterlockedExchangeAdd8: 2452 case Builtin::BI_InterlockedExchangeAdd16: 2453 case Builtin::BI_InterlockedExchangeAdd: 2454 return RValue::get( 2455 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E)); 2456 case Builtin::BI_InterlockedExchangeSub8: 2457 case Builtin::BI_InterlockedExchangeSub16: 2458 case Builtin::BI_InterlockedExchangeSub: 2459 return RValue::get( 2460 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E)); 2461 case Builtin::BI_InterlockedOr8: 2462 case Builtin::BI_InterlockedOr16: 2463 case Builtin::BI_InterlockedOr: 2464 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E)); 2465 case Builtin::BI_InterlockedXor8: 2466 case Builtin::BI_InterlockedXor16: 2467 case Builtin::BI_InterlockedXor: 2468 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E)); 2469 case Builtin::BI_interlockedbittestandset: 2470 return RValue::get( 2471 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E)); 2472 2473 case Builtin::BI__exception_code: 2474 case Builtin::BI_exception_code: 2475 return RValue::get(EmitSEHExceptionCode()); 2476 case Builtin::BI__exception_info: 2477 case Builtin::BI_exception_info: 2478 return RValue::get(EmitSEHExceptionInfo()); 2479 case Builtin::BI__abnormal_termination: 2480 case Builtin::BI_abnormal_termination: 2481 return RValue::get(EmitSEHAbnormalTermination()); 2482 case Builtin::BI_setjmpex: { 2483 if (getTarget().getTriple().isOSMSVCRT()) { 2484 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2485 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2486 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2487 llvm::Attribute::ReturnsTwice); 2488 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction( 2489 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2490 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true); 2491 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2492 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2493 llvm::Value *FrameAddr = 2494 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2495 ConstantInt::get(Int32Ty, 0)); 2496 llvm::Value *Args[] = {Buf, FrameAddr}; 2497 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args); 2498 CS.setAttributes(ReturnsTwiceAttr); 2499 return RValue::get(CS.getInstruction()); 2500 } 2501 break; 2502 } 2503 case Builtin::BI_setjmp: { 2504 if (getTarget().getTriple().isOSMSVCRT()) { 2505 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2506 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2507 llvm::Attribute::ReturnsTwice); 2508 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2509 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2510 llvm::CallSite CS; 2511 if (getTarget().getTriple().getArch() == llvm::Triple::x86) { 2512 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy}; 2513 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction( 2514 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true), 2515 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true); 2516 llvm::Value *Count = ConstantInt::get(IntTy, 0); 2517 llvm::Value *Args[] = {Buf, Count}; 2518 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args); 2519 } else { 2520 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2521 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( 2522 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2523 "_setjmp", ReturnsTwiceAttr, /*Local=*/true); 2524 llvm::Value *FrameAddr = 2525 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2526 ConstantInt::get(Int32Ty, 0)); 2527 llvm::Value *Args[] = {Buf, FrameAddr}; 2528 CS = EmitRuntimeCallOrInvoke(SetJmp, Args); 2529 } 2530 CS.setAttributes(ReturnsTwiceAttr); 2531 return RValue::get(CS.getInstruction()); 2532 } 2533 break; 2534 } 2535 2536 case Builtin::BI__GetExceptionInfo: { 2537 if (llvm::GlobalVariable *GV = 2538 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType())) 2539 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy)); 2540 break; 2541 } 2542 2543 case Builtin::BI__fastfail: 2544 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E)); 2545 2546 case Builtin::BI__builtin_coro_size: { 2547 auto & Context = getContext(); 2548 auto SizeTy = Context.getSizeType(); 2549 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy)); 2550 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T); 2551 return RValue::get(Builder.CreateCall(F)); 2552 } 2553 2554 case Builtin::BI__builtin_coro_id: 2555 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id); 2556 case Builtin::BI__builtin_coro_promise: 2557 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise); 2558 case Builtin::BI__builtin_coro_resume: 2559 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume); 2560 case Builtin::BI__builtin_coro_frame: 2561 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame); 2562 case Builtin::BI__builtin_coro_free: 2563 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free); 2564 case Builtin::BI__builtin_coro_destroy: 2565 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy); 2566 case Builtin::BI__builtin_coro_done: 2567 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done); 2568 case Builtin::BI__builtin_coro_alloc: 2569 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc); 2570 case Builtin::BI__builtin_coro_begin: 2571 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin); 2572 case Builtin::BI__builtin_coro_end: 2573 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end); 2574 case Builtin::BI__builtin_coro_suspend: 2575 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend); 2576 case Builtin::BI__builtin_coro_param: 2577 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param); 2578 2579 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions 2580 case Builtin::BIread_pipe: 2581 case Builtin::BIwrite_pipe: { 2582 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2583 *Arg1 = EmitScalarExpr(E->getArg(1)); 2584 CGOpenCLRuntime OpenCLRT(CGM); 2585 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2586 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2587 2588 // Type of the generic packet parameter. 2589 unsigned GenericAS = 2590 getContext().getTargetAddressSpace(LangAS::opencl_generic); 2591 llvm::Type *I8PTy = llvm::PointerType::get( 2592 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS); 2593 2594 // Testing which overloaded version we should generate the call for. 2595 if (2U == E->getNumArgs()) { 2596 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2" 2597 : "__write_pipe_2"; 2598 // Creating a generic function type to be able to call with any builtin or 2599 // user defined type. 2600 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty}; 2601 llvm::FunctionType *FTy = llvm::FunctionType::get( 2602 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2603 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy); 2604 return RValue::get( 2605 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2606 {Arg0, BCast, PacketSize, PacketAlign})); 2607 } else { 2608 assert(4 == E->getNumArgs() && 2609 "Illegal number of parameters to pipe function"); 2610 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4" 2611 : "__write_pipe_4"; 2612 2613 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy, 2614 Int32Ty, Int32Ty}; 2615 Value *Arg2 = EmitScalarExpr(E->getArg(2)), 2616 *Arg3 = EmitScalarExpr(E->getArg(3)); 2617 llvm::FunctionType *FTy = llvm::FunctionType::get( 2618 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2619 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy); 2620 // We know the third argument is an integer type, but we may need to cast 2621 // it to i32. 2622 if (Arg2->getType() != Int32Ty) 2623 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty); 2624 return RValue::get(Builder.CreateCall( 2625 CGM.CreateRuntimeFunction(FTy, Name), 2626 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign})); 2627 } 2628 } 2629 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write 2630 // functions 2631 case Builtin::BIreserve_read_pipe: 2632 case Builtin::BIreserve_write_pipe: 2633 case Builtin::BIwork_group_reserve_read_pipe: 2634 case Builtin::BIwork_group_reserve_write_pipe: 2635 case Builtin::BIsub_group_reserve_read_pipe: 2636 case Builtin::BIsub_group_reserve_write_pipe: { 2637 // Composing the mangled name for the function. 2638 const char *Name; 2639 if (BuiltinID == Builtin::BIreserve_read_pipe) 2640 Name = "__reserve_read_pipe"; 2641 else if (BuiltinID == Builtin::BIreserve_write_pipe) 2642 Name = "__reserve_write_pipe"; 2643 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe) 2644 Name = "__work_group_reserve_read_pipe"; 2645 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe) 2646 Name = "__work_group_reserve_write_pipe"; 2647 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe) 2648 Name = "__sub_group_reserve_read_pipe"; 2649 else 2650 Name = "__sub_group_reserve_write_pipe"; 2651 2652 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2653 *Arg1 = EmitScalarExpr(E->getArg(1)); 2654 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy); 2655 CGOpenCLRuntime OpenCLRT(CGM); 2656 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2657 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2658 2659 // Building the generic function prototype. 2660 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty}; 2661 llvm::FunctionType *FTy = llvm::FunctionType::get( 2662 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2663 // We know the second argument is an integer type, but we may need to cast 2664 // it to i32. 2665 if (Arg1->getType() != Int32Ty) 2666 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty); 2667 return RValue::get( 2668 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2669 {Arg0, Arg1, PacketSize, PacketAlign})); 2670 } 2671 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write 2672 // functions 2673 case Builtin::BIcommit_read_pipe: 2674 case Builtin::BIcommit_write_pipe: 2675 case Builtin::BIwork_group_commit_read_pipe: 2676 case Builtin::BIwork_group_commit_write_pipe: 2677 case Builtin::BIsub_group_commit_read_pipe: 2678 case Builtin::BIsub_group_commit_write_pipe: { 2679 const char *Name; 2680 if (BuiltinID == Builtin::BIcommit_read_pipe) 2681 Name = "__commit_read_pipe"; 2682 else if (BuiltinID == Builtin::BIcommit_write_pipe) 2683 Name = "__commit_write_pipe"; 2684 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe) 2685 Name = "__work_group_commit_read_pipe"; 2686 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe) 2687 Name = "__work_group_commit_write_pipe"; 2688 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe) 2689 Name = "__sub_group_commit_read_pipe"; 2690 else 2691 Name = "__sub_group_commit_write_pipe"; 2692 2693 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2694 *Arg1 = EmitScalarExpr(E->getArg(1)); 2695 CGOpenCLRuntime OpenCLRT(CGM); 2696 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2697 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2698 2699 // Building the generic function prototype. 2700 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty}; 2701 llvm::FunctionType *FTy = 2702 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 2703 llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2704 2705 return RValue::get( 2706 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2707 {Arg0, Arg1, PacketSize, PacketAlign})); 2708 } 2709 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions 2710 case Builtin::BIget_pipe_num_packets: 2711 case Builtin::BIget_pipe_max_packets: { 2712 const char *Name; 2713 if (BuiltinID == Builtin::BIget_pipe_num_packets) 2714 Name = "__get_pipe_num_packets"; 2715 else 2716 Name = "__get_pipe_max_packets"; 2717 2718 // Building the generic function prototype. 2719 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 2720 CGOpenCLRuntime OpenCLRT(CGM); 2721 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2722 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2723 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty}; 2724 llvm::FunctionType *FTy = llvm::FunctionType::get( 2725 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2726 2727 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2728 {Arg0, PacketSize, PacketAlign})); 2729 } 2730 2731 // OpenCL v2.0 s6.13.9 - Address space qualifier functions. 2732 case Builtin::BIto_global: 2733 case Builtin::BIto_local: 2734 case Builtin::BIto_private: { 2735 auto Arg0 = EmitScalarExpr(E->getArg(0)); 2736 auto NewArgT = llvm::PointerType::get(Int8Ty, 2737 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2738 auto NewRetT = llvm::PointerType::get(Int8Ty, 2739 CGM.getContext().getTargetAddressSpace( 2740 E->getType()->getPointeeType().getAddressSpace())); 2741 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false); 2742 llvm::Value *NewArg; 2743 if (Arg0->getType()->getPointerAddressSpace() != 2744 NewArgT->getPointerAddressSpace()) 2745 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT); 2746 else 2747 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT); 2748 auto NewName = std::string("__") + E->getDirectCallee()->getName().str(); 2749 auto NewCall = 2750 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg}); 2751 return RValue::get(Builder.CreateBitOrPointerCast(NewCall, 2752 ConvertType(E->getType()))); 2753 } 2754 2755 // OpenCL v2.0, s6.13.17 - Enqueue kernel function. 2756 // It contains four different overload formats specified in Table 6.13.17.1. 2757 case Builtin::BIenqueue_kernel: { 2758 StringRef Name; // Generated function call name 2759 unsigned NumArgs = E->getNumArgs(); 2760 2761 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy); 2762 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2763 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2764 2765 llvm::Value *Queue = EmitScalarExpr(E->getArg(0)); 2766 llvm::Value *Flags = EmitScalarExpr(E->getArg(1)); 2767 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2)); 2768 llvm::Value *Range = NDRangeL.getAddress().getPointer(); 2769 llvm::Type *RangeTy = NDRangeL.getAddress().getType(); 2770 2771 if (NumArgs == 4) { 2772 // The most basic form of the call with parameters: 2773 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void) 2774 Name = "__enqueue_kernel_basic"; 2775 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy, 2776 GenericVoidPtrTy}; 2777 llvm::FunctionType *FTy = llvm::FunctionType::get( 2778 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2779 2780 auto Info = 2781 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2782 llvm::Value *Kernel = 2783 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2784 llvm::Value *Block = 2785 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2786 2787 AttrBuilder B; 2788 B.addAttribute(Attribute::ByVal); 2789 llvm::AttributeList ByValAttrSet = 2790 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B); 2791 2792 auto RTCall = 2793 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet), 2794 {Queue, Flags, Range, Kernel, Block}); 2795 RTCall->setAttributes(ByValAttrSet); 2796 return RValue::get(RTCall); 2797 } 2798 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature"); 2799 2800 // Create a temporary array to hold the sizes of local pointer arguments 2801 // for the block. \p First is the position of the first size argument. 2802 auto CreateArrayForSizeVar = [=](unsigned First) { 2803 auto *AT = llvm::ArrayType::get(SizeTy, NumArgs - First); 2804 auto *Arr = Builder.CreateAlloca(AT); 2805 llvm::Value *Ptr; 2806 // Each of the following arguments specifies the size of the corresponding 2807 // argument passed to the enqueued block. 2808 auto *Zero = llvm::ConstantInt::get(IntTy, 0); 2809 for (unsigned I = First; I < NumArgs; ++I) { 2810 auto *Index = llvm::ConstantInt::get(IntTy, I - First); 2811 auto *GEP = Builder.CreateGEP(Arr, {Zero, Index}); 2812 if (I == First) 2813 Ptr = GEP; 2814 auto *V = 2815 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy); 2816 Builder.CreateAlignedStore( 2817 V, GEP, CGM.getDataLayout().getPrefTypeAlignment(SizeTy)); 2818 } 2819 return Ptr; 2820 }; 2821 2822 // Could have events and/or vaargs. 2823 if (E->getArg(3)->getType()->isBlockPointerType()) { 2824 // No events passed, but has variadic arguments. 2825 Name = "__enqueue_kernel_vaargs"; 2826 auto Info = 2827 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2828 llvm::Value *Kernel = 2829 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2830 auto *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2831 auto *PtrToSizeArray = CreateArrayForSizeVar(4); 2832 2833 // Create a vector of the arguments, as well as a constant value to 2834 // express to the runtime the number of variadic arguments. 2835 std::vector<llvm::Value *> Args = { 2836 Queue, Flags, Range, 2837 Kernel, Block, ConstantInt::get(IntTy, NumArgs - 4), 2838 PtrToSizeArray}; 2839 std::vector<llvm::Type *> ArgTys = { 2840 QueueTy, IntTy, RangeTy, 2841 GenericVoidPtrTy, GenericVoidPtrTy, IntTy, 2842 PtrToSizeArray->getType()}; 2843 2844 llvm::FunctionType *FTy = llvm::FunctionType::get( 2845 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2846 return RValue::get( 2847 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2848 llvm::ArrayRef<llvm::Value *>(Args))); 2849 } 2850 // Any calls now have event arguments passed. 2851 if (NumArgs >= 7) { 2852 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy); 2853 llvm::Type *EventPtrTy = EventTy->getPointerTo( 2854 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2855 2856 llvm::Value *NumEvents = 2857 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty); 2858 llvm::Value *EventList = 2859 E->getArg(4)->getType()->isArrayType() 2860 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer() 2861 : EmitScalarExpr(E->getArg(4)); 2862 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5)); 2863 // Convert to generic address space. 2864 EventList = Builder.CreatePointerCast(EventList, EventPtrTy); 2865 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy); 2866 auto Info = 2867 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(6)); 2868 llvm::Value *Kernel = 2869 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2870 llvm::Value *Block = 2871 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2872 2873 std::vector<llvm::Type *> ArgTys = { 2874 QueueTy, Int32Ty, RangeTy, Int32Ty, 2875 EventPtrTy, EventPtrTy, GenericVoidPtrTy, GenericVoidPtrTy}; 2876 2877 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents, 2878 EventList, ClkEvent, Kernel, Block}; 2879 2880 if (NumArgs == 7) { 2881 // Has events but no variadics. 2882 Name = "__enqueue_kernel_basic_events"; 2883 llvm::FunctionType *FTy = llvm::FunctionType::get( 2884 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2885 return RValue::get( 2886 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2887 llvm::ArrayRef<llvm::Value *>(Args))); 2888 } 2889 // Has event info and variadics 2890 // Pass the number of variadics to the runtime function too. 2891 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7)); 2892 ArgTys.push_back(Int32Ty); 2893 Name = "__enqueue_kernel_events_vaargs"; 2894 2895 auto *PtrToSizeArray = CreateArrayForSizeVar(7); 2896 Args.push_back(PtrToSizeArray); 2897 ArgTys.push_back(PtrToSizeArray->getType()); 2898 2899 llvm::FunctionType *FTy = llvm::FunctionType::get( 2900 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2901 return RValue::get( 2902 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2903 llvm::ArrayRef<llvm::Value *>(Args))); 2904 } 2905 LLVM_FALLTHROUGH; 2906 } 2907 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block 2908 // parameter. 2909 case Builtin::BIget_kernel_work_group_size: { 2910 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2911 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2912 auto Info = 2913 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 2914 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2915 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2916 return RValue::get(Builder.CreateCall( 2917 CGM.CreateRuntimeFunction( 2918 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 2919 false), 2920 "__get_kernel_work_group_size_impl"), 2921 {Kernel, Arg})); 2922 } 2923 case Builtin::BIget_kernel_preferred_work_group_size_multiple: { 2924 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2925 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2926 auto Info = 2927 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 2928 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2929 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2930 return RValue::get(Builder.CreateCall( 2931 CGM.CreateRuntimeFunction( 2932 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 2933 false), 2934 "__get_kernel_preferred_work_group_multiple_impl"), 2935 {Kernel, Arg})); 2936 } 2937 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange: 2938 case Builtin::BIget_kernel_sub_group_count_for_ndrange: { 2939 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2940 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2941 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0)); 2942 llvm::Value *NDRange = NDRangeL.getAddress().getPointer(); 2943 auto Info = 2944 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(1)); 2945 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2946 Value *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2947 const char *Name = 2948 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange 2949 ? "__get_kernel_max_sub_group_size_for_ndrange_impl" 2950 : "__get_kernel_sub_group_count_for_ndrange_impl"; 2951 return RValue::get(Builder.CreateCall( 2952 CGM.CreateRuntimeFunction( 2953 llvm::FunctionType::get( 2954 IntTy, {NDRange->getType(), GenericVoidPtrTy, GenericVoidPtrTy}, 2955 false), 2956 Name), 2957 {NDRange, Kernel, Block})); 2958 } 2959 2960 case Builtin::BI__builtin_store_half: 2961 case Builtin::BI__builtin_store_halff: { 2962 Value *Val = EmitScalarExpr(E->getArg(0)); 2963 Address Address = EmitPointerWithAlignment(E->getArg(1)); 2964 Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy()); 2965 return RValue::get(Builder.CreateStore(HalfVal, Address)); 2966 } 2967 case Builtin::BI__builtin_load_half: { 2968 Address Address = EmitPointerWithAlignment(E->getArg(0)); 2969 Value *HalfVal = Builder.CreateLoad(Address); 2970 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy())); 2971 } 2972 case Builtin::BI__builtin_load_halff: { 2973 Address Address = EmitPointerWithAlignment(E->getArg(0)); 2974 Value *HalfVal = Builder.CreateLoad(Address); 2975 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy())); 2976 } 2977 case Builtin::BIprintf: 2978 if (getTarget().getTriple().isNVPTX()) 2979 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue); 2980 break; 2981 case Builtin::BI__builtin_canonicalize: 2982 case Builtin::BI__builtin_canonicalizef: 2983 case Builtin::BI__builtin_canonicalizel: 2984 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize)); 2985 2986 case Builtin::BI__builtin_thread_pointer: { 2987 if (!getContext().getTargetInfo().isTLSSupported()) 2988 CGM.ErrorUnsupported(E, "__builtin_thread_pointer"); 2989 // Fall through - it's already mapped to the intrinsic by GCCBuiltin. 2990 break; 2991 } 2992 case Builtin::BI__builtin_os_log_format: 2993 return emitBuiltinOSLogFormat(*E); 2994 2995 case Builtin::BI__builtin_os_log_format_buffer_size: { 2996 analyze_os_log::OSLogBufferLayout Layout; 2997 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); 2998 return RValue::get(ConstantInt::get(ConvertType(E->getType()), 2999 Layout.size().getQuantity())); 3000 } 3001 3002 case Builtin::BI__xray_customevent: { 3003 if (!ShouldXRayInstrumentFunction()) 3004 return RValue::getIgnored(); 3005 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) { 3006 if (XRayAttr->neverXRayInstrument()) 3007 return RValue::getIgnored(); 3008 } 3009 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent); 3010 auto FTy = F->getFunctionType(); 3011 auto Arg0 = E->getArg(0); 3012 auto Arg0Val = EmitScalarExpr(Arg0); 3013 auto Arg0Ty = Arg0->getType(); 3014 auto PTy0 = FTy->getParamType(0); 3015 if (PTy0 != Arg0Val->getType()) { 3016 if (Arg0Ty->isArrayType()) 3017 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer(); 3018 else 3019 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0); 3020 } 3021 auto Arg1 = EmitScalarExpr(E->getArg(1)); 3022 auto PTy1 = FTy->getParamType(1); 3023 if (PTy1 != Arg1->getType()) 3024 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1); 3025 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1})); 3026 } 3027 3028 case Builtin::BI__builtin_ms_va_start: 3029 case Builtin::BI__builtin_ms_va_end: 3030 return RValue::get( 3031 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(), 3032 BuiltinID == Builtin::BI__builtin_ms_va_start)); 3033 3034 case Builtin::BI__builtin_ms_va_copy: { 3035 // Lower this manually. We can't reliably determine whether or not any 3036 // given va_copy() is for a Win64 va_list from the calling convention 3037 // alone, because it's legal to do this from a System V ABI function. 3038 // With opaque pointer types, we won't have enough information in LLVM 3039 // IR to determine this from the argument types, either. Best to do it 3040 // now, while we have enough information. 3041 Address DestAddr = EmitMSVAListRef(E->getArg(0)); 3042 Address SrcAddr = EmitMSVAListRef(E->getArg(1)); 3043 3044 llvm::Type *BPP = Int8PtrPtrTy; 3045 3046 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"), 3047 DestAddr.getAlignment()); 3048 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"), 3049 SrcAddr.getAlignment()); 3050 3051 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); 3052 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr)); 3053 } 3054 } 3055 3056 // If this is an alias for a lib function (e.g. __builtin_sin), emit 3057 // the call using the normal call path, but using the unmangled 3058 // version of the function name. 3059 if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 3060 return emitLibraryCall(*this, FD, E, 3061 CGM.getBuiltinLibFunction(FD, BuiltinID)); 3062 3063 // If this is a predefined lib function (e.g. malloc), emit the call 3064 // using exactly the normal call path. 3065 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 3066 return emitLibraryCall(*this, FD, E, 3067 cast<llvm::Constant>(EmitScalarExpr(E->getCallee()))); 3068 3069 // Check that a call to a target specific builtin has the correct target 3070 // features. 3071 // This is down here to avoid non-target specific builtins, however, if 3072 // generic builtins start to require generic target features then we 3073 // can move this up to the beginning of the function. 3074 checkTargetFeatures(E, FD); 3075 3076 // See if we have a target specific intrinsic. 3077 const char *Name = getContext().BuiltinInfo.getName(BuiltinID); 3078 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 3079 StringRef Prefix = 3080 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); 3081 if (!Prefix.empty()) { 3082 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name); 3083 // NOTE we dont need to perform a compatibility flag check here since the 3084 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the 3085 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. 3086 if (IntrinsicID == Intrinsic::not_intrinsic) 3087 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name); 3088 } 3089 3090 if (IntrinsicID != Intrinsic::not_intrinsic) { 3091 SmallVector<Value*, 16> Args; 3092 3093 // Find out if any arguments are required to be integer constant 3094 // expressions. 3095 unsigned ICEArguments = 0; 3096 ASTContext::GetBuiltinTypeError Error; 3097 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 3098 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 3099 3100 Function *F = CGM.getIntrinsic(IntrinsicID); 3101 llvm::FunctionType *FTy = F->getFunctionType(); 3102 3103 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 3104 Value *ArgValue; 3105 // If this is a normal argument, just emit it as a scalar. 3106 if ((ICEArguments & (1 << i)) == 0) { 3107 ArgValue = EmitScalarExpr(E->getArg(i)); 3108 } else { 3109 // If this is required to be a constant, constant fold it so that we 3110 // know that the generated intrinsic gets a ConstantInt. 3111 llvm::APSInt Result; 3112 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 3113 assert(IsConst && "Constant arg isn't actually constant?"); 3114 (void)IsConst; 3115 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 3116 } 3117 3118 // If the intrinsic arg type is different from the builtin arg type 3119 // we need to do a bit cast. 3120 llvm::Type *PTy = FTy->getParamType(i); 3121 if (PTy != ArgValue->getType()) { 3122 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 3123 "Must be able to losslessly bit cast to param"); 3124 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 3125 } 3126 3127 Args.push_back(ArgValue); 3128 } 3129 3130 Value *V = Builder.CreateCall(F, Args); 3131 QualType BuiltinRetType = E->getType(); 3132 3133 llvm::Type *RetTy = VoidTy; 3134 if (!BuiltinRetType->isVoidType()) 3135 RetTy = ConvertType(BuiltinRetType); 3136 3137 if (RetTy != V->getType()) { 3138 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 3139 "Must be able to losslessly bit cast result type"); 3140 V = Builder.CreateBitCast(V, RetTy); 3141 } 3142 3143 return RValue::get(V); 3144 } 3145 3146 // See if we have a target specific builtin that needs to be lowered. 3147 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 3148 return RValue::get(V); 3149 3150 ErrorUnsupported(E, "builtin function"); 3151 3152 // Unknown builtin, for now just dump it out and return undef. 3153 return GetUndefRValue(E->getType()); 3154 } 3155 3156 static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, 3157 unsigned BuiltinID, const CallExpr *E, 3158 llvm::Triple::ArchType Arch) { 3159 switch (Arch) { 3160 case llvm::Triple::arm: 3161 case llvm::Triple::armeb: 3162 case llvm::Triple::thumb: 3163 case llvm::Triple::thumbeb: 3164 return CGF->EmitARMBuiltinExpr(BuiltinID, E); 3165 case llvm::Triple::aarch64: 3166 case llvm::Triple::aarch64_be: 3167 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E); 3168 case llvm::Triple::x86: 3169 case llvm::Triple::x86_64: 3170 return CGF->EmitX86BuiltinExpr(BuiltinID, E); 3171 case llvm::Triple::ppc: 3172 case llvm::Triple::ppc64: 3173 case llvm::Triple::ppc64le: 3174 return CGF->EmitPPCBuiltinExpr(BuiltinID, E); 3175 case llvm::Triple::r600: 3176 case llvm::Triple::amdgcn: 3177 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E); 3178 case llvm::Triple::systemz: 3179 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E); 3180 case llvm::Triple::nvptx: 3181 case llvm::Triple::nvptx64: 3182 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E); 3183 case llvm::Triple::wasm32: 3184 case llvm::Triple::wasm64: 3185 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E); 3186 default: 3187 return nullptr; 3188 } 3189 } 3190 3191 Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 3192 const CallExpr *E) { 3193 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { 3194 assert(getContext().getAuxTargetInfo() && "Missing aux target info"); 3195 return EmitTargetArchBuiltinExpr( 3196 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E, 3197 getContext().getAuxTargetInfo()->getTriple().getArch()); 3198 } 3199 3200 return EmitTargetArchBuiltinExpr(this, BuiltinID, E, 3201 getTarget().getTriple().getArch()); 3202 } 3203 3204 static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 3205 NeonTypeFlags TypeFlags, 3206 bool V1Ty=false) { 3207 int IsQuad = TypeFlags.isQuad(); 3208 switch (TypeFlags.getEltType()) { 3209 case NeonTypeFlags::Int8: 3210 case NeonTypeFlags::Poly8: 3211 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); 3212 case NeonTypeFlags::Int16: 3213 case NeonTypeFlags::Poly16: 3214 case NeonTypeFlags::Float16: 3215 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); 3216 case NeonTypeFlags::Int32: 3217 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); 3218 case NeonTypeFlags::Int64: 3219 case NeonTypeFlags::Poly64: 3220 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad)); 3221 case NeonTypeFlags::Poly128: 3222 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm. 3223 // There is a lot of i128 and f128 API missing. 3224 // so we use v16i8 to represent poly128 and get pattern matched. 3225 return llvm::VectorType::get(CGF->Int8Ty, 16); 3226 case NeonTypeFlags::Float32: 3227 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); 3228 case NeonTypeFlags::Float64: 3229 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad)); 3230 } 3231 llvm_unreachable("Unknown vector element type!"); 3232 } 3233 3234 static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF, 3235 NeonTypeFlags IntTypeFlags) { 3236 int IsQuad = IntTypeFlags.isQuad(); 3237 switch (IntTypeFlags.getEltType()) { 3238 case NeonTypeFlags::Int32: 3239 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad)); 3240 case NeonTypeFlags::Int64: 3241 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad)); 3242 default: 3243 llvm_unreachable("Type can't be converted to floating-point!"); 3244 } 3245 } 3246 3247 Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 3248 unsigned nElts = V->getType()->getVectorNumElements(); 3249 Value* SV = llvm::ConstantVector::getSplat(nElts, C); 3250 return Builder.CreateShuffleVector(V, V, SV, "lane"); 3251 } 3252 3253 Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 3254 const char *name, 3255 unsigned shift, bool rightshift) { 3256 unsigned j = 0; 3257 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3258 ai != ae; ++ai, ++j) 3259 if (shift > 0 && shift == j) 3260 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 3261 else 3262 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 3263 3264 return Builder.CreateCall(F, Ops, name); 3265 } 3266 3267 Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 3268 bool neg) { 3269 int SV = cast<ConstantInt>(V)->getSExtValue(); 3270 return ConstantInt::get(Ty, neg ? -SV : SV); 3271 } 3272 3273 // \brief Right-shift a vector by a constant. 3274 Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, 3275 llvm::Type *Ty, bool usgn, 3276 const char *name) { 3277 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3278 3279 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); 3280 int EltSize = VTy->getScalarSizeInBits(); 3281 3282 Vec = Builder.CreateBitCast(Vec, Ty); 3283 3284 // lshr/ashr are undefined when the shift amount is equal to the vector 3285 // element size. 3286 if (ShiftAmt == EltSize) { 3287 if (usgn) { 3288 // Right-shifting an unsigned value by its size yields 0. 3289 return llvm::ConstantAggregateZero::get(VTy); 3290 } else { 3291 // Right-shifting a signed value by its size is equivalent 3292 // to a shift of size-1. 3293 --ShiftAmt; 3294 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); 3295 } 3296 } 3297 3298 Shift = EmitNeonShiftVector(Shift, Ty, false); 3299 if (usgn) 3300 return Builder.CreateLShr(Vec, Shift, name); 3301 else 3302 return Builder.CreateAShr(Vec, Shift, name); 3303 } 3304 3305 enum { 3306 AddRetType = (1 << 0), 3307 Add1ArgType = (1 << 1), 3308 Add2ArgTypes = (1 << 2), 3309 3310 VectorizeRetType = (1 << 3), 3311 VectorizeArgTypes = (1 << 4), 3312 3313 InventFloatType = (1 << 5), 3314 UnsignedAlts = (1 << 6), 3315 3316 Use64BitVectors = (1 << 7), 3317 Use128BitVectors = (1 << 8), 3318 3319 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes, 3320 VectorRet = AddRetType | VectorizeRetType, 3321 VectorRetGetArgs01 = 3322 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes, 3323 FpCmpzModifiers = 3324 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType 3325 }; 3326 3327 namespace { 3328 struct NeonIntrinsicInfo { 3329 const char *NameHint; 3330 unsigned BuiltinID; 3331 unsigned LLVMIntrinsic; 3332 unsigned AltLLVMIntrinsic; 3333 unsigned TypeModifier; 3334 3335 bool operator<(unsigned RHSBuiltinID) const { 3336 return BuiltinID < RHSBuiltinID; 3337 } 3338 bool operator<(const NeonIntrinsicInfo &TE) const { 3339 return BuiltinID < TE.BuiltinID; 3340 } 3341 }; 3342 } // end anonymous namespace 3343 3344 #define NEONMAP0(NameBase) \ 3345 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 } 3346 3347 #define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ 3348 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3349 Intrinsic::LLVMIntrinsic, 0, TypeModifier } 3350 3351 #define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \ 3352 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3353 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ 3354 TypeModifier } 3355 3356 static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { 3357 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3358 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3359 NEONMAP1(vabs_v, arm_neon_vabs, 0), 3360 NEONMAP1(vabsq_v, arm_neon_vabs, 0), 3361 NEONMAP0(vaddhn_v), 3362 NEONMAP1(vaesdq_v, arm_neon_aesd, 0), 3363 NEONMAP1(vaeseq_v, arm_neon_aese, 0), 3364 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), 3365 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), 3366 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), 3367 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), 3368 NEONMAP1(vcage_v, arm_neon_vacge, 0), 3369 NEONMAP1(vcageq_v, arm_neon_vacge, 0), 3370 NEONMAP1(vcagt_v, arm_neon_vacgt, 0), 3371 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0), 3372 NEONMAP1(vcale_v, arm_neon_vacge, 0), 3373 NEONMAP1(vcaleq_v, arm_neon_vacge, 0), 3374 NEONMAP1(vcalt_v, arm_neon_vacgt, 0), 3375 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0), 3376 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType), 3377 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType), 3378 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3379 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3380 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3381 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3382 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0), 3383 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), 3384 NEONMAP0(vcvt_f32_v), 3385 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3386 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3387 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3388 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3389 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3390 NEONMAP0(vcvt_s32_v), 3391 NEONMAP0(vcvt_s64_v), 3392 NEONMAP0(vcvt_u32_v), 3393 NEONMAP0(vcvt_u64_v), 3394 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), 3395 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), 3396 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), 3397 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), 3398 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), 3399 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), 3400 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), 3401 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), 3402 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), 3403 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), 3404 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), 3405 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), 3406 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), 3407 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), 3408 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), 3409 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), 3410 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), 3411 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), 3412 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), 3413 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), 3414 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), 3415 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), 3416 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), 3417 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), 3418 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), 3419 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), 3420 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), 3421 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), 3422 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), 3423 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), 3424 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), 3425 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), 3426 NEONMAP0(vcvtq_f32_v), 3427 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3428 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3429 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3430 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3431 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3432 NEONMAP0(vcvtq_s32_v), 3433 NEONMAP0(vcvtq_s64_v), 3434 NEONMAP0(vcvtq_u32_v), 3435 NEONMAP0(vcvtq_u64_v), 3436 NEONMAP0(vext_v), 3437 NEONMAP0(vextq_v), 3438 NEONMAP0(vfma_v), 3439 NEONMAP0(vfmaq_v), 3440 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3441 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3442 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3443 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3444 NEONMAP0(vld1_dup_v), 3445 NEONMAP1(vld1_v, arm_neon_vld1, 0), 3446 NEONMAP0(vld1q_dup_v), 3447 NEONMAP1(vld1q_v, arm_neon_vld1, 0), 3448 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0), 3449 NEONMAP1(vld2_v, arm_neon_vld2, 0), 3450 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0), 3451 NEONMAP1(vld2q_v, arm_neon_vld2, 0), 3452 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0), 3453 NEONMAP1(vld3_v, arm_neon_vld3, 0), 3454 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0), 3455 NEONMAP1(vld3q_v, arm_neon_vld3, 0), 3456 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0), 3457 NEONMAP1(vld4_v, arm_neon_vld4, 0), 3458 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0), 3459 NEONMAP1(vld4q_v, arm_neon_vld4, 0), 3460 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3461 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType), 3462 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType), 3463 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3464 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3465 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType), 3466 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType), 3467 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3468 NEONMAP0(vmovl_v), 3469 NEONMAP0(vmovn_v), 3470 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType), 3471 NEONMAP0(vmull_v), 3472 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType), 3473 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3474 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3475 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType), 3476 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3477 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3478 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType), 3479 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts), 3480 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts), 3481 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType), 3482 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType), 3483 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3484 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3485 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0), 3486 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0), 3487 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType), 3488 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType), 3489 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType), 3490 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts), 3491 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), 3492 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), 3493 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), 3494 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), 3495 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), 3496 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3497 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3498 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3499 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3500 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3501 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3502 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0), 3503 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0), 3504 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3505 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3506 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType), 3507 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3508 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3509 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType), 3510 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType), 3511 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3512 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3513 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType), 3514 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType), 3515 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType), 3516 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType), 3517 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType), 3518 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType), 3519 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType), 3520 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType), 3521 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType), 3522 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType), 3523 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType), 3524 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType), 3525 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3526 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3527 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3528 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3529 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3530 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3531 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType), 3532 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType), 3533 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType), 3534 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0), 3535 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0), 3536 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0), 3537 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0), 3538 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0), 3539 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0), 3540 NEONMAP0(vshl_n_v), 3541 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3542 NEONMAP0(vshll_n_v), 3543 NEONMAP0(vshlq_n_v), 3544 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3545 NEONMAP0(vshr_n_v), 3546 NEONMAP0(vshrn_n_v), 3547 NEONMAP0(vshrq_n_v), 3548 NEONMAP1(vst1_v, arm_neon_vst1, 0), 3549 NEONMAP1(vst1q_v, arm_neon_vst1, 0), 3550 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0), 3551 NEONMAP1(vst2_v, arm_neon_vst2, 0), 3552 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0), 3553 NEONMAP1(vst2q_v, arm_neon_vst2, 0), 3554 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0), 3555 NEONMAP1(vst3_v, arm_neon_vst3, 0), 3556 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0), 3557 NEONMAP1(vst3q_v, arm_neon_vst3, 0), 3558 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0), 3559 NEONMAP1(vst4_v, arm_neon_vst4, 0), 3560 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0), 3561 NEONMAP1(vst4q_v, arm_neon_vst4, 0), 3562 NEONMAP0(vsubhn_v), 3563 NEONMAP0(vtrn_v), 3564 NEONMAP0(vtrnq_v), 3565 NEONMAP0(vtst_v), 3566 NEONMAP0(vtstq_v), 3567 NEONMAP0(vuzp_v), 3568 NEONMAP0(vuzpq_v), 3569 NEONMAP0(vzip_v), 3570 NEONMAP0(vzipq_v) 3571 }; 3572 3573 static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = { 3574 NEONMAP1(vabs_v, aarch64_neon_abs, 0), 3575 NEONMAP1(vabsq_v, aarch64_neon_abs, 0), 3576 NEONMAP0(vaddhn_v), 3577 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0), 3578 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0), 3579 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0), 3580 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0), 3581 NEONMAP1(vcage_v, aarch64_neon_facge, 0), 3582 NEONMAP1(vcageq_v, aarch64_neon_facge, 0), 3583 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0), 3584 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0), 3585 NEONMAP1(vcale_v, aarch64_neon_facge, 0), 3586 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0), 3587 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0), 3588 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0), 3589 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType), 3590 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType), 3591 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3592 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3593 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3594 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3595 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0), 3596 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0), 3597 NEONMAP0(vcvt_f32_v), 3598 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3599 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3600 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3601 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3602 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3603 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3604 NEONMAP0(vcvtq_f32_v), 3605 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3606 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3607 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3608 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3609 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3610 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3611 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType), 3612 NEONMAP0(vext_v), 3613 NEONMAP0(vextq_v), 3614 NEONMAP0(vfma_v), 3615 NEONMAP0(vfmaq_v), 3616 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3617 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3618 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3619 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3620 NEONMAP0(vmovl_v), 3621 NEONMAP0(vmovn_v), 3622 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType), 3623 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType), 3624 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType), 3625 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3626 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3627 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType), 3628 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType), 3629 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType), 3630 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3631 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3632 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0), 3633 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0), 3634 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType), 3635 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType), 3636 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType), 3637 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts), 3638 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType), 3639 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType), 3640 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType), 3641 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType), 3642 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType), 3643 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3644 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3645 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts), 3646 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3647 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts), 3648 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3649 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0), 3650 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0), 3651 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3652 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3653 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType), 3654 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3655 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3656 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType), 3657 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType), 3658 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3659 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3660 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3661 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3662 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3663 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3664 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3665 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3666 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType), 3667 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType), 3668 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType), 3669 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0), 3670 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0), 3671 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0), 3672 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0), 3673 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0), 3674 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0), 3675 NEONMAP0(vshl_n_v), 3676 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3677 NEONMAP0(vshll_n_v), 3678 NEONMAP0(vshlq_n_v), 3679 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3680 NEONMAP0(vshr_n_v), 3681 NEONMAP0(vshrn_n_v), 3682 NEONMAP0(vshrq_n_v), 3683 NEONMAP0(vsubhn_v), 3684 NEONMAP0(vtst_v), 3685 NEONMAP0(vtstq_v), 3686 }; 3687 3688 static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = { 3689 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType), 3690 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType), 3691 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType), 3692 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3693 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3694 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3695 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3696 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3697 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3698 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3699 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3700 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType), 3701 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3702 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType), 3703 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3704 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3705 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3706 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3707 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3708 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3709 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3710 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3711 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3712 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3713 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3714 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3715 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3716 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3717 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3718 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3719 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3720 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3721 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3722 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3723 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3724 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3725 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3726 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3727 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3728 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3729 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3730 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3731 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3732 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3733 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3734 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3735 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3736 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3737 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0), 3738 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3739 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3740 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3741 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3742 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3743 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3744 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3745 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3746 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3747 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3748 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3749 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3750 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3751 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3752 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3753 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3754 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3755 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3756 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3757 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3758 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0), 3759 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType), 3760 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType), 3761 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3762 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3763 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3764 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3765 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3766 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3767 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3768 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3769 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3770 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3771 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3772 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType), 3773 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3774 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType), 3775 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3776 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3777 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType), 3778 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType), 3779 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3780 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3781 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType), 3782 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType), 3783 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors), 3784 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType), 3785 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors), 3786 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0), 3787 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType), 3788 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType), 3789 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3790 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3791 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3792 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3793 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType), 3794 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3795 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3796 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3797 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType), 3798 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3799 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType), 3800 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors), 3801 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType), 3802 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3803 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3804 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType), 3805 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType), 3806 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3807 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3808 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType), 3809 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType), 3810 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType), 3811 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType), 3812 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3813 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3814 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3815 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3816 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType), 3817 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3818 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3819 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3820 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3821 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3822 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3823 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType), 3824 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType), 3825 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3826 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3827 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3828 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3829 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType), 3830 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType), 3831 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType), 3832 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType), 3833 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3834 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3835 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType), 3836 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType), 3837 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType), 3838 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3839 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3840 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3841 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3842 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType), 3843 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3844 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3845 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3846 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3847 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType), 3848 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType), 3849 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3850 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3851 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType), 3852 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType), 3853 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType), 3854 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType), 3855 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType), 3856 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType), 3857 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType), 3858 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType), 3859 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType), 3860 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType), 3861 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType), 3862 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType), 3863 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0), 3864 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0), 3865 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0), 3866 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0), 3867 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType), 3868 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType), 3869 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType), 3870 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType), 3871 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3872 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType), 3873 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3874 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType), 3875 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType), 3876 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType), 3877 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3878 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType), 3879 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3880 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType), 3881 }; 3882 3883 #undef NEONMAP0 3884 #undef NEONMAP1 3885 #undef NEONMAP2 3886 3887 static bool NEONSIMDIntrinsicsProvenSorted = false; 3888 3889 static bool AArch64SIMDIntrinsicsProvenSorted = false; 3890 static bool AArch64SISDIntrinsicsProvenSorted = false; 3891 3892 3893 static const NeonIntrinsicInfo * 3894 findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap, 3895 unsigned BuiltinID, bool &MapProvenSorted) { 3896 3897 #ifndef NDEBUG 3898 if (!MapProvenSorted) { 3899 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap))); 3900 MapProvenSorted = true; 3901 } 3902 #endif 3903 3904 const NeonIntrinsicInfo *Builtin = 3905 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID); 3906 3907 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) 3908 return Builtin; 3909 3910 return nullptr; 3911 } 3912 3913 Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 3914 unsigned Modifier, 3915 llvm::Type *ArgType, 3916 const CallExpr *E) { 3917 int VectorSize = 0; 3918 if (Modifier & Use64BitVectors) 3919 VectorSize = 64; 3920 else if (Modifier & Use128BitVectors) 3921 VectorSize = 128; 3922 3923 // Return type. 3924 SmallVector<llvm::Type *, 3> Tys; 3925 if (Modifier & AddRetType) { 3926 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 3927 if (Modifier & VectorizeRetType) 3928 Ty = llvm::VectorType::get( 3929 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1); 3930 3931 Tys.push_back(Ty); 3932 } 3933 3934 // Arguments. 3935 if (Modifier & VectorizeArgTypes) { 3936 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1; 3937 ArgType = llvm::VectorType::get(ArgType, Elts); 3938 } 3939 3940 if (Modifier & (Add1ArgType | Add2ArgTypes)) 3941 Tys.push_back(ArgType); 3942 3943 if (Modifier & Add2ArgTypes) 3944 Tys.push_back(ArgType); 3945 3946 if (Modifier & InventFloatType) 3947 Tys.push_back(FloatTy); 3948 3949 return CGM.getIntrinsic(IntrinsicID, Tys); 3950 } 3951 3952 static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF, 3953 const NeonIntrinsicInfo &SISDInfo, 3954 SmallVectorImpl<Value *> &Ops, 3955 const CallExpr *E) { 3956 unsigned BuiltinID = SISDInfo.BuiltinID; 3957 unsigned int Int = SISDInfo.LLVMIntrinsic; 3958 unsigned Modifier = SISDInfo.TypeModifier; 3959 const char *s = SISDInfo.NameHint; 3960 3961 switch (BuiltinID) { 3962 case NEON::BI__builtin_neon_vcled_s64: 3963 case NEON::BI__builtin_neon_vcled_u64: 3964 case NEON::BI__builtin_neon_vcles_f32: 3965 case NEON::BI__builtin_neon_vcled_f64: 3966 case NEON::BI__builtin_neon_vcltd_s64: 3967 case NEON::BI__builtin_neon_vcltd_u64: 3968 case NEON::BI__builtin_neon_vclts_f32: 3969 case NEON::BI__builtin_neon_vcltd_f64: 3970 case NEON::BI__builtin_neon_vcales_f32: 3971 case NEON::BI__builtin_neon_vcaled_f64: 3972 case NEON::BI__builtin_neon_vcalts_f32: 3973 case NEON::BI__builtin_neon_vcaltd_f64: 3974 // Only one direction of comparisons actually exist, cmle is actually a cmge 3975 // with swapped operands. The table gives us the right intrinsic but we 3976 // still need to do the swap. 3977 std::swap(Ops[0], Ops[1]); 3978 break; 3979 } 3980 3981 assert(Int && "Generic code assumes a valid intrinsic"); 3982 3983 // Determine the type(s) of this overloaded AArch64 intrinsic. 3984 const Expr *Arg = E->getArg(0); 3985 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType()); 3986 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E); 3987 3988 int j = 0; 3989 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0); 3990 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3991 ai != ae; ++ai, ++j) { 3992 llvm::Type *ArgTy = ai->getType(); 3993 if (Ops[j]->getType()->getPrimitiveSizeInBits() == 3994 ArgTy->getPrimitiveSizeInBits()) 3995 continue; 3996 3997 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy()); 3998 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate 3999 // it before inserting. 4000 Ops[j] = 4001 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType()); 4002 Ops[j] = 4003 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0); 4004 } 4005 4006 Value *Result = CGF.EmitNeonCall(F, Ops, s); 4007 llvm::Type *ResultType = CGF.ConvertType(E->getType()); 4008 if (ResultType->getPrimitiveSizeInBits() < 4009 Result->getType()->getPrimitiveSizeInBits()) 4010 return CGF.Builder.CreateExtractElement(Result, C0); 4011 4012 return CGF.Builder.CreateBitCast(Result, ResultType, s); 4013 } 4014 4015 Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( 4016 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, 4017 const char *NameHint, unsigned Modifier, const CallExpr *E, 4018 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) { 4019 // Get the last argument, which specifies the vector type. 4020 llvm::APSInt NeonTypeConst; 4021 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 4022 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext())) 4023 return nullptr; 4024 4025 // Determine the type of this overloaded NEON intrinsic. 4026 NeonTypeFlags Type(NeonTypeConst.getZExtValue()); 4027 bool Usgn = Type.isUnsigned(); 4028 bool Quad = Type.isQuad(); 4029 4030 llvm::VectorType *VTy = GetNeonType(this, Type); 4031 llvm::Type *Ty = VTy; 4032 if (!Ty) 4033 return nullptr; 4034 4035 auto getAlignmentValue32 = [&](Address addr) -> Value* { 4036 return Builder.getInt32(addr.getAlignment().getQuantity()); 4037 }; 4038 4039 unsigned Int = LLVMIntrinsic; 4040 if ((Modifier & UnsignedAlts) && !Usgn) 4041 Int = AltLLVMIntrinsic; 4042 4043 switch (BuiltinID) { 4044 default: break; 4045 case NEON::BI__builtin_neon_vabs_v: 4046 case NEON::BI__builtin_neon_vabsq_v: 4047 if (VTy->getElementType()->isFloatingPointTy()) 4048 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); 4049 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs"); 4050 case NEON::BI__builtin_neon_vaddhn_v: { 4051 llvm::VectorType *SrcTy = 4052 llvm::VectorType::getExtendedElementVectorType(VTy); 4053 4054 // %sum = add <4 x i32> %lhs, %rhs 4055 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4056 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4057 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 4058 4059 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4060 Constant *ShiftAmt = 4061 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4062 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 4063 4064 // %res = trunc <4 x i32> %high to <4 x i16> 4065 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 4066 } 4067 case NEON::BI__builtin_neon_vcale_v: 4068 case NEON::BI__builtin_neon_vcaleq_v: 4069 case NEON::BI__builtin_neon_vcalt_v: 4070 case NEON::BI__builtin_neon_vcaltq_v: 4071 std::swap(Ops[0], Ops[1]); 4072 LLVM_FALLTHROUGH; 4073 case NEON::BI__builtin_neon_vcage_v: 4074 case NEON::BI__builtin_neon_vcageq_v: 4075 case NEON::BI__builtin_neon_vcagt_v: 4076 case NEON::BI__builtin_neon_vcagtq_v: { 4077 llvm::Type *VecFlt = llvm::VectorType::get( 4078 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, 4079 VTy->getNumElements()); 4080 llvm::Type *Tys[] = { VTy, VecFlt }; 4081 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4082 return EmitNeonCall(F, Ops, NameHint); 4083 } 4084 case NEON::BI__builtin_neon_vclz_v: 4085 case NEON::BI__builtin_neon_vclzq_v: 4086 // We generate target-independent intrinsic, which needs a second argument 4087 // for whether or not clz of zero is undefined; on ARM it isn't. 4088 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 4089 break; 4090 case NEON::BI__builtin_neon_vcvt_f32_v: 4091 case NEON::BI__builtin_neon_vcvtq_f32_v: 4092 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4093 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); 4094 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 4095 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 4096 case NEON::BI__builtin_neon_vcvt_n_f32_v: 4097 case NEON::BI__builtin_neon_vcvt_n_f64_v: 4098 case NEON::BI__builtin_neon_vcvtq_n_f32_v: 4099 case NEON::BI__builtin_neon_vcvtq_n_f64_v: { 4100 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty }; 4101 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic; 4102 Function *F = CGM.getIntrinsic(Int, Tys); 4103 return EmitNeonCall(F, Ops, "vcvt_n"); 4104 } 4105 case NEON::BI__builtin_neon_vcvt_n_s32_v: 4106 case NEON::BI__builtin_neon_vcvt_n_u32_v: 4107 case NEON::BI__builtin_neon_vcvt_n_s64_v: 4108 case NEON::BI__builtin_neon_vcvt_n_u64_v: 4109 case NEON::BI__builtin_neon_vcvtq_n_s32_v: 4110 case NEON::BI__builtin_neon_vcvtq_n_u32_v: 4111 case NEON::BI__builtin_neon_vcvtq_n_s64_v: 4112 case NEON::BI__builtin_neon_vcvtq_n_u64_v: { 4113 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4114 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4115 return EmitNeonCall(F, Ops, "vcvt_n"); 4116 } 4117 case NEON::BI__builtin_neon_vcvt_s32_v: 4118 case NEON::BI__builtin_neon_vcvt_u32_v: 4119 case NEON::BI__builtin_neon_vcvt_s64_v: 4120 case NEON::BI__builtin_neon_vcvt_u64_v: 4121 case NEON::BI__builtin_neon_vcvtq_s32_v: 4122 case NEON::BI__builtin_neon_vcvtq_u32_v: 4123 case NEON::BI__builtin_neon_vcvtq_s64_v: 4124 case NEON::BI__builtin_neon_vcvtq_u64_v: { 4125 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 4126 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 4127 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 4128 } 4129 case NEON::BI__builtin_neon_vcvta_s32_v: 4130 case NEON::BI__builtin_neon_vcvta_s64_v: 4131 case NEON::BI__builtin_neon_vcvta_u32_v: 4132 case NEON::BI__builtin_neon_vcvta_u64_v: 4133 case NEON::BI__builtin_neon_vcvtaq_s32_v: 4134 case NEON::BI__builtin_neon_vcvtaq_s64_v: 4135 case NEON::BI__builtin_neon_vcvtaq_u32_v: 4136 case NEON::BI__builtin_neon_vcvtaq_u64_v: 4137 case NEON::BI__builtin_neon_vcvtn_s32_v: 4138 case NEON::BI__builtin_neon_vcvtn_s64_v: 4139 case NEON::BI__builtin_neon_vcvtn_u32_v: 4140 case NEON::BI__builtin_neon_vcvtn_u64_v: 4141 case NEON::BI__builtin_neon_vcvtnq_s32_v: 4142 case NEON::BI__builtin_neon_vcvtnq_s64_v: 4143 case NEON::BI__builtin_neon_vcvtnq_u32_v: 4144 case NEON::BI__builtin_neon_vcvtnq_u64_v: 4145 case NEON::BI__builtin_neon_vcvtp_s32_v: 4146 case NEON::BI__builtin_neon_vcvtp_s64_v: 4147 case NEON::BI__builtin_neon_vcvtp_u32_v: 4148 case NEON::BI__builtin_neon_vcvtp_u64_v: 4149 case NEON::BI__builtin_neon_vcvtpq_s32_v: 4150 case NEON::BI__builtin_neon_vcvtpq_s64_v: 4151 case NEON::BI__builtin_neon_vcvtpq_u32_v: 4152 case NEON::BI__builtin_neon_vcvtpq_u64_v: 4153 case NEON::BI__builtin_neon_vcvtm_s32_v: 4154 case NEON::BI__builtin_neon_vcvtm_s64_v: 4155 case NEON::BI__builtin_neon_vcvtm_u32_v: 4156 case NEON::BI__builtin_neon_vcvtm_u64_v: 4157 case NEON::BI__builtin_neon_vcvtmq_s32_v: 4158 case NEON::BI__builtin_neon_vcvtmq_s64_v: 4159 case NEON::BI__builtin_neon_vcvtmq_u32_v: 4160 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 4161 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4162 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint); 4163 } 4164 case NEON::BI__builtin_neon_vext_v: 4165 case NEON::BI__builtin_neon_vextq_v: { 4166 int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 4167 SmallVector<uint32_t, 16> Indices; 4168 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4169 Indices.push_back(i+CV); 4170 4171 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4172 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4173 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext"); 4174 } 4175 case NEON::BI__builtin_neon_vfma_v: 4176 case NEON::BI__builtin_neon_vfmaq_v: { 4177 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 4178 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4179 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4180 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4181 4182 // NEON intrinsic puts accumulator first, unlike the LLVM fma. 4183 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 4184 } 4185 case NEON::BI__builtin_neon_vld1_v: 4186 case NEON::BI__builtin_neon_vld1q_v: { 4187 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4188 Ops.push_back(getAlignmentValue32(PtrOp0)); 4189 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1"); 4190 } 4191 case NEON::BI__builtin_neon_vld2_v: 4192 case NEON::BI__builtin_neon_vld2q_v: 4193 case NEON::BI__builtin_neon_vld3_v: 4194 case NEON::BI__builtin_neon_vld3q_v: 4195 case NEON::BI__builtin_neon_vld4_v: 4196 case NEON::BI__builtin_neon_vld4q_v: { 4197 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4198 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4199 Value *Align = getAlignmentValue32(PtrOp1); 4200 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint); 4201 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4202 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4203 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4204 } 4205 case NEON::BI__builtin_neon_vld1_dup_v: 4206 case NEON::BI__builtin_neon_vld1q_dup_v: { 4207 Value *V = UndefValue::get(Ty); 4208 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 4209 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty); 4210 LoadInst *Ld = Builder.CreateLoad(PtrOp0); 4211 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 4212 Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 4213 return EmitNeonSplat(Ops[0], CI); 4214 } 4215 case NEON::BI__builtin_neon_vld2_lane_v: 4216 case NEON::BI__builtin_neon_vld2q_lane_v: 4217 case NEON::BI__builtin_neon_vld3_lane_v: 4218 case NEON::BI__builtin_neon_vld3q_lane_v: 4219 case NEON::BI__builtin_neon_vld4_lane_v: 4220 case NEON::BI__builtin_neon_vld4q_lane_v: { 4221 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4222 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4223 for (unsigned I = 2; I < Ops.size() - 1; ++I) 4224 Ops[I] = Builder.CreateBitCast(Ops[I], Ty); 4225 Ops.push_back(getAlignmentValue32(PtrOp1)); 4226 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint); 4227 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4228 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4229 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4230 } 4231 case NEON::BI__builtin_neon_vmovl_v: { 4232 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 4233 Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 4234 if (Usgn) 4235 return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 4236 return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 4237 } 4238 case NEON::BI__builtin_neon_vmovn_v: { 4239 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4240 Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 4241 return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 4242 } 4243 case NEON::BI__builtin_neon_vmull_v: 4244 // FIXME: the integer vmull operations could be emitted in terms of pure 4245 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 4246 // hoisting the exts outside loops. Until global ISel comes along that can 4247 // see through such movement this leads to bad CodeGen. So we need an 4248 // intrinsic for now. 4249 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 4250 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 4251 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 4252 case NEON::BI__builtin_neon_vpadal_v: 4253 case NEON::BI__builtin_neon_vpadalq_v: { 4254 // The source operand type has twice as many elements of half the size. 4255 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4256 llvm::Type *EltTy = 4257 llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4258 llvm::Type *NarrowTy = 4259 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4260 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4261 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); 4262 } 4263 case NEON::BI__builtin_neon_vpaddl_v: 4264 case NEON::BI__builtin_neon_vpaddlq_v: { 4265 // The source operand type has twice as many elements of half the size. 4266 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4267 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4268 llvm::Type *NarrowTy = 4269 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4270 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4271 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 4272 } 4273 case NEON::BI__builtin_neon_vqdmlal_v: 4274 case NEON::BI__builtin_neon_vqdmlsl_v: { 4275 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 4276 Ops[1] = 4277 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal"); 4278 Ops.resize(2); 4279 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint); 4280 } 4281 case NEON::BI__builtin_neon_vqshl_n_v: 4282 case NEON::BI__builtin_neon_vqshlq_n_v: 4283 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 4284 1, false); 4285 case NEON::BI__builtin_neon_vqshlu_n_v: 4286 case NEON::BI__builtin_neon_vqshluq_n_v: 4287 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n", 4288 1, false); 4289 case NEON::BI__builtin_neon_vrecpe_v: 4290 case NEON::BI__builtin_neon_vrecpeq_v: 4291 case NEON::BI__builtin_neon_vrsqrte_v: 4292 case NEON::BI__builtin_neon_vrsqrteq_v: 4293 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic; 4294 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint); 4295 4296 case NEON::BI__builtin_neon_vrshr_n_v: 4297 case NEON::BI__builtin_neon_vrshrq_n_v: 4298 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 4299 1, true); 4300 case NEON::BI__builtin_neon_vshl_n_v: 4301 case NEON::BI__builtin_neon_vshlq_n_v: 4302 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 4303 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 4304 "vshl_n"); 4305 case NEON::BI__builtin_neon_vshll_n_v: { 4306 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 4307 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4308 if (Usgn) 4309 Ops[0] = Builder.CreateZExt(Ops[0], VTy); 4310 else 4311 Ops[0] = Builder.CreateSExt(Ops[0], VTy); 4312 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 4313 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 4314 } 4315 case NEON::BI__builtin_neon_vshrn_n_v: { 4316 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4317 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4318 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 4319 if (Usgn) 4320 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 4321 else 4322 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 4323 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 4324 } 4325 case NEON::BI__builtin_neon_vshr_n_v: 4326 case NEON::BI__builtin_neon_vshrq_n_v: 4327 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n"); 4328 case NEON::BI__builtin_neon_vst1_v: 4329 case NEON::BI__builtin_neon_vst1q_v: 4330 case NEON::BI__builtin_neon_vst2_v: 4331 case NEON::BI__builtin_neon_vst2q_v: 4332 case NEON::BI__builtin_neon_vst3_v: 4333 case NEON::BI__builtin_neon_vst3q_v: 4334 case NEON::BI__builtin_neon_vst4_v: 4335 case NEON::BI__builtin_neon_vst4q_v: 4336 case NEON::BI__builtin_neon_vst2_lane_v: 4337 case NEON::BI__builtin_neon_vst2q_lane_v: 4338 case NEON::BI__builtin_neon_vst3_lane_v: 4339 case NEON::BI__builtin_neon_vst3q_lane_v: 4340 case NEON::BI__builtin_neon_vst4_lane_v: 4341 case NEON::BI__builtin_neon_vst4q_lane_v: { 4342 llvm::Type *Tys[] = {Int8PtrTy, Ty}; 4343 Ops.push_back(getAlignmentValue32(PtrOp0)); 4344 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 4345 } 4346 case NEON::BI__builtin_neon_vsubhn_v: { 4347 llvm::VectorType *SrcTy = 4348 llvm::VectorType::getExtendedElementVectorType(VTy); 4349 4350 // %sum = add <4 x i32> %lhs, %rhs 4351 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4352 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4353 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 4354 4355 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4356 Constant *ShiftAmt = 4357 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4358 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 4359 4360 // %res = trunc <4 x i32> %high to <4 x i16> 4361 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 4362 } 4363 case NEON::BI__builtin_neon_vtrn_v: 4364 case NEON::BI__builtin_neon_vtrnq_v: { 4365 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4366 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4367 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4368 Value *SV = nullptr; 4369 4370 for (unsigned vi = 0; vi != 2; ++vi) { 4371 SmallVector<uint32_t, 16> Indices; 4372 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4373 Indices.push_back(i+vi); 4374 Indices.push_back(i+e+vi); 4375 } 4376 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4377 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 4378 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4379 } 4380 return SV; 4381 } 4382 case NEON::BI__builtin_neon_vtst_v: 4383 case NEON::BI__builtin_neon_vtstq_v: { 4384 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4385 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4386 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 4387 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 4388 ConstantAggregateZero::get(Ty)); 4389 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 4390 } 4391 case NEON::BI__builtin_neon_vuzp_v: 4392 case NEON::BI__builtin_neon_vuzpq_v: { 4393 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4394 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4395 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4396 Value *SV = nullptr; 4397 4398 for (unsigned vi = 0; vi != 2; ++vi) { 4399 SmallVector<uint32_t, 16> Indices; 4400 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4401 Indices.push_back(2*i+vi); 4402 4403 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4404 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 4405 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4406 } 4407 return SV; 4408 } 4409 case NEON::BI__builtin_neon_vzip_v: 4410 case NEON::BI__builtin_neon_vzipq_v: { 4411 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4412 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4413 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4414 Value *SV = nullptr; 4415 4416 for (unsigned vi = 0; vi != 2; ++vi) { 4417 SmallVector<uint32_t, 16> Indices; 4418 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4419 Indices.push_back((i + vi*e) >> 1); 4420 Indices.push_back(((i + vi*e) >> 1)+e); 4421 } 4422 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4423 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 4424 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4425 } 4426 return SV; 4427 } 4428 } 4429 4430 assert(Int && "Expected valid intrinsic number"); 4431 4432 // Determine the type(s) of this overloaded AArch64 intrinsic. 4433 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E); 4434 4435 Value *Result = EmitNeonCall(F, Ops, NameHint); 4436 llvm::Type *ResultType = ConvertType(E->getType()); 4437 // AArch64 intrinsic one-element vector type cast to 4438 // scalar type expected by the builtin 4439 return Builder.CreateBitCast(Result, ResultType, NameHint); 4440 } 4441 4442 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( 4443 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, 4444 const CmpInst::Predicate Ip, const Twine &Name) { 4445 llvm::Type *OTy = Op->getType(); 4446 4447 // FIXME: this is utterly horrific. We should not be looking at previous 4448 // codegen context to find out what needs doing. Unfortunately TableGen 4449 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32 4450 // (etc). 4451 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op)) 4452 OTy = BI->getOperand(0)->getType(); 4453 4454 Op = Builder.CreateBitCast(Op, OTy); 4455 if (OTy->getScalarType()->isFloatingPointTy()) { 4456 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy)); 4457 } else { 4458 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy)); 4459 } 4460 return Builder.CreateSExt(Op, Ty, Name); 4461 } 4462 4463 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, 4464 Value *ExtOp, Value *IndexOp, 4465 llvm::Type *ResTy, unsigned IntID, 4466 const char *Name) { 4467 SmallVector<Value *, 2> TblOps; 4468 if (ExtOp) 4469 TblOps.push_back(ExtOp); 4470 4471 // Build a vector containing sequential number like (0, 1, 2, ..., 15) 4472 SmallVector<uint32_t, 16> Indices; 4473 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); 4474 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { 4475 Indices.push_back(2*i); 4476 Indices.push_back(2*i+1); 4477 } 4478 4479 int PairPos = 0, End = Ops.size() - 1; 4480 while (PairPos < End) { 4481 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4482 Ops[PairPos+1], Indices, 4483 Name)); 4484 PairPos += 2; 4485 } 4486 4487 // If there's an odd number of 64-bit lookup table, fill the high 64-bit 4488 // of the 128-bit lookup table with zero. 4489 if (PairPos == End) { 4490 Value *ZeroTbl = ConstantAggregateZero::get(TblTy); 4491 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4492 ZeroTbl, Indices, Name)); 4493 } 4494 4495 Function *TblF; 4496 TblOps.push_back(IndexOp); 4497 TblF = CGF.CGM.getIntrinsic(IntID, ResTy); 4498 4499 return CGF.EmitNeonCall(TblF, TblOps, Name); 4500 } 4501 4502 Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) { 4503 unsigned Value; 4504 switch (BuiltinID) { 4505 default: 4506 return nullptr; 4507 case ARM::BI__builtin_arm_nop: 4508 Value = 0; 4509 break; 4510 case ARM::BI__builtin_arm_yield: 4511 case ARM::BI__yield: 4512 Value = 1; 4513 break; 4514 case ARM::BI__builtin_arm_wfe: 4515 case ARM::BI__wfe: 4516 Value = 2; 4517 break; 4518 case ARM::BI__builtin_arm_wfi: 4519 case ARM::BI__wfi: 4520 Value = 3; 4521 break; 4522 case ARM::BI__builtin_arm_sev: 4523 case ARM::BI__sev: 4524 Value = 4; 4525 break; 4526 case ARM::BI__builtin_arm_sevl: 4527 case ARM::BI__sevl: 4528 Value = 5; 4529 break; 4530 } 4531 4532 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint), 4533 llvm::ConstantInt::get(Int32Ty, Value)); 4534 } 4535 4536 // Generates the IR for the read/write special register builtin, 4537 // ValueType is the type of the value that is to be written or read, 4538 // RegisterType is the type of the register being written to or read from. 4539 static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF, 4540 const CallExpr *E, 4541 llvm::Type *RegisterType, 4542 llvm::Type *ValueType, 4543 bool IsRead, 4544 StringRef SysReg = "") { 4545 // write and register intrinsics only support 32 and 64 bit operations. 4546 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64)) 4547 && "Unsupported size for register."); 4548 4549 CodeGen::CGBuilderTy &Builder = CGF.Builder; 4550 CodeGen::CodeGenModule &CGM = CGF.CGM; 4551 LLVMContext &Context = CGM.getLLVMContext(); 4552 4553 if (SysReg.empty()) { 4554 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts(); 4555 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString(); 4556 } 4557 4558 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) }; 4559 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops); 4560 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName); 4561 4562 llvm::Type *Types[] = { RegisterType }; 4563 4564 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32); 4565 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64)) 4566 && "Can't fit 64-bit value in 32-bit register"); 4567 4568 if (IsRead) { 4569 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types); 4570 llvm::Value *Call = Builder.CreateCall(F, Metadata); 4571 4572 if (MixedTypes) 4573 // Read into 64 bit register and then truncate result to 32 bit. 4574 return Builder.CreateTrunc(Call, ValueType); 4575 4576 if (ValueType->isPointerTy()) 4577 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*). 4578 return Builder.CreateIntToPtr(Call, ValueType); 4579 4580 return Call; 4581 } 4582 4583 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types); 4584 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1)); 4585 if (MixedTypes) { 4586 // Extend 32 bit write value to 64 bit to pass to write. 4587 ArgValue = Builder.CreateZExt(ArgValue, RegisterType); 4588 return Builder.CreateCall(F, { Metadata, ArgValue }); 4589 } 4590 4591 if (ValueType->isPointerTy()) { 4592 // Have VoidPtrTy ArgValue but want to return an i32/i64. 4593 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType); 4594 return Builder.CreateCall(F, { Metadata, ArgValue }); 4595 } 4596 4597 return Builder.CreateCall(F, { Metadata, ArgValue }); 4598 } 4599 4600 /// Return true if BuiltinID is an overloaded Neon intrinsic with an extra 4601 /// argument that specifies the vector type. 4602 static bool HasExtraNeonArgument(unsigned BuiltinID) { 4603 switch (BuiltinID) { 4604 default: break; 4605 case NEON::BI__builtin_neon_vget_lane_i8: 4606 case NEON::BI__builtin_neon_vget_lane_i16: 4607 case NEON::BI__builtin_neon_vget_lane_i32: 4608 case NEON::BI__builtin_neon_vget_lane_i64: 4609 case NEON::BI__builtin_neon_vget_lane_f32: 4610 case NEON::BI__builtin_neon_vgetq_lane_i8: 4611 case NEON::BI__builtin_neon_vgetq_lane_i16: 4612 case NEON::BI__builtin_neon_vgetq_lane_i32: 4613 case NEON::BI__builtin_neon_vgetq_lane_i64: 4614 case NEON::BI__builtin_neon_vgetq_lane_f32: 4615 case NEON::BI__builtin_neon_vset_lane_i8: 4616 case NEON::BI__builtin_neon_vset_lane_i16: 4617 case NEON::BI__builtin_neon_vset_lane_i32: 4618 case NEON::BI__builtin_neon_vset_lane_i64: 4619 case NEON::BI__builtin_neon_vset_lane_f32: 4620 case NEON::BI__builtin_neon_vsetq_lane_i8: 4621 case NEON::BI__builtin_neon_vsetq_lane_i16: 4622 case NEON::BI__builtin_neon_vsetq_lane_i32: 4623 case NEON::BI__builtin_neon_vsetq_lane_i64: 4624 case NEON::BI__builtin_neon_vsetq_lane_f32: 4625 case NEON::BI__builtin_neon_vsha1h_u32: 4626 case NEON::BI__builtin_neon_vsha1cq_u32: 4627 case NEON::BI__builtin_neon_vsha1pq_u32: 4628 case NEON::BI__builtin_neon_vsha1mq_u32: 4629 case ARM::BI_MoveToCoprocessor: 4630 case ARM::BI_MoveToCoprocessor2: 4631 return false; 4632 } 4633 return true; 4634 } 4635 4636 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 4637 const CallExpr *E) { 4638 if (auto Hint = GetValueForARMHint(BuiltinID)) 4639 return Hint; 4640 4641 if (BuiltinID == ARM::BI__emit) { 4642 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb; 4643 llvm::FunctionType *FTy = 4644 llvm::FunctionType::get(VoidTy, /*Variadic=*/false); 4645 4646 APSInt Value; 4647 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext())) 4648 llvm_unreachable("Sema will ensure that the parameter is constant"); 4649 4650 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue(); 4651 4652 llvm::InlineAsm *Emit = 4653 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "", 4654 /*SideEffects=*/true) 4655 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "", 4656 /*SideEffects=*/true); 4657 4658 return Builder.CreateCall(Emit); 4659 } 4660 4661 if (BuiltinID == ARM::BI__builtin_arm_dbg) { 4662 Value *Option = EmitScalarExpr(E->getArg(0)); 4663 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option); 4664 } 4665 4666 if (BuiltinID == ARM::BI__builtin_arm_prefetch) { 4667 Value *Address = EmitScalarExpr(E->getArg(0)); 4668 Value *RW = EmitScalarExpr(E->getArg(1)); 4669 Value *IsData = EmitScalarExpr(E->getArg(2)); 4670 4671 // Locality is not supported on ARM target 4672 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3); 4673 4674 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4675 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 4676 } 4677 4678 if (BuiltinID == ARM::BI__builtin_arm_rbit) { 4679 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 4680 return Builder.CreateCall( 4681 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 4682 } 4683 4684 if (BuiltinID == ARM::BI__clear_cache) { 4685 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 4686 const FunctionDecl *FD = E->getDirectCallee(); 4687 Value *Ops[2]; 4688 for (unsigned i = 0; i < 2; i++) 4689 Ops[i] = EmitScalarExpr(E->getArg(i)); 4690 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 4691 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 4692 StringRef Name = FD->getName(); 4693 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 4694 } 4695 4696 if (BuiltinID == ARM::BI__builtin_arm_mcrr || 4697 BuiltinID == ARM::BI__builtin_arm_mcrr2) { 4698 Function *F; 4699 4700 switch (BuiltinID) { 4701 default: llvm_unreachable("unexpected builtin"); 4702 case ARM::BI__builtin_arm_mcrr: 4703 F = CGM.getIntrinsic(Intrinsic::arm_mcrr); 4704 break; 4705 case ARM::BI__builtin_arm_mcrr2: 4706 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2); 4707 break; 4708 } 4709 4710 // MCRR{2} instruction has 5 operands but 4711 // the intrinsic has 4 because Rt and Rt2 4712 // are represented as a single unsigned 64 4713 // bit integer in the intrinsic definition 4714 // but internally it's represented as 2 32 4715 // bit integers. 4716 4717 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4718 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4719 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2)); 4720 Value *CRm = EmitScalarExpr(E->getArg(3)); 4721 4722 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4723 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty); 4724 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1); 4725 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty); 4726 4727 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm}); 4728 } 4729 4730 if (BuiltinID == ARM::BI__builtin_arm_mrrc || 4731 BuiltinID == ARM::BI__builtin_arm_mrrc2) { 4732 Function *F; 4733 4734 switch (BuiltinID) { 4735 default: llvm_unreachable("unexpected builtin"); 4736 case ARM::BI__builtin_arm_mrrc: 4737 F = CGM.getIntrinsic(Intrinsic::arm_mrrc); 4738 break; 4739 case ARM::BI__builtin_arm_mrrc2: 4740 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2); 4741 break; 4742 } 4743 4744 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4745 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4746 Value *CRm = EmitScalarExpr(E->getArg(2)); 4747 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm}); 4748 4749 // Returns an unsigned 64 bit integer, represented 4750 // as two 32 bit integers. 4751 4752 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1); 4753 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0); 4754 Rt = Builder.CreateZExt(Rt, Int64Ty); 4755 Rt1 = Builder.CreateZExt(Rt1, Int64Ty); 4756 4757 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32); 4758 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true); 4759 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1); 4760 4761 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType())); 4762 } 4763 4764 if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 4765 ((BuiltinID == ARM::BI__builtin_arm_ldrex || 4766 BuiltinID == ARM::BI__builtin_arm_ldaex) && 4767 getContext().getTypeSize(E->getType()) == 64) || 4768 BuiltinID == ARM::BI__ldrexd) { 4769 Function *F; 4770 4771 switch (BuiltinID) { 4772 default: llvm_unreachable("unexpected builtin"); 4773 case ARM::BI__builtin_arm_ldaex: 4774 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd); 4775 break; 4776 case ARM::BI__builtin_arm_ldrexd: 4777 case ARM::BI__builtin_arm_ldrex: 4778 case ARM::BI__ldrexd: 4779 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 4780 break; 4781 } 4782 4783 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 4784 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 4785 "ldrexd"); 4786 4787 Value *Val0 = Builder.CreateExtractValue(Val, 1); 4788 Value *Val1 = Builder.CreateExtractValue(Val, 0); 4789 Val0 = Builder.CreateZExt(Val0, Int64Ty); 4790 Val1 = Builder.CreateZExt(Val1, Int64Ty); 4791 4792 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 4793 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 4794 Val = Builder.CreateOr(Val, Val1); 4795 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 4796 } 4797 4798 if (BuiltinID == ARM::BI__builtin_arm_ldrex || 4799 BuiltinID == ARM::BI__builtin_arm_ldaex) { 4800 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 4801 4802 QualType Ty = E->getType(); 4803 llvm::Type *RealResTy = ConvertType(Ty); 4804 llvm::Type *PtrTy = llvm::IntegerType::get( 4805 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 4806 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 4807 4808 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex 4809 ? Intrinsic::arm_ldaex 4810 : Intrinsic::arm_ldrex, 4811 PtrTy); 4812 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 4813 4814 if (RealResTy->isPointerTy()) 4815 return Builder.CreateIntToPtr(Val, RealResTy); 4816 else { 4817 llvm::Type *IntResTy = llvm::IntegerType::get( 4818 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 4819 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 4820 return Builder.CreateBitCast(Val, RealResTy); 4821 } 4822 } 4823 4824 if (BuiltinID == ARM::BI__builtin_arm_strexd || 4825 ((BuiltinID == ARM::BI__builtin_arm_stlex || 4826 BuiltinID == ARM::BI__builtin_arm_strex) && 4827 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 4828 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4829 ? Intrinsic::arm_stlexd 4830 : Intrinsic::arm_strexd); 4831 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty); 4832 4833 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 4834 Value *Val = EmitScalarExpr(E->getArg(0)); 4835 Builder.CreateStore(Val, Tmp); 4836 4837 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 4838 Val = Builder.CreateLoad(LdPtr); 4839 4840 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 4841 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 4842 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 4843 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd"); 4844 } 4845 4846 if (BuiltinID == ARM::BI__builtin_arm_strex || 4847 BuiltinID == ARM::BI__builtin_arm_stlex) { 4848 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 4849 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 4850 4851 QualType Ty = E->getArg(0)->getType(); 4852 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 4853 getContext().getTypeSize(Ty)); 4854 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 4855 4856 if (StoreVal->getType()->isPointerTy()) 4857 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 4858 else { 4859 llvm::Type *IntTy = llvm::IntegerType::get( 4860 getLLVMContext(), 4861 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 4862 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 4863 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 4864 } 4865 4866 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4867 ? Intrinsic::arm_stlex 4868 : Intrinsic::arm_strex, 4869 StoreAddr->getType()); 4870 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex"); 4871 } 4872 4873 switch (BuiltinID) { 4874 case ARM::BI__iso_volatile_load8: 4875 case ARM::BI__iso_volatile_load16: 4876 case ARM::BI__iso_volatile_load32: 4877 case ARM::BI__iso_volatile_load64: { 4878 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4879 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4880 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); 4881 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4882 LoadSize.getQuantity() * 8); 4883 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4884 llvm::LoadInst *Load = 4885 Builder.CreateAlignedLoad(Ptr, LoadSize); 4886 Load->setVolatile(true); 4887 return Load; 4888 } 4889 case ARM::BI__iso_volatile_store8: 4890 case ARM::BI__iso_volatile_store16: 4891 case ARM::BI__iso_volatile_store32: 4892 case ARM::BI__iso_volatile_store64: { 4893 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4894 Value *Value = EmitScalarExpr(E->getArg(1)); 4895 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4896 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 4897 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4898 StoreSize.getQuantity() * 8); 4899 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4900 llvm::StoreInst *Store = 4901 Builder.CreateAlignedStore(Value, Ptr, 4902 StoreSize); 4903 Store->setVolatile(true); 4904 return Store; 4905 } 4906 } 4907 4908 if (BuiltinID == ARM::BI__builtin_arm_clrex) { 4909 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 4910 return Builder.CreateCall(F); 4911 } 4912 4913 // CRC32 4914 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 4915 switch (BuiltinID) { 4916 case ARM::BI__builtin_arm_crc32b: 4917 CRCIntrinsicID = Intrinsic::arm_crc32b; break; 4918 case ARM::BI__builtin_arm_crc32cb: 4919 CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 4920 case ARM::BI__builtin_arm_crc32h: 4921 CRCIntrinsicID = Intrinsic::arm_crc32h; break; 4922 case ARM::BI__builtin_arm_crc32ch: 4923 CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 4924 case ARM::BI__builtin_arm_crc32w: 4925 case ARM::BI__builtin_arm_crc32d: 4926 CRCIntrinsicID = Intrinsic::arm_crc32w; break; 4927 case ARM::BI__builtin_arm_crc32cw: 4928 case ARM::BI__builtin_arm_crc32cd: 4929 CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 4930 } 4931 4932 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 4933 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 4934 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 4935 4936 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 4937 // intrinsics, hence we need different codegen for these cases. 4938 if (BuiltinID == ARM::BI__builtin_arm_crc32d || 4939 BuiltinID == ARM::BI__builtin_arm_crc32cd) { 4940 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4941 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 4942 Value *Arg1b = Builder.CreateLShr(Arg1, C1); 4943 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 4944 4945 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4946 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a}); 4947 return Builder.CreateCall(F, {Res, Arg1b}); 4948 } else { 4949 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 4950 4951 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4952 return Builder.CreateCall(F, {Arg0, Arg1}); 4953 } 4954 } 4955 4956 if (BuiltinID == ARM::BI__builtin_arm_rsr || 4957 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4958 BuiltinID == ARM::BI__builtin_arm_rsrp || 4959 BuiltinID == ARM::BI__builtin_arm_wsr || 4960 BuiltinID == ARM::BI__builtin_arm_wsr64 || 4961 BuiltinID == ARM::BI__builtin_arm_wsrp) { 4962 4963 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr || 4964 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4965 BuiltinID == ARM::BI__builtin_arm_rsrp; 4966 4967 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp || 4968 BuiltinID == ARM::BI__builtin_arm_wsrp; 4969 4970 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 || 4971 BuiltinID == ARM::BI__builtin_arm_wsr64; 4972 4973 llvm::Type *ValueType; 4974 llvm::Type *RegisterType; 4975 if (IsPointerBuiltin) { 4976 ValueType = VoidPtrTy; 4977 RegisterType = Int32Ty; 4978 } else if (Is64Bit) { 4979 ValueType = RegisterType = Int64Ty; 4980 } else { 4981 ValueType = RegisterType = Int32Ty; 4982 } 4983 4984 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 4985 } 4986 4987 // Find out if any arguments are required to be integer constant 4988 // expressions. 4989 unsigned ICEArguments = 0; 4990 ASTContext::GetBuiltinTypeError Error; 4991 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 4992 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 4993 4994 auto getAlignmentValue32 = [&](Address addr) -> Value* { 4995 return Builder.getInt32(addr.getAlignment().getQuantity()); 4996 }; 4997 4998 Address PtrOp0 = Address::invalid(); 4999 Address PtrOp1 = Address::invalid(); 5000 SmallVector<Value*, 4> Ops; 5001 bool HasExtraArg = HasExtraNeonArgument(BuiltinID); 5002 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0); 5003 for (unsigned i = 0, e = NumArgs; i != e; i++) { 5004 if (i == 0) { 5005 switch (BuiltinID) { 5006 case NEON::BI__builtin_neon_vld1_v: 5007 case NEON::BI__builtin_neon_vld1q_v: 5008 case NEON::BI__builtin_neon_vld1q_lane_v: 5009 case NEON::BI__builtin_neon_vld1_lane_v: 5010 case NEON::BI__builtin_neon_vld1_dup_v: 5011 case NEON::BI__builtin_neon_vld1q_dup_v: 5012 case NEON::BI__builtin_neon_vst1_v: 5013 case NEON::BI__builtin_neon_vst1q_v: 5014 case NEON::BI__builtin_neon_vst1q_lane_v: 5015 case NEON::BI__builtin_neon_vst1_lane_v: 5016 case NEON::BI__builtin_neon_vst2_v: 5017 case NEON::BI__builtin_neon_vst2q_v: 5018 case NEON::BI__builtin_neon_vst2_lane_v: 5019 case NEON::BI__builtin_neon_vst2q_lane_v: 5020 case NEON::BI__builtin_neon_vst3_v: 5021 case NEON::BI__builtin_neon_vst3q_v: 5022 case NEON::BI__builtin_neon_vst3_lane_v: 5023 case NEON::BI__builtin_neon_vst3q_lane_v: 5024 case NEON::BI__builtin_neon_vst4_v: 5025 case NEON::BI__builtin_neon_vst4q_v: 5026 case NEON::BI__builtin_neon_vst4_lane_v: 5027 case NEON::BI__builtin_neon_vst4q_lane_v: 5028 // Get the alignment for the argument in addition to the value; 5029 // we'll use it later. 5030 PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); 5031 Ops.push_back(PtrOp0.getPointer()); 5032 continue; 5033 } 5034 } 5035 if (i == 1) { 5036 switch (BuiltinID) { 5037 case NEON::BI__builtin_neon_vld2_v: 5038 case NEON::BI__builtin_neon_vld2q_v: 5039 case NEON::BI__builtin_neon_vld3_v: 5040 case NEON::BI__builtin_neon_vld3q_v: 5041 case NEON::BI__builtin_neon_vld4_v: 5042 case NEON::BI__builtin_neon_vld4q_v: 5043 case NEON::BI__builtin_neon_vld2_lane_v: 5044 case NEON::BI__builtin_neon_vld2q_lane_v: 5045 case NEON::BI__builtin_neon_vld3_lane_v: 5046 case NEON::BI__builtin_neon_vld3q_lane_v: 5047 case NEON::BI__builtin_neon_vld4_lane_v: 5048 case NEON::BI__builtin_neon_vld4q_lane_v: 5049 case NEON::BI__builtin_neon_vld2_dup_v: 5050 case NEON::BI__builtin_neon_vld3_dup_v: 5051 case NEON::BI__builtin_neon_vld4_dup_v: 5052 // Get the alignment for the argument in addition to the value; 5053 // we'll use it later. 5054 PtrOp1 = EmitPointerWithAlignment(E->getArg(1)); 5055 Ops.push_back(PtrOp1.getPointer()); 5056 continue; 5057 } 5058 } 5059 5060 if ((ICEArguments & (1 << i)) == 0) { 5061 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5062 } else { 5063 // If this is required to be a constant, constant fold it so that we know 5064 // that the generated intrinsic gets a ConstantInt. 5065 llvm::APSInt Result; 5066 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5067 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 5068 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5069 } 5070 } 5071 5072 switch (BuiltinID) { 5073 default: break; 5074 5075 case NEON::BI__builtin_neon_vget_lane_i8: 5076 case NEON::BI__builtin_neon_vget_lane_i16: 5077 case NEON::BI__builtin_neon_vget_lane_i32: 5078 case NEON::BI__builtin_neon_vget_lane_i64: 5079 case NEON::BI__builtin_neon_vget_lane_f32: 5080 case NEON::BI__builtin_neon_vgetq_lane_i8: 5081 case NEON::BI__builtin_neon_vgetq_lane_i16: 5082 case NEON::BI__builtin_neon_vgetq_lane_i32: 5083 case NEON::BI__builtin_neon_vgetq_lane_i64: 5084 case NEON::BI__builtin_neon_vgetq_lane_f32: 5085 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); 5086 5087 case NEON::BI__builtin_neon_vset_lane_i8: 5088 case NEON::BI__builtin_neon_vset_lane_i16: 5089 case NEON::BI__builtin_neon_vset_lane_i32: 5090 case NEON::BI__builtin_neon_vset_lane_i64: 5091 case NEON::BI__builtin_neon_vset_lane_f32: 5092 case NEON::BI__builtin_neon_vsetq_lane_i8: 5093 case NEON::BI__builtin_neon_vsetq_lane_i16: 5094 case NEON::BI__builtin_neon_vsetq_lane_i32: 5095 case NEON::BI__builtin_neon_vsetq_lane_i64: 5096 case NEON::BI__builtin_neon_vsetq_lane_f32: 5097 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 5098 5099 case NEON::BI__builtin_neon_vsha1h_u32: 5100 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, 5101 "vsha1h"); 5102 case NEON::BI__builtin_neon_vsha1cq_u32: 5103 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, 5104 "vsha1h"); 5105 case NEON::BI__builtin_neon_vsha1pq_u32: 5106 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, 5107 "vsha1h"); 5108 case NEON::BI__builtin_neon_vsha1mq_u32: 5109 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, 5110 "vsha1h"); 5111 5112 // The ARM _MoveToCoprocessor builtins put the input register value as 5113 // the first argument, but the LLVM intrinsic expects it as the third one. 5114 case ARM::BI_MoveToCoprocessor: 5115 case ARM::BI_MoveToCoprocessor2: { 5116 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ? 5117 Intrinsic::arm_mcr : Intrinsic::arm_mcr2); 5118 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], 5119 Ops[3], Ops[4], Ops[5]}); 5120 } 5121 case ARM::BI_BitScanForward: 5122 case ARM::BI_BitScanForward64: 5123 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 5124 case ARM::BI_BitScanReverse: 5125 case ARM::BI_BitScanReverse64: 5126 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 5127 5128 case ARM::BI_InterlockedAnd64: 5129 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 5130 case ARM::BI_InterlockedExchange64: 5131 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 5132 case ARM::BI_InterlockedExchangeAdd64: 5133 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 5134 case ARM::BI_InterlockedExchangeSub64: 5135 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 5136 case ARM::BI_InterlockedOr64: 5137 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 5138 case ARM::BI_InterlockedXor64: 5139 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 5140 case ARM::BI_InterlockedDecrement64: 5141 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 5142 case ARM::BI_InterlockedIncrement64: 5143 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 5144 } 5145 5146 // Get the last argument, which specifies the vector type. 5147 assert(HasExtraArg); 5148 llvm::APSInt Result; 5149 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5150 if (!Arg->isIntegerConstantExpr(Result, getContext())) 5151 return nullptr; 5152 5153 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 5154 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 5155 // Determine the overloaded type of this builtin. 5156 llvm::Type *Ty; 5157 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 5158 Ty = FloatTy; 5159 else 5160 Ty = DoubleTy; 5161 5162 // Determine whether this is an unsigned conversion or not. 5163 bool usgn = Result.getZExtValue() == 1; 5164 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 5165 5166 // Call the appropriate intrinsic. 5167 Function *F = CGM.getIntrinsic(Int, Ty); 5168 return Builder.CreateCall(F, Ops, "vcvtr"); 5169 } 5170 5171 // Determine the type of this overloaded NEON intrinsic. 5172 NeonTypeFlags Type(Result.getZExtValue()); 5173 bool usgn = Type.isUnsigned(); 5174 bool rightShift = false; 5175 5176 llvm::VectorType *VTy = GetNeonType(this, Type); 5177 llvm::Type *Ty = VTy; 5178 if (!Ty) 5179 return nullptr; 5180 5181 // Many NEON builtins have identical semantics and uses in ARM and 5182 // AArch64. Emit these in a single function. 5183 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap); 5184 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5185 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); 5186 if (Builtin) 5187 return EmitCommonNeonBuiltinExpr( 5188 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 5189 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1); 5190 5191 unsigned Int; 5192 switch (BuiltinID) { 5193 default: return nullptr; 5194 case NEON::BI__builtin_neon_vld1q_lane_v: 5195 // Handle 64-bit integer elements as a special case. Use shuffles of 5196 // one-element vectors to avoid poor code for i64 in the backend. 5197 if (VTy->getElementType()->isIntegerTy(64)) { 5198 // Extract the other lane. 5199 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5200 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 5201 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 5202 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5203 // Load the value as a one-element vector. 5204 Ty = llvm::VectorType::get(VTy->getElementType(), 1); 5205 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5206 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys); 5207 Value *Align = getAlignmentValue32(PtrOp0); 5208 Value *Ld = Builder.CreateCall(F, {Ops[0], Align}); 5209 // Combine them. 5210 uint32_t Indices[] = {1 - Lane, Lane}; 5211 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices); 5212 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 5213 } 5214 // fall through 5215 case NEON::BI__builtin_neon_vld1_lane_v: { 5216 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5217 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType()); 5218 Value *Ld = Builder.CreateLoad(PtrOp0); 5219 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 5220 } 5221 case NEON::BI__builtin_neon_vld2_dup_v: 5222 case NEON::BI__builtin_neon_vld3_dup_v: 5223 case NEON::BI__builtin_neon_vld4_dup_v: { 5224 // Handle 64-bit elements as a special-case. There is no "dup" needed. 5225 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 5226 switch (BuiltinID) { 5227 case NEON::BI__builtin_neon_vld2_dup_v: 5228 Int = Intrinsic::arm_neon_vld2; 5229 break; 5230 case NEON::BI__builtin_neon_vld3_dup_v: 5231 Int = Intrinsic::arm_neon_vld3; 5232 break; 5233 case NEON::BI__builtin_neon_vld4_dup_v: 5234 Int = Intrinsic::arm_neon_vld4; 5235 break; 5236 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5237 } 5238 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5239 Function *F = CGM.getIntrinsic(Int, Tys); 5240 llvm::Value *Align = getAlignmentValue32(PtrOp1); 5241 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup"); 5242 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5243 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5244 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5245 } 5246 switch (BuiltinID) { 5247 case NEON::BI__builtin_neon_vld2_dup_v: 5248 Int = Intrinsic::arm_neon_vld2lane; 5249 break; 5250 case NEON::BI__builtin_neon_vld3_dup_v: 5251 Int = Intrinsic::arm_neon_vld3lane; 5252 break; 5253 case NEON::BI__builtin_neon_vld4_dup_v: 5254 Int = Intrinsic::arm_neon_vld4lane; 5255 break; 5256 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5257 } 5258 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5259 Function *F = CGM.getIntrinsic(Int, Tys); 5260 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 5261 5262 SmallVector<Value*, 6> Args; 5263 Args.push_back(Ops[1]); 5264 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 5265 5266 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 5267 Args.push_back(CI); 5268 Args.push_back(getAlignmentValue32(PtrOp1)); 5269 5270 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 5271 // splat lane 0 to all elts in each vector of the result. 5272 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 5273 Value *Val = Builder.CreateExtractValue(Ops[1], i); 5274 Value *Elt = Builder.CreateBitCast(Val, Ty); 5275 Elt = EmitNeonSplat(Elt, CI); 5276 Elt = Builder.CreateBitCast(Elt, Val->getType()); 5277 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 5278 } 5279 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5280 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5281 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5282 } 5283 case NEON::BI__builtin_neon_vqrshrn_n_v: 5284 Int = 5285 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 5286 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 5287 1, true); 5288 case NEON::BI__builtin_neon_vqrshrun_n_v: 5289 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 5290 Ops, "vqrshrun_n", 1, true); 5291 case NEON::BI__builtin_neon_vqshrn_n_v: 5292 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 5293 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 5294 1, true); 5295 case NEON::BI__builtin_neon_vqshrun_n_v: 5296 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 5297 Ops, "vqshrun_n", 1, true); 5298 case NEON::BI__builtin_neon_vrecpe_v: 5299 case NEON::BI__builtin_neon_vrecpeq_v: 5300 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 5301 Ops, "vrecpe"); 5302 case NEON::BI__builtin_neon_vrshrn_n_v: 5303 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 5304 Ops, "vrshrn_n", 1, true); 5305 case NEON::BI__builtin_neon_vrsra_n_v: 5306 case NEON::BI__builtin_neon_vrsraq_n_v: 5307 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5308 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5309 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 5310 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 5311 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]}); 5312 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 5313 case NEON::BI__builtin_neon_vsri_n_v: 5314 case NEON::BI__builtin_neon_vsriq_n_v: 5315 rightShift = true; 5316 LLVM_FALLTHROUGH; 5317 case NEON::BI__builtin_neon_vsli_n_v: 5318 case NEON::BI__builtin_neon_vsliq_n_v: 5319 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 5320 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 5321 Ops, "vsli_n"); 5322 case NEON::BI__builtin_neon_vsra_n_v: 5323 case NEON::BI__builtin_neon_vsraq_n_v: 5324 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5325 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 5326 return Builder.CreateAdd(Ops[0], Ops[1]); 5327 case NEON::BI__builtin_neon_vst1q_lane_v: 5328 // Handle 64-bit integer elements as a special case. Use a shuffle to get 5329 // a one-element vector and avoid poor code for i64 in the backend. 5330 if (VTy->getElementType()->isIntegerTy(64)) { 5331 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5332 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 5333 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5334 Ops[2] = getAlignmentValue32(PtrOp0); 5335 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()}; 5336 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 5337 Tys), Ops); 5338 } 5339 // fall through 5340 case NEON::BI__builtin_neon_vst1_lane_v: { 5341 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5342 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 5343 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5344 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty)); 5345 return St; 5346 } 5347 case NEON::BI__builtin_neon_vtbl1_v: 5348 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 5349 Ops, "vtbl1"); 5350 case NEON::BI__builtin_neon_vtbl2_v: 5351 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 5352 Ops, "vtbl2"); 5353 case NEON::BI__builtin_neon_vtbl3_v: 5354 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 5355 Ops, "vtbl3"); 5356 case NEON::BI__builtin_neon_vtbl4_v: 5357 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 5358 Ops, "vtbl4"); 5359 case NEON::BI__builtin_neon_vtbx1_v: 5360 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 5361 Ops, "vtbx1"); 5362 case NEON::BI__builtin_neon_vtbx2_v: 5363 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 5364 Ops, "vtbx2"); 5365 case NEON::BI__builtin_neon_vtbx3_v: 5366 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 5367 Ops, "vtbx3"); 5368 case NEON::BI__builtin_neon_vtbx4_v: 5369 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 5370 Ops, "vtbx4"); 5371 } 5372 } 5373 5374 static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID, 5375 const CallExpr *E, 5376 SmallVectorImpl<Value *> &Ops) { 5377 unsigned int Int = 0; 5378 const char *s = nullptr; 5379 5380 switch (BuiltinID) { 5381 default: 5382 return nullptr; 5383 case NEON::BI__builtin_neon_vtbl1_v: 5384 case NEON::BI__builtin_neon_vqtbl1_v: 5385 case NEON::BI__builtin_neon_vqtbl1q_v: 5386 case NEON::BI__builtin_neon_vtbl2_v: 5387 case NEON::BI__builtin_neon_vqtbl2_v: 5388 case NEON::BI__builtin_neon_vqtbl2q_v: 5389 case NEON::BI__builtin_neon_vtbl3_v: 5390 case NEON::BI__builtin_neon_vqtbl3_v: 5391 case NEON::BI__builtin_neon_vqtbl3q_v: 5392 case NEON::BI__builtin_neon_vtbl4_v: 5393 case NEON::BI__builtin_neon_vqtbl4_v: 5394 case NEON::BI__builtin_neon_vqtbl4q_v: 5395 break; 5396 case NEON::BI__builtin_neon_vtbx1_v: 5397 case NEON::BI__builtin_neon_vqtbx1_v: 5398 case NEON::BI__builtin_neon_vqtbx1q_v: 5399 case NEON::BI__builtin_neon_vtbx2_v: 5400 case NEON::BI__builtin_neon_vqtbx2_v: 5401 case NEON::BI__builtin_neon_vqtbx2q_v: 5402 case NEON::BI__builtin_neon_vtbx3_v: 5403 case NEON::BI__builtin_neon_vqtbx3_v: 5404 case NEON::BI__builtin_neon_vqtbx3q_v: 5405 case NEON::BI__builtin_neon_vtbx4_v: 5406 case NEON::BI__builtin_neon_vqtbx4_v: 5407 case NEON::BI__builtin_neon_vqtbx4q_v: 5408 break; 5409 } 5410 5411 assert(E->getNumArgs() >= 3); 5412 5413 // Get the last argument, which specifies the vector type. 5414 llvm::APSInt Result; 5415 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 5416 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) 5417 return nullptr; 5418 5419 // Determine the type of this overloaded NEON intrinsic. 5420 NeonTypeFlags Type(Result.getZExtValue()); 5421 llvm::VectorType *Ty = GetNeonType(&CGF, Type); 5422 if (!Ty) 5423 return nullptr; 5424 5425 CodeGen::CGBuilderTy &Builder = CGF.Builder; 5426 5427 // AArch64 scalar builtins are not overloaded, they do not have an extra 5428 // argument that specifies the vector type, need to handle each case. 5429 switch (BuiltinID) { 5430 case NEON::BI__builtin_neon_vtbl1_v: { 5431 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr, 5432 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1, 5433 "vtbl1"); 5434 } 5435 case NEON::BI__builtin_neon_vtbl2_v: { 5436 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr, 5437 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1, 5438 "vtbl1"); 5439 } 5440 case NEON::BI__builtin_neon_vtbl3_v: { 5441 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr, 5442 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2, 5443 "vtbl2"); 5444 } 5445 case NEON::BI__builtin_neon_vtbl4_v: { 5446 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr, 5447 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2, 5448 "vtbl2"); 5449 } 5450 case NEON::BI__builtin_neon_vtbx1_v: { 5451 Value *TblRes = 5452 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2], 5453 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1"); 5454 5455 llvm::Constant *EightV = ConstantInt::get(Ty, 8); 5456 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); 5457 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5458 5459 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5460 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5461 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5462 } 5463 case NEON::BI__builtin_neon_vtbx2_v: { 5464 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0], 5465 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1, 5466 "vtbx1"); 5467 } 5468 case NEON::BI__builtin_neon_vtbx3_v: { 5469 Value *TblRes = 5470 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4], 5471 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2"); 5472 5473 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24); 5474 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], 5475 TwentyFourV); 5476 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5477 5478 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5479 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5480 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5481 } 5482 case NEON::BI__builtin_neon_vtbx4_v: { 5483 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0], 5484 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2, 5485 "vtbx2"); 5486 } 5487 case NEON::BI__builtin_neon_vqtbl1_v: 5488 case NEON::BI__builtin_neon_vqtbl1q_v: 5489 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break; 5490 case NEON::BI__builtin_neon_vqtbl2_v: 5491 case NEON::BI__builtin_neon_vqtbl2q_v: { 5492 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break; 5493 case NEON::BI__builtin_neon_vqtbl3_v: 5494 case NEON::BI__builtin_neon_vqtbl3q_v: 5495 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break; 5496 case NEON::BI__builtin_neon_vqtbl4_v: 5497 case NEON::BI__builtin_neon_vqtbl4q_v: 5498 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break; 5499 case NEON::BI__builtin_neon_vqtbx1_v: 5500 case NEON::BI__builtin_neon_vqtbx1q_v: 5501 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break; 5502 case NEON::BI__builtin_neon_vqtbx2_v: 5503 case NEON::BI__builtin_neon_vqtbx2q_v: 5504 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break; 5505 case NEON::BI__builtin_neon_vqtbx3_v: 5506 case NEON::BI__builtin_neon_vqtbx3q_v: 5507 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break; 5508 case NEON::BI__builtin_neon_vqtbx4_v: 5509 case NEON::BI__builtin_neon_vqtbx4q_v: 5510 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break; 5511 } 5512 } 5513 5514 if (!Int) 5515 return nullptr; 5516 5517 Function *F = CGF.CGM.getIntrinsic(Int, Ty); 5518 return CGF.EmitNeonCall(F, Ops, s); 5519 } 5520 5521 Value *CodeGenFunction::vectorWrapScalar16(Value *Op) { 5522 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4); 5523 Op = Builder.CreateBitCast(Op, Int16Ty); 5524 Value *V = UndefValue::get(VTy); 5525 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 5526 Op = Builder.CreateInsertElement(V, Op, CI); 5527 return Op; 5528 } 5529 5530 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 5531 const CallExpr *E) { 5532 unsigned HintID = static_cast<unsigned>(-1); 5533 switch (BuiltinID) { 5534 default: break; 5535 case AArch64::BI__builtin_arm_nop: 5536 HintID = 0; 5537 break; 5538 case AArch64::BI__builtin_arm_yield: 5539 HintID = 1; 5540 break; 5541 case AArch64::BI__builtin_arm_wfe: 5542 HintID = 2; 5543 break; 5544 case AArch64::BI__builtin_arm_wfi: 5545 HintID = 3; 5546 break; 5547 case AArch64::BI__builtin_arm_sev: 5548 HintID = 4; 5549 break; 5550 case AArch64::BI__builtin_arm_sevl: 5551 HintID = 5; 5552 break; 5553 } 5554 5555 if (HintID != static_cast<unsigned>(-1)) { 5556 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint); 5557 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); 5558 } 5559 5560 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { 5561 Value *Address = EmitScalarExpr(E->getArg(0)); 5562 Value *RW = EmitScalarExpr(E->getArg(1)); 5563 Value *CacheLevel = EmitScalarExpr(E->getArg(2)); 5564 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3)); 5565 Value *IsData = EmitScalarExpr(E->getArg(4)); 5566 5567 Value *Locality = nullptr; 5568 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) { 5569 // Temporal fetch, needs to convert cache level to locality. 5570 Locality = llvm::ConstantInt::get(Int32Ty, 5571 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3); 5572 } else { 5573 // Streaming fetch. 5574 Locality = llvm::ConstantInt::get(Int32Ty, 0); 5575 } 5576 5577 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify 5578 // PLDL3STRM or PLDL2STRM. 5579 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 5580 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 5581 } 5582 5583 if (BuiltinID == AArch64::BI__builtin_arm_rbit) { 5584 assert((getContext().getTypeSize(E->getType()) == 32) && 5585 "rbit of unusual size!"); 5586 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5587 return Builder.CreateCall( 5588 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5589 } 5590 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) { 5591 assert((getContext().getTypeSize(E->getType()) == 64) && 5592 "rbit of unusual size!"); 5593 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5594 return Builder.CreateCall( 5595 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5596 } 5597 5598 if (BuiltinID == AArch64::BI__clear_cache) { 5599 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 5600 const FunctionDecl *FD = E->getDirectCallee(); 5601 Value *Ops[2]; 5602 for (unsigned i = 0; i < 2; i++) 5603 Ops[i] = EmitScalarExpr(E->getArg(i)); 5604 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 5605 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 5606 StringRef Name = FD->getName(); 5607 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 5608 } 5609 5610 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex || 5611 BuiltinID == AArch64::BI__builtin_arm_ldaex) && 5612 getContext().getTypeSize(E->getType()) == 128) { 5613 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5614 ? Intrinsic::aarch64_ldaxp 5615 : Intrinsic::aarch64_ldxp); 5616 5617 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 5618 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 5619 "ldxp"); 5620 5621 Value *Val0 = Builder.CreateExtractValue(Val, 1); 5622 Value *Val1 = Builder.CreateExtractValue(Val, 0); 5623 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 5624 Val0 = Builder.CreateZExt(Val0, Int128Ty); 5625 Val1 = Builder.CreateZExt(Val1, Int128Ty); 5626 5627 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64); 5628 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 5629 Val = Builder.CreateOr(Val, Val1); 5630 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 5631 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex || 5632 BuiltinID == AArch64::BI__builtin_arm_ldaex) { 5633 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 5634 5635 QualType Ty = E->getType(); 5636 llvm::Type *RealResTy = ConvertType(Ty); 5637 llvm::Type *PtrTy = llvm::IntegerType::get( 5638 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 5639 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 5640 5641 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5642 ? Intrinsic::aarch64_ldaxr 5643 : Intrinsic::aarch64_ldxr, 5644 PtrTy); 5645 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr"); 5646 5647 if (RealResTy->isPointerTy()) 5648 return Builder.CreateIntToPtr(Val, RealResTy); 5649 5650 llvm::Type *IntResTy = llvm::IntegerType::get( 5651 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 5652 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 5653 return Builder.CreateBitCast(Val, RealResTy); 5654 } 5655 5656 if ((BuiltinID == AArch64::BI__builtin_arm_strex || 5657 BuiltinID == AArch64::BI__builtin_arm_stlex) && 5658 getContext().getTypeSize(E->getArg(0)->getType()) == 128) { 5659 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5660 ? Intrinsic::aarch64_stlxp 5661 : Intrinsic::aarch64_stxp); 5662 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty); 5663 5664 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 5665 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true); 5666 5667 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy)); 5668 llvm::Value *Val = Builder.CreateLoad(Tmp); 5669 5670 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 5671 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 5672 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), 5673 Int8PtrTy); 5674 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp"); 5675 } 5676 5677 if (BuiltinID == AArch64::BI__builtin_arm_strex || 5678 BuiltinID == AArch64::BI__builtin_arm_stlex) { 5679 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 5680 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 5681 5682 QualType Ty = E->getArg(0)->getType(); 5683 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 5684 getContext().getTypeSize(Ty)); 5685 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 5686 5687 if (StoreVal->getType()->isPointerTy()) 5688 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty); 5689 else { 5690 llvm::Type *IntTy = llvm::IntegerType::get( 5691 getLLVMContext(), 5692 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 5693 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 5694 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty); 5695 } 5696 5697 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5698 ? Intrinsic::aarch64_stlxr 5699 : Intrinsic::aarch64_stxr, 5700 StoreAddr->getType()); 5701 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr"); 5702 } 5703 5704 if (BuiltinID == AArch64::BI__builtin_arm_clrex) { 5705 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex); 5706 return Builder.CreateCall(F); 5707 } 5708 5709 // CRC32 5710 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 5711 switch (BuiltinID) { 5712 case AArch64::BI__builtin_arm_crc32b: 5713 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break; 5714 case AArch64::BI__builtin_arm_crc32cb: 5715 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break; 5716 case AArch64::BI__builtin_arm_crc32h: 5717 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break; 5718 case AArch64::BI__builtin_arm_crc32ch: 5719 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break; 5720 case AArch64::BI__builtin_arm_crc32w: 5721 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break; 5722 case AArch64::BI__builtin_arm_crc32cw: 5723 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break; 5724 case AArch64::BI__builtin_arm_crc32d: 5725 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break; 5726 case AArch64::BI__builtin_arm_crc32cd: 5727 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break; 5728 } 5729 5730 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 5731 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 5732 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 5733 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 5734 5735 llvm::Type *DataTy = F->getFunctionType()->getParamType(1); 5736 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy); 5737 5738 return Builder.CreateCall(F, {Arg0, Arg1}); 5739 } 5740 5741 if (BuiltinID == AArch64::BI__builtin_arm_rsr || 5742 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5743 BuiltinID == AArch64::BI__builtin_arm_rsrp || 5744 BuiltinID == AArch64::BI__builtin_arm_wsr || 5745 BuiltinID == AArch64::BI__builtin_arm_wsr64 || 5746 BuiltinID == AArch64::BI__builtin_arm_wsrp) { 5747 5748 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr || 5749 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5750 BuiltinID == AArch64::BI__builtin_arm_rsrp; 5751 5752 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp || 5753 BuiltinID == AArch64::BI__builtin_arm_wsrp; 5754 5755 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr && 5756 BuiltinID != AArch64::BI__builtin_arm_wsr; 5757 5758 llvm::Type *ValueType; 5759 llvm::Type *RegisterType = Int64Ty; 5760 if (IsPointerBuiltin) { 5761 ValueType = VoidPtrTy; 5762 } else if (Is64Bit) { 5763 ValueType = Int64Ty; 5764 } else { 5765 ValueType = Int32Ty; 5766 } 5767 5768 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 5769 } 5770 5771 // Find out if any arguments are required to be integer constant 5772 // expressions. 5773 unsigned ICEArguments = 0; 5774 ASTContext::GetBuiltinTypeError Error; 5775 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 5776 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 5777 5778 llvm::SmallVector<Value*, 4> Ops; 5779 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 5780 if ((ICEArguments & (1 << i)) == 0) { 5781 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5782 } else { 5783 // If this is required to be a constant, constant fold it so that we know 5784 // that the generated intrinsic gets a ConstantInt. 5785 llvm::APSInt Result; 5786 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5787 assert(IsConst && "Constant arg isn't actually constant?"); 5788 (void)IsConst; 5789 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5790 } 5791 } 5792 5793 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap); 5794 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5795 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted); 5796 5797 if (Builtin) { 5798 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1))); 5799 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E); 5800 assert(Result && "SISD intrinsic should have been handled"); 5801 return Result; 5802 } 5803 5804 llvm::APSInt Result; 5805 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5806 NeonTypeFlags Type(0); 5807 if (Arg->isIntegerConstantExpr(Result, getContext())) 5808 // Determine the type of this overloaded NEON intrinsic. 5809 Type = NeonTypeFlags(Result.getZExtValue()); 5810 5811 bool usgn = Type.isUnsigned(); 5812 bool quad = Type.isQuad(); 5813 5814 // Handle non-overloaded intrinsics first. 5815 switch (BuiltinID) { 5816 default: break; 5817 case NEON::BI__builtin_neon_vldrq_p128: { 5818 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128); 5819 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0); 5820 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy); 5821 return Builder.CreateAlignedLoad(Int128Ty, Ptr, 5822 CharUnits::fromQuantity(16)); 5823 } 5824 case NEON::BI__builtin_neon_vstrq_p128: { 5825 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128); 5826 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy); 5827 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr); 5828 } 5829 case NEON::BI__builtin_neon_vcvts_u32_f32: 5830 case NEON::BI__builtin_neon_vcvtd_u64_f64: 5831 usgn = true; 5832 // FALL THROUGH 5833 case NEON::BI__builtin_neon_vcvts_s32_f32: 5834 case NEON::BI__builtin_neon_vcvtd_s64_f64: { 5835 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5836 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5837 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5838 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5839 Ops[0] = Builder.CreateBitCast(Ops[0], FTy); 5840 if (usgn) 5841 return Builder.CreateFPToUI(Ops[0], InTy); 5842 return Builder.CreateFPToSI(Ops[0], InTy); 5843 } 5844 case NEON::BI__builtin_neon_vcvts_f32_u32: 5845 case NEON::BI__builtin_neon_vcvtd_f64_u64: 5846 usgn = true; 5847 // FALL THROUGH 5848 case NEON::BI__builtin_neon_vcvts_f32_s32: 5849 case NEON::BI__builtin_neon_vcvtd_f64_s64: { 5850 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5851 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5852 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5853 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5854 Ops[0] = Builder.CreateBitCast(Ops[0], InTy); 5855 if (usgn) 5856 return Builder.CreateUIToFP(Ops[0], FTy); 5857 return Builder.CreateSIToFP(Ops[0], FTy); 5858 } 5859 case NEON::BI__builtin_neon_vpaddd_s64: { 5860 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2); 5861 Value *Vec = EmitScalarExpr(E->getArg(0)); 5862 // The vector is v2f64, so make sure it's bitcast to that. 5863 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64"); 5864 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5865 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5866 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5867 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5868 // Pairwise addition of a v2f64 into a scalar f64. 5869 return Builder.CreateAdd(Op0, Op1, "vpaddd"); 5870 } 5871 case NEON::BI__builtin_neon_vpaddd_f64: { 5872 llvm::Type *Ty = 5873 llvm::VectorType::get(DoubleTy, 2); 5874 Value *Vec = EmitScalarExpr(E->getArg(0)); 5875 // The vector is v2f64, so make sure it's bitcast to that. 5876 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64"); 5877 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5878 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5879 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5880 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5881 // Pairwise addition of a v2f64 into a scalar f64. 5882 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5883 } 5884 case NEON::BI__builtin_neon_vpadds_f32: { 5885 llvm::Type *Ty = 5886 llvm::VectorType::get(FloatTy, 2); 5887 Value *Vec = EmitScalarExpr(E->getArg(0)); 5888 // The vector is v2f32, so make sure it's bitcast to that. 5889 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32"); 5890 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5891 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5892 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5893 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5894 // Pairwise addition of a v2f32 into a scalar f32. 5895 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5896 } 5897 case NEON::BI__builtin_neon_vceqzd_s64: 5898 case NEON::BI__builtin_neon_vceqzd_f64: 5899 case NEON::BI__builtin_neon_vceqzs_f32: 5900 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5901 return EmitAArch64CompareBuiltinExpr( 5902 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5903 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz"); 5904 case NEON::BI__builtin_neon_vcgezd_s64: 5905 case NEON::BI__builtin_neon_vcgezd_f64: 5906 case NEON::BI__builtin_neon_vcgezs_f32: 5907 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5908 return EmitAArch64CompareBuiltinExpr( 5909 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5910 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez"); 5911 case NEON::BI__builtin_neon_vclezd_s64: 5912 case NEON::BI__builtin_neon_vclezd_f64: 5913 case NEON::BI__builtin_neon_vclezs_f32: 5914 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5915 return EmitAArch64CompareBuiltinExpr( 5916 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5917 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez"); 5918 case NEON::BI__builtin_neon_vcgtzd_s64: 5919 case NEON::BI__builtin_neon_vcgtzd_f64: 5920 case NEON::BI__builtin_neon_vcgtzs_f32: 5921 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5922 return EmitAArch64CompareBuiltinExpr( 5923 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5924 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz"); 5925 case NEON::BI__builtin_neon_vcltzd_s64: 5926 case NEON::BI__builtin_neon_vcltzd_f64: 5927 case NEON::BI__builtin_neon_vcltzs_f32: 5928 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5929 return EmitAArch64CompareBuiltinExpr( 5930 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5931 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz"); 5932 5933 case NEON::BI__builtin_neon_vceqzd_u64: { 5934 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5935 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 5936 Ops[0] = 5937 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty)); 5938 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd"); 5939 } 5940 case NEON::BI__builtin_neon_vceqd_f64: 5941 case NEON::BI__builtin_neon_vcled_f64: 5942 case NEON::BI__builtin_neon_vcltd_f64: 5943 case NEON::BI__builtin_neon_vcged_f64: 5944 case NEON::BI__builtin_neon_vcgtd_f64: { 5945 llvm::CmpInst::Predicate P; 5946 switch (BuiltinID) { 5947 default: llvm_unreachable("missing builtin ID in switch!"); 5948 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break; 5949 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break; 5950 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break; 5951 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break; 5952 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break; 5953 } 5954 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5955 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 5956 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 5957 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5958 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd"); 5959 } 5960 case NEON::BI__builtin_neon_vceqs_f32: 5961 case NEON::BI__builtin_neon_vcles_f32: 5962 case NEON::BI__builtin_neon_vclts_f32: 5963 case NEON::BI__builtin_neon_vcges_f32: 5964 case NEON::BI__builtin_neon_vcgts_f32: { 5965 llvm::CmpInst::Predicate P; 5966 switch (BuiltinID) { 5967 default: llvm_unreachable("missing builtin ID in switch!"); 5968 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break; 5969 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break; 5970 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break; 5971 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break; 5972 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break; 5973 } 5974 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5975 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 5976 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy); 5977 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5978 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd"); 5979 } 5980 case NEON::BI__builtin_neon_vceqd_s64: 5981 case NEON::BI__builtin_neon_vceqd_u64: 5982 case NEON::BI__builtin_neon_vcgtd_s64: 5983 case NEON::BI__builtin_neon_vcgtd_u64: 5984 case NEON::BI__builtin_neon_vcltd_s64: 5985 case NEON::BI__builtin_neon_vcltd_u64: 5986 case NEON::BI__builtin_neon_vcged_u64: 5987 case NEON::BI__builtin_neon_vcged_s64: 5988 case NEON::BI__builtin_neon_vcled_u64: 5989 case NEON::BI__builtin_neon_vcled_s64: { 5990 llvm::CmpInst::Predicate P; 5991 switch (BuiltinID) { 5992 default: llvm_unreachable("missing builtin ID in switch!"); 5993 case NEON::BI__builtin_neon_vceqd_s64: 5994 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break; 5995 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break; 5996 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break; 5997 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break; 5998 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break; 5999 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break; 6000 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break; 6001 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break; 6002 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break; 6003 } 6004 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6005 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6006 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6007 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]); 6008 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd"); 6009 } 6010 case NEON::BI__builtin_neon_vtstd_s64: 6011 case NEON::BI__builtin_neon_vtstd_u64: { 6012 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6013 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6014 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6015 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 6016 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 6017 llvm::Constant::getNullValue(Int64Ty)); 6018 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd"); 6019 } 6020 case NEON::BI__builtin_neon_vset_lane_i8: 6021 case NEON::BI__builtin_neon_vset_lane_i16: 6022 case NEON::BI__builtin_neon_vset_lane_i32: 6023 case NEON::BI__builtin_neon_vset_lane_i64: 6024 case NEON::BI__builtin_neon_vset_lane_f32: 6025 case NEON::BI__builtin_neon_vsetq_lane_i8: 6026 case NEON::BI__builtin_neon_vsetq_lane_i16: 6027 case NEON::BI__builtin_neon_vsetq_lane_i32: 6028 case NEON::BI__builtin_neon_vsetq_lane_i64: 6029 case NEON::BI__builtin_neon_vsetq_lane_f32: 6030 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6031 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6032 case NEON::BI__builtin_neon_vset_lane_f64: 6033 // The vector type needs a cast for the v1f64 variant. 6034 Ops[1] = Builder.CreateBitCast(Ops[1], 6035 llvm::VectorType::get(DoubleTy, 1)); 6036 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6037 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6038 case NEON::BI__builtin_neon_vsetq_lane_f64: 6039 // The vector type needs a cast for the v2f64 variant. 6040 Ops[1] = Builder.CreateBitCast(Ops[1], 6041 llvm::VectorType::get(DoubleTy, 2)); 6042 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6043 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6044 6045 case NEON::BI__builtin_neon_vget_lane_i8: 6046 case NEON::BI__builtin_neon_vdupb_lane_i8: 6047 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8)); 6048 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6049 "vget_lane"); 6050 case NEON::BI__builtin_neon_vgetq_lane_i8: 6051 case NEON::BI__builtin_neon_vdupb_laneq_i8: 6052 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16)); 6053 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6054 "vgetq_lane"); 6055 case NEON::BI__builtin_neon_vget_lane_i16: 6056 case NEON::BI__builtin_neon_vduph_lane_i16: 6057 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4)); 6058 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6059 "vget_lane"); 6060 case NEON::BI__builtin_neon_vgetq_lane_i16: 6061 case NEON::BI__builtin_neon_vduph_laneq_i16: 6062 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8)); 6063 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6064 "vgetq_lane"); 6065 case NEON::BI__builtin_neon_vget_lane_i32: 6066 case NEON::BI__builtin_neon_vdups_lane_i32: 6067 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2)); 6068 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6069 "vget_lane"); 6070 case NEON::BI__builtin_neon_vdups_lane_f32: 6071 Ops[0] = Builder.CreateBitCast(Ops[0], 6072 llvm::VectorType::get(FloatTy, 2)); 6073 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6074 "vdups_lane"); 6075 case NEON::BI__builtin_neon_vgetq_lane_i32: 6076 case NEON::BI__builtin_neon_vdups_laneq_i32: 6077 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 6078 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6079 "vgetq_lane"); 6080 case NEON::BI__builtin_neon_vget_lane_i64: 6081 case NEON::BI__builtin_neon_vdupd_lane_i64: 6082 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1)); 6083 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6084 "vget_lane"); 6085 case NEON::BI__builtin_neon_vdupd_lane_f64: 6086 Ops[0] = Builder.CreateBitCast(Ops[0], 6087 llvm::VectorType::get(DoubleTy, 1)); 6088 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6089 "vdupd_lane"); 6090 case NEON::BI__builtin_neon_vgetq_lane_i64: 6091 case NEON::BI__builtin_neon_vdupd_laneq_i64: 6092 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 6093 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6094 "vgetq_lane"); 6095 case NEON::BI__builtin_neon_vget_lane_f32: 6096 Ops[0] = Builder.CreateBitCast(Ops[0], 6097 llvm::VectorType::get(FloatTy, 2)); 6098 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6099 "vget_lane"); 6100 case NEON::BI__builtin_neon_vget_lane_f64: 6101 Ops[0] = Builder.CreateBitCast(Ops[0], 6102 llvm::VectorType::get(DoubleTy, 1)); 6103 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6104 "vget_lane"); 6105 case NEON::BI__builtin_neon_vgetq_lane_f32: 6106 case NEON::BI__builtin_neon_vdups_laneq_f32: 6107 Ops[0] = Builder.CreateBitCast(Ops[0], 6108 llvm::VectorType::get(FloatTy, 4)); 6109 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6110 "vgetq_lane"); 6111 case NEON::BI__builtin_neon_vgetq_lane_f64: 6112 case NEON::BI__builtin_neon_vdupd_laneq_f64: 6113 Ops[0] = Builder.CreateBitCast(Ops[0], 6114 llvm::VectorType::get(DoubleTy, 2)); 6115 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6116 "vgetq_lane"); 6117 case NEON::BI__builtin_neon_vaddd_s64: 6118 case NEON::BI__builtin_neon_vaddd_u64: 6119 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd"); 6120 case NEON::BI__builtin_neon_vsubd_s64: 6121 case NEON::BI__builtin_neon_vsubd_u64: 6122 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd"); 6123 case NEON::BI__builtin_neon_vqdmlalh_s16: 6124 case NEON::BI__builtin_neon_vqdmlslh_s16: { 6125 SmallVector<Value *, 2> ProductOps; 6126 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6127 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2)))); 6128 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6129 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6130 ProductOps, "vqdmlXl"); 6131 Constant *CI = ConstantInt::get(SizeTy, 0); 6132 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6133 6134 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16 6135 ? Intrinsic::aarch64_neon_sqadd 6136 : Intrinsic::aarch64_neon_sqsub; 6137 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl"); 6138 } 6139 case NEON::BI__builtin_neon_vqshlud_n_s64: { 6140 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6141 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6142 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty), 6143 Ops, "vqshlu_n"); 6144 } 6145 case NEON::BI__builtin_neon_vqshld_n_u64: 6146 case NEON::BI__builtin_neon_vqshld_n_s64: { 6147 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64 6148 ? Intrinsic::aarch64_neon_uqshl 6149 : Intrinsic::aarch64_neon_sqshl; 6150 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6151 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6152 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n"); 6153 } 6154 case NEON::BI__builtin_neon_vrshrd_n_u64: 6155 case NEON::BI__builtin_neon_vrshrd_n_s64: { 6156 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64 6157 ? Intrinsic::aarch64_neon_urshl 6158 : Intrinsic::aarch64_neon_srshl; 6159 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6160 int SV = cast<ConstantInt>(Ops[1])->getSExtValue(); 6161 Ops[1] = ConstantInt::get(Int64Ty, -SV); 6162 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n"); 6163 } 6164 case NEON::BI__builtin_neon_vrsrad_n_u64: 6165 case NEON::BI__builtin_neon_vrsrad_n_s64: { 6166 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64 6167 ? Intrinsic::aarch64_neon_urshl 6168 : Intrinsic::aarch64_neon_srshl; 6169 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6170 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2)))); 6171 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty), 6172 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)}); 6173 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty)); 6174 } 6175 case NEON::BI__builtin_neon_vshld_n_s64: 6176 case NEON::BI__builtin_neon_vshld_n_u64: { 6177 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6178 return Builder.CreateShl( 6179 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n"); 6180 } 6181 case NEON::BI__builtin_neon_vshrd_n_s64: { 6182 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6183 return Builder.CreateAShr( 6184 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6185 Amt->getZExtValue())), 6186 "shrd_n"); 6187 } 6188 case NEON::BI__builtin_neon_vshrd_n_u64: { 6189 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6190 uint64_t ShiftAmt = Amt->getZExtValue(); 6191 // Right-shifting an unsigned value by its size yields 0. 6192 if (ShiftAmt == 64) 6193 return ConstantInt::get(Int64Ty, 0); 6194 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt), 6195 "shrd_n"); 6196 } 6197 case NEON::BI__builtin_neon_vsrad_n_s64: { 6198 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6199 Ops[1] = Builder.CreateAShr( 6200 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6201 Amt->getZExtValue())), 6202 "shrd_n"); 6203 return Builder.CreateAdd(Ops[0], Ops[1]); 6204 } 6205 case NEON::BI__builtin_neon_vsrad_n_u64: { 6206 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6207 uint64_t ShiftAmt = Amt->getZExtValue(); 6208 // Right-shifting an unsigned value by its size yields 0. 6209 // As Op + 0 = Op, return Ops[0] directly. 6210 if (ShiftAmt == 64) 6211 return Ops[0]; 6212 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt), 6213 "shrd_n"); 6214 return Builder.CreateAdd(Ops[0], Ops[1]); 6215 } 6216 case NEON::BI__builtin_neon_vqdmlalh_lane_s16: 6217 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16: 6218 case NEON::BI__builtin_neon_vqdmlslh_lane_s16: 6219 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: { 6220 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6221 "lane"); 6222 SmallVector<Value *, 2> ProductOps; 6223 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6224 ProductOps.push_back(vectorWrapScalar16(Ops[2])); 6225 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6226 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6227 ProductOps, "vqdmlXl"); 6228 Constant *CI = ConstantInt::get(SizeTy, 0); 6229 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6230 Ops.pop_back(); 6231 6232 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 || 6233 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16) 6234 ? Intrinsic::aarch64_neon_sqadd 6235 : Intrinsic::aarch64_neon_sqsub; 6236 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl"); 6237 } 6238 case NEON::BI__builtin_neon_vqdmlals_s32: 6239 case NEON::BI__builtin_neon_vqdmlsls_s32: { 6240 SmallVector<Value *, 2> ProductOps; 6241 ProductOps.push_back(Ops[1]); 6242 ProductOps.push_back(EmitScalarExpr(E->getArg(2))); 6243 Ops[1] = 6244 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6245 ProductOps, "vqdmlXl"); 6246 6247 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32 6248 ? Intrinsic::aarch64_neon_sqadd 6249 : Intrinsic::aarch64_neon_sqsub; 6250 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl"); 6251 } 6252 case NEON::BI__builtin_neon_vqdmlals_lane_s32: 6253 case NEON::BI__builtin_neon_vqdmlals_laneq_s32: 6254 case NEON::BI__builtin_neon_vqdmlsls_lane_s32: 6255 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: { 6256 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6257 "lane"); 6258 SmallVector<Value *, 2> ProductOps; 6259 ProductOps.push_back(Ops[1]); 6260 ProductOps.push_back(Ops[2]); 6261 Ops[1] = 6262 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6263 ProductOps, "vqdmlXl"); 6264 Ops.pop_back(); 6265 6266 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 || 6267 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32) 6268 ? Intrinsic::aarch64_neon_sqadd 6269 : Intrinsic::aarch64_neon_sqsub; 6270 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl"); 6271 } 6272 } 6273 6274 llvm::VectorType *VTy = GetNeonType(this, Type); 6275 llvm::Type *Ty = VTy; 6276 if (!Ty) 6277 return nullptr; 6278 6279 // Not all intrinsics handled by the common case work for AArch64 yet, so only 6280 // defer to common code if it's been added to our special map. 6281 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID, 6282 AArch64SIMDIntrinsicsProvenSorted); 6283 6284 if (Builtin) 6285 return EmitCommonNeonBuiltinExpr( 6286 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 6287 Builtin->NameHint, Builtin->TypeModifier, E, Ops, 6288 /*never use addresses*/ Address::invalid(), Address::invalid()); 6289 6290 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops)) 6291 return V; 6292 6293 unsigned Int; 6294 switch (BuiltinID) { 6295 default: return nullptr; 6296 case NEON::BI__builtin_neon_vbsl_v: 6297 case NEON::BI__builtin_neon_vbslq_v: { 6298 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy); 6299 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl"); 6300 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl"); 6301 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl"); 6302 6303 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl"); 6304 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl"); 6305 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl"); 6306 return Builder.CreateBitCast(Ops[0], Ty); 6307 } 6308 case NEON::BI__builtin_neon_vfma_lane_v: 6309 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types 6310 // The ARM builtins (and instructions) have the addend as the first 6311 // operand, but the 'fma' intrinsics have it last. Swap it around here. 6312 Value *Addend = Ops[0]; 6313 Value *Multiplicand = Ops[1]; 6314 Value *LaneSource = Ops[2]; 6315 Ops[0] = Multiplicand; 6316 Ops[1] = LaneSource; 6317 Ops[2] = Addend; 6318 6319 // Now adjust things to handle the lane access. 6320 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ? 6321 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) : 6322 VTy; 6323 llvm::Constant *cst = cast<Constant>(Ops[3]); 6324 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst); 6325 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy); 6326 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane"); 6327 6328 Ops.pop_back(); 6329 Int = Intrinsic::fma; 6330 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla"); 6331 } 6332 case NEON::BI__builtin_neon_vfma_laneq_v: { 6333 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 6334 // v1f64 fma should be mapped to Neon scalar f64 fma 6335 if (VTy && VTy->getElementType() == DoubleTy) { 6336 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6337 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 6338 llvm::Type *VTy = GetNeonType(this, 6339 NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 6340 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 6341 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6342 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 6343 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6344 return Builder.CreateBitCast(Result, Ty); 6345 } 6346 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6347 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6348 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6349 6350 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 6351 VTy->getNumElements() * 2); 6352 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 6353 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 6354 cast<ConstantInt>(Ops[3])); 6355 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 6356 6357 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6358 } 6359 case NEON::BI__builtin_neon_vfmaq_laneq_v: { 6360 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6361 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6362 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6363 6364 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6365 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 6366 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6367 } 6368 case NEON::BI__builtin_neon_vfmas_lane_f32: 6369 case NEON::BI__builtin_neon_vfmas_laneq_f32: 6370 case NEON::BI__builtin_neon_vfmad_lane_f64: 6371 case NEON::BI__builtin_neon_vfmad_laneq_f64: { 6372 Ops.push_back(EmitScalarExpr(E->getArg(3))); 6373 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 6374 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6375 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6376 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6377 } 6378 case NEON::BI__builtin_neon_vmull_v: 6379 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6380 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull; 6381 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull; 6382 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 6383 case NEON::BI__builtin_neon_vmax_v: 6384 case NEON::BI__builtin_neon_vmaxq_v: 6385 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6386 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax; 6387 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax; 6388 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 6389 case NEON::BI__builtin_neon_vmin_v: 6390 case NEON::BI__builtin_neon_vminq_v: 6391 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6392 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin; 6393 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin; 6394 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 6395 case NEON::BI__builtin_neon_vabd_v: 6396 case NEON::BI__builtin_neon_vabdq_v: 6397 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6398 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd; 6399 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd; 6400 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 6401 case NEON::BI__builtin_neon_vpadal_v: 6402 case NEON::BI__builtin_neon_vpadalq_v: { 6403 unsigned ArgElts = VTy->getNumElements(); 6404 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType()); 6405 unsigned BitWidth = EltTy->getBitWidth(); 6406 llvm::Type *ArgTy = llvm::VectorType::get( 6407 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts); 6408 llvm::Type* Tys[2] = { VTy, ArgTy }; 6409 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp; 6410 SmallVector<llvm::Value*, 1> TmpOps; 6411 TmpOps.push_back(Ops[1]); 6412 Function *F = CGM.getIntrinsic(Int, Tys); 6413 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal"); 6414 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType()); 6415 return Builder.CreateAdd(tmp, addend); 6416 } 6417 case NEON::BI__builtin_neon_vpmin_v: 6418 case NEON::BI__builtin_neon_vpminq_v: 6419 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6420 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp; 6421 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp; 6422 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 6423 case NEON::BI__builtin_neon_vpmax_v: 6424 case NEON::BI__builtin_neon_vpmaxq_v: 6425 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6426 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp; 6427 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp; 6428 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 6429 case NEON::BI__builtin_neon_vminnm_v: 6430 case NEON::BI__builtin_neon_vminnmq_v: 6431 Int = Intrinsic::aarch64_neon_fminnm; 6432 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 6433 case NEON::BI__builtin_neon_vmaxnm_v: 6434 case NEON::BI__builtin_neon_vmaxnmq_v: 6435 Int = Intrinsic::aarch64_neon_fmaxnm; 6436 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 6437 case NEON::BI__builtin_neon_vrecpss_f32: { 6438 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6439 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy), 6440 Ops, "vrecps"); 6441 } 6442 case NEON::BI__builtin_neon_vrecpsd_f64: { 6443 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6444 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy), 6445 Ops, "vrecps"); 6446 } 6447 case NEON::BI__builtin_neon_vqshrun_n_v: 6448 Int = Intrinsic::aarch64_neon_sqshrun; 6449 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 6450 case NEON::BI__builtin_neon_vqrshrun_n_v: 6451 Int = Intrinsic::aarch64_neon_sqrshrun; 6452 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 6453 case NEON::BI__builtin_neon_vqshrn_n_v: 6454 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn; 6455 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 6456 case NEON::BI__builtin_neon_vrshrn_n_v: 6457 Int = Intrinsic::aarch64_neon_rshrn; 6458 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 6459 case NEON::BI__builtin_neon_vqrshrn_n_v: 6460 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn; 6461 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 6462 case NEON::BI__builtin_neon_vrnda_v: 6463 case NEON::BI__builtin_neon_vrndaq_v: { 6464 Int = Intrinsic::round; 6465 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); 6466 } 6467 case NEON::BI__builtin_neon_vrndi_v: 6468 case NEON::BI__builtin_neon_vrndiq_v: { 6469 Int = Intrinsic::nearbyint; 6470 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); 6471 } 6472 case NEON::BI__builtin_neon_vrndm_v: 6473 case NEON::BI__builtin_neon_vrndmq_v: { 6474 Int = Intrinsic::floor; 6475 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); 6476 } 6477 case NEON::BI__builtin_neon_vrndn_v: 6478 case NEON::BI__builtin_neon_vrndnq_v: { 6479 Int = Intrinsic::aarch64_neon_frintn; 6480 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); 6481 } 6482 case NEON::BI__builtin_neon_vrndp_v: 6483 case NEON::BI__builtin_neon_vrndpq_v: { 6484 Int = Intrinsic::ceil; 6485 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); 6486 } 6487 case NEON::BI__builtin_neon_vrndx_v: 6488 case NEON::BI__builtin_neon_vrndxq_v: { 6489 Int = Intrinsic::rint; 6490 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); 6491 } 6492 case NEON::BI__builtin_neon_vrnd_v: 6493 case NEON::BI__builtin_neon_vrndq_v: { 6494 Int = Intrinsic::trunc; 6495 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz"); 6496 } 6497 case NEON::BI__builtin_neon_vceqz_v: 6498 case NEON::BI__builtin_neon_vceqzq_v: 6499 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, 6500 ICmpInst::ICMP_EQ, "vceqz"); 6501 case NEON::BI__builtin_neon_vcgez_v: 6502 case NEON::BI__builtin_neon_vcgezq_v: 6503 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, 6504 ICmpInst::ICMP_SGE, "vcgez"); 6505 case NEON::BI__builtin_neon_vclez_v: 6506 case NEON::BI__builtin_neon_vclezq_v: 6507 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, 6508 ICmpInst::ICMP_SLE, "vclez"); 6509 case NEON::BI__builtin_neon_vcgtz_v: 6510 case NEON::BI__builtin_neon_vcgtzq_v: 6511 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, 6512 ICmpInst::ICMP_SGT, "vcgtz"); 6513 case NEON::BI__builtin_neon_vcltz_v: 6514 case NEON::BI__builtin_neon_vcltzq_v: 6515 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, 6516 ICmpInst::ICMP_SLT, "vcltz"); 6517 case NEON::BI__builtin_neon_vcvt_f64_v: 6518 case NEON::BI__builtin_neon_vcvtq_f64_v: 6519 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6520 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 6521 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 6522 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 6523 case NEON::BI__builtin_neon_vcvt_f64_f32: { 6524 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad && 6525 "unexpected vcvt_f64_f32 builtin"); 6526 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false); 6527 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6528 6529 return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); 6530 } 6531 case NEON::BI__builtin_neon_vcvt_f32_f64: { 6532 assert(Type.getEltType() == NeonTypeFlags::Float32 && 6533 "unexpected vcvt_f32_f64 builtin"); 6534 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); 6535 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6536 6537 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); 6538 } 6539 case NEON::BI__builtin_neon_vcvt_s32_v: 6540 case NEON::BI__builtin_neon_vcvt_u32_v: 6541 case NEON::BI__builtin_neon_vcvt_s64_v: 6542 case NEON::BI__builtin_neon_vcvt_u64_v: 6543 case NEON::BI__builtin_neon_vcvtq_s32_v: 6544 case NEON::BI__builtin_neon_vcvtq_u32_v: 6545 case NEON::BI__builtin_neon_vcvtq_s64_v: 6546 case NEON::BI__builtin_neon_vcvtq_u64_v: { 6547 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 6548 if (usgn) 6549 return Builder.CreateFPToUI(Ops[0], Ty); 6550 return Builder.CreateFPToSI(Ops[0], Ty); 6551 } 6552 case NEON::BI__builtin_neon_vcvta_s32_v: 6553 case NEON::BI__builtin_neon_vcvtaq_s32_v: 6554 case NEON::BI__builtin_neon_vcvta_u32_v: 6555 case NEON::BI__builtin_neon_vcvtaq_u32_v: 6556 case NEON::BI__builtin_neon_vcvta_s64_v: 6557 case NEON::BI__builtin_neon_vcvtaq_s64_v: 6558 case NEON::BI__builtin_neon_vcvta_u64_v: 6559 case NEON::BI__builtin_neon_vcvtaq_u64_v: { 6560 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas; 6561 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6562 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta"); 6563 } 6564 case NEON::BI__builtin_neon_vcvtm_s32_v: 6565 case NEON::BI__builtin_neon_vcvtmq_s32_v: 6566 case NEON::BI__builtin_neon_vcvtm_u32_v: 6567 case NEON::BI__builtin_neon_vcvtmq_u32_v: 6568 case NEON::BI__builtin_neon_vcvtm_s64_v: 6569 case NEON::BI__builtin_neon_vcvtmq_s64_v: 6570 case NEON::BI__builtin_neon_vcvtm_u64_v: 6571 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 6572 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms; 6573 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6574 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm"); 6575 } 6576 case NEON::BI__builtin_neon_vcvtn_s32_v: 6577 case NEON::BI__builtin_neon_vcvtnq_s32_v: 6578 case NEON::BI__builtin_neon_vcvtn_u32_v: 6579 case NEON::BI__builtin_neon_vcvtnq_u32_v: 6580 case NEON::BI__builtin_neon_vcvtn_s64_v: 6581 case NEON::BI__builtin_neon_vcvtnq_s64_v: 6582 case NEON::BI__builtin_neon_vcvtn_u64_v: 6583 case NEON::BI__builtin_neon_vcvtnq_u64_v: { 6584 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns; 6585 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6586 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn"); 6587 } 6588 case NEON::BI__builtin_neon_vcvtp_s32_v: 6589 case NEON::BI__builtin_neon_vcvtpq_s32_v: 6590 case NEON::BI__builtin_neon_vcvtp_u32_v: 6591 case NEON::BI__builtin_neon_vcvtpq_u32_v: 6592 case NEON::BI__builtin_neon_vcvtp_s64_v: 6593 case NEON::BI__builtin_neon_vcvtpq_s64_v: 6594 case NEON::BI__builtin_neon_vcvtp_u64_v: 6595 case NEON::BI__builtin_neon_vcvtpq_u64_v: { 6596 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps; 6597 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6598 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp"); 6599 } 6600 case NEON::BI__builtin_neon_vmulx_v: 6601 case NEON::BI__builtin_neon_vmulxq_v: { 6602 Int = Intrinsic::aarch64_neon_fmulx; 6603 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 6604 } 6605 case NEON::BI__builtin_neon_vmul_lane_v: 6606 case NEON::BI__builtin_neon_vmul_laneq_v: { 6607 // v1f64 vmul_lane should be mapped to Neon scalar mul lane 6608 bool Quad = false; 6609 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v) 6610 Quad = true; 6611 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6612 llvm::Type *VTy = GetNeonType(this, 6613 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); 6614 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 6615 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); 6616 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); 6617 return Builder.CreateBitCast(Result, Ty); 6618 } 6619 case NEON::BI__builtin_neon_vnegd_s64: 6620 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd"); 6621 case NEON::BI__builtin_neon_vpmaxnm_v: 6622 case NEON::BI__builtin_neon_vpmaxnmq_v: { 6623 Int = Intrinsic::aarch64_neon_fmaxnmp; 6624 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 6625 } 6626 case NEON::BI__builtin_neon_vpminnm_v: 6627 case NEON::BI__builtin_neon_vpminnmq_v: { 6628 Int = Intrinsic::aarch64_neon_fminnmp; 6629 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 6630 } 6631 case NEON::BI__builtin_neon_vsqrt_v: 6632 case NEON::BI__builtin_neon_vsqrtq_v: { 6633 Int = Intrinsic::sqrt; 6634 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6635 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); 6636 } 6637 case NEON::BI__builtin_neon_vrbit_v: 6638 case NEON::BI__builtin_neon_vrbitq_v: { 6639 Int = Intrinsic::aarch64_neon_rbit; 6640 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); 6641 } 6642 case NEON::BI__builtin_neon_vaddv_u8: 6643 // FIXME: These are handled by the AArch64 scalar code. 6644 usgn = true; 6645 // FALLTHROUGH 6646 case NEON::BI__builtin_neon_vaddv_s8: { 6647 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6648 Ty = Int32Ty; 6649 VTy = llvm::VectorType::get(Int8Ty, 8); 6650 llvm::Type *Tys[2] = { Ty, VTy }; 6651 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6652 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6653 return Builder.CreateTrunc(Ops[0], Int8Ty); 6654 } 6655 case NEON::BI__builtin_neon_vaddv_u16: 6656 usgn = true; 6657 // FALLTHROUGH 6658 case NEON::BI__builtin_neon_vaddv_s16: { 6659 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6660 Ty = Int32Ty; 6661 VTy = llvm::VectorType::get(Int16Ty, 4); 6662 llvm::Type *Tys[2] = { Ty, VTy }; 6663 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6664 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6665 return Builder.CreateTrunc(Ops[0], Int16Ty); 6666 } 6667 case NEON::BI__builtin_neon_vaddvq_u8: 6668 usgn = true; 6669 // FALLTHROUGH 6670 case NEON::BI__builtin_neon_vaddvq_s8: { 6671 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6672 Ty = Int32Ty; 6673 VTy = llvm::VectorType::get(Int8Ty, 16); 6674 llvm::Type *Tys[2] = { Ty, VTy }; 6675 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6676 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6677 return Builder.CreateTrunc(Ops[0], Int8Ty); 6678 } 6679 case NEON::BI__builtin_neon_vaddvq_u16: 6680 usgn = true; 6681 // FALLTHROUGH 6682 case NEON::BI__builtin_neon_vaddvq_s16: { 6683 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6684 Ty = Int32Ty; 6685 VTy = llvm::VectorType::get(Int16Ty, 8); 6686 llvm::Type *Tys[2] = { Ty, VTy }; 6687 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6688 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6689 return Builder.CreateTrunc(Ops[0], Int16Ty); 6690 } 6691 case NEON::BI__builtin_neon_vmaxv_u8: { 6692 Int = Intrinsic::aarch64_neon_umaxv; 6693 Ty = Int32Ty; 6694 VTy = llvm::VectorType::get(Int8Ty, 8); 6695 llvm::Type *Tys[2] = { Ty, VTy }; 6696 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6697 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6698 return Builder.CreateTrunc(Ops[0], Int8Ty); 6699 } 6700 case NEON::BI__builtin_neon_vmaxv_u16: { 6701 Int = Intrinsic::aarch64_neon_umaxv; 6702 Ty = Int32Ty; 6703 VTy = llvm::VectorType::get(Int16Ty, 4); 6704 llvm::Type *Tys[2] = { Ty, VTy }; 6705 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6706 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6707 return Builder.CreateTrunc(Ops[0], Int16Ty); 6708 } 6709 case NEON::BI__builtin_neon_vmaxvq_u8: { 6710 Int = Intrinsic::aarch64_neon_umaxv; 6711 Ty = Int32Ty; 6712 VTy = llvm::VectorType::get(Int8Ty, 16); 6713 llvm::Type *Tys[2] = { Ty, VTy }; 6714 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6715 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6716 return Builder.CreateTrunc(Ops[0], Int8Ty); 6717 } 6718 case NEON::BI__builtin_neon_vmaxvq_u16: { 6719 Int = Intrinsic::aarch64_neon_umaxv; 6720 Ty = Int32Ty; 6721 VTy = llvm::VectorType::get(Int16Ty, 8); 6722 llvm::Type *Tys[2] = { Ty, VTy }; 6723 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6724 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6725 return Builder.CreateTrunc(Ops[0], Int16Ty); 6726 } 6727 case NEON::BI__builtin_neon_vmaxv_s8: { 6728 Int = Intrinsic::aarch64_neon_smaxv; 6729 Ty = Int32Ty; 6730 VTy = llvm::VectorType::get(Int8Ty, 8); 6731 llvm::Type *Tys[2] = { Ty, VTy }; 6732 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6733 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6734 return Builder.CreateTrunc(Ops[0], Int8Ty); 6735 } 6736 case NEON::BI__builtin_neon_vmaxv_s16: { 6737 Int = Intrinsic::aarch64_neon_smaxv; 6738 Ty = Int32Ty; 6739 VTy = llvm::VectorType::get(Int16Ty, 4); 6740 llvm::Type *Tys[2] = { Ty, VTy }; 6741 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6742 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6743 return Builder.CreateTrunc(Ops[0], Int16Ty); 6744 } 6745 case NEON::BI__builtin_neon_vmaxvq_s8: { 6746 Int = Intrinsic::aarch64_neon_smaxv; 6747 Ty = Int32Ty; 6748 VTy = llvm::VectorType::get(Int8Ty, 16); 6749 llvm::Type *Tys[2] = { Ty, VTy }; 6750 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6751 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6752 return Builder.CreateTrunc(Ops[0], Int8Ty); 6753 } 6754 case NEON::BI__builtin_neon_vmaxvq_s16: { 6755 Int = Intrinsic::aarch64_neon_smaxv; 6756 Ty = Int32Ty; 6757 VTy = llvm::VectorType::get(Int16Ty, 8); 6758 llvm::Type *Tys[2] = { Ty, VTy }; 6759 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6760 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6761 return Builder.CreateTrunc(Ops[0], Int16Ty); 6762 } 6763 case NEON::BI__builtin_neon_vminv_u8: { 6764 Int = Intrinsic::aarch64_neon_uminv; 6765 Ty = Int32Ty; 6766 VTy = llvm::VectorType::get(Int8Ty, 8); 6767 llvm::Type *Tys[2] = { Ty, VTy }; 6768 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6769 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6770 return Builder.CreateTrunc(Ops[0], Int8Ty); 6771 } 6772 case NEON::BI__builtin_neon_vminv_u16: { 6773 Int = Intrinsic::aarch64_neon_uminv; 6774 Ty = Int32Ty; 6775 VTy = llvm::VectorType::get(Int16Ty, 4); 6776 llvm::Type *Tys[2] = { Ty, VTy }; 6777 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6778 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6779 return Builder.CreateTrunc(Ops[0], Int16Ty); 6780 } 6781 case NEON::BI__builtin_neon_vminvq_u8: { 6782 Int = Intrinsic::aarch64_neon_uminv; 6783 Ty = Int32Ty; 6784 VTy = llvm::VectorType::get(Int8Ty, 16); 6785 llvm::Type *Tys[2] = { Ty, VTy }; 6786 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6787 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6788 return Builder.CreateTrunc(Ops[0], Int8Ty); 6789 } 6790 case NEON::BI__builtin_neon_vminvq_u16: { 6791 Int = Intrinsic::aarch64_neon_uminv; 6792 Ty = Int32Ty; 6793 VTy = llvm::VectorType::get(Int16Ty, 8); 6794 llvm::Type *Tys[2] = { Ty, VTy }; 6795 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6796 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6797 return Builder.CreateTrunc(Ops[0], Int16Ty); 6798 } 6799 case NEON::BI__builtin_neon_vminv_s8: { 6800 Int = Intrinsic::aarch64_neon_sminv; 6801 Ty = Int32Ty; 6802 VTy = llvm::VectorType::get(Int8Ty, 8); 6803 llvm::Type *Tys[2] = { Ty, VTy }; 6804 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6805 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6806 return Builder.CreateTrunc(Ops[0], Int8Ty); 6807 } 6808 case NEON::BI__builtin_neon_vminv_s16: { 6809 Int = Intrinsic::aarch64_neon_sminv; 6810 Ty = Int32Ty; 6811 VTy = llvm::VectorType::get(Int16Ty, 4); 6812 llvm::Type *Tys[2] = { Ty, VTy }; 6813 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6814 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6815 return Builder.CreateTrunc(Ops[0], Int16Ty); 6816 } 6817 case NEON::BI__builtin_neon_vminvq_s8: { 6818 Int = Intrinsic::aarch64_neon_sminv; 6819 Ty = Int32Ty; 6820 VTy = llvm::VectorType::get(Int8Ty, 16); 6821 llvm::Type *Tys[2] = { Ty, VTy }; 6822 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6823 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6824 return Builder.CreateTrunc(Ops[0], Int8Ty); 6825 } 6826 case NEON::BI__builtin_neon_vminvq_s16: { 6827 Int = Intrinsic::aarch64_neon_sminv; 6828 Ty = Int32Ty; 6829 VTy = llvm::VectorType::get(Int16Ty, 8); 6830 llvm::Type *Tys[2] = { Ty, VTy }; 6831 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6832 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6833 return Builder.CreateTrunc(Ops[0], Int16Ty); 6834 } 6835 case NEON::BI__builtin_neon_vmul_n_f64: { 6836 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6837 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy); 6838 return Builder.CreateFMul(Ops[0], RHS); 6839 } 6840 case NEON::BI__builtin_neon_vaddlv_u8: { 6841 Int = Intrinsic::aarch64_neon_uaddlv; 6842 Ty = Int32Ty; 6843 VTy = llvm::VectorType::get(Int8Ty, 8); 6844 llvm::Type *Tys[2] = { Ty, VTy }; 6845 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6846 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6847 return Builder.CreateTrunc(Ops[0], Int16Ty); 6848 } 6849 case NEON::BI__builtin_neon_vaddlv_u16: { 6850 Int = Intrinsic::aarch64_neon_uaddlv; 6851 Ty = Int32Ty; 6852 VTy = llvm::VectorType::get(Int16Ty, 4); 6853 llvm::Type *Tys[2] = { Ty, VTy }; 6854 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6855 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6856 } 6857 case NEON::BI__builtin_neon_vaddlvq_u8: { 6858 Int = Intrinsic::aarch64_neon_uaddlv; 6859 Ty = Int32Ty; 6860 VTy = llvm::VectorType::get(Int8Ty, 16); 6861 llvm::Type *Tys[2] = { Ty, VTy }; 6862 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6863 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6864 return Builder.CreateTrunc(Ops[0], Int16Ty); 6865 } 6866 case NEON::BI__builtin_neon_vaddlvq_u16: { 6867 Int = Intrinsic::aarch64_neon_uaddlv; 6868 Ty = Int32Ty; 6869 VTy = llvm::VectorType::get(Int16Ty, 8); 6870 llvm::Type *Tys[2] = { Ty, VTy }; 6871 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6872 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6873 } 6874 case NEON::BI__builtin_neon_vaddlv_s8: { 6875 Int = Intrinsic::aarch64_neon_saddlv; 6876 Ty = Int32Ty; 6877 VTy = llvm::VectorType::get(Int8Ty, 8); 6878 llvm::Type *Tys[2] = { Ty, VTy }; 6879 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6880 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6881 return Builder.CreateTrunc(Ops[0], Int16Ty); 6882 } 6883 case NEON::BI__builtin_neon_vaddlv_s16: { 6884 Int = Intrinsic::aarch64_neon_saddlv; 6885 Ty = Int32Ty; 6886 VTy = llvm::VectorType::get(Int16Ty, 4); 6887 llvm::Type *Tys[2] = { Ty, VTy }; 6888 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6889 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6890 } 6891 case NEON::BI__builtin_neon_vaddlvq_s8: { 6892 Int = Intrinsic::aarch64_neon_saddlv; 6893 Ty = Int32Ty; 6894 VTy = llvm::VectorType::get(Int8Ty, 16); 6895 llvm::Type *Tys[2] = { Ty, VTy }; 6896 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6897 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6898 return Builder.CreateTrunc(Ops[0], Int16Ty); 6899 } 6900 case NEON::BI__builtin_neon_vaddlvq_s16: { 6901 Int = Intrinsic::aarch64_neon_saddlv; 6902 Ty = Int32Ty; 6903 VTy = llvm::VectorType::get(Int16Ty, 8); 6904 llvm::Type *Tys[2] = { Ty, VTy }; 6905 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6906 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6907 } 6908 case NEON::BI__builtin_neon_vsri_n_v: 6909 case NEON::BI__builtin_neon_vsriq_n_v: { 6910 Int = Intrinsic::aarch64_neon_vsri; 6911 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6912 return EmitNeonCall(Intrin, Ops, "vsri_n"); 6913 } 6914 case NEON::BI__builtin_neon_vsli_n_v: 6915 case NEON::BI__builtin_neon_vsliq_n_v: { 6916 Int = Intrinsic::aarch64_neon_vsli; 6917 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6918 return EmitNeonCall(Intrin, Ops, "vsli_n"); 6919 } 6920 case NEON::BI__builtin_neon_vsra_n_v: 6921 case NEON::BI__builtin_neon_vsraq_n_v: 6922 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6923 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 6924 return Builder.CreateAdd(Ops[0], Ops[1]); 6925 case NEON::BI__builtin_neon_vrsra_n_v: 6926 case NEON::BI__builtin_neon_vrsraq_n_v: { 6927 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl; 6928 SmallVector<llvm::Value*,2> TmpOps; 6929 TmpOps.push_back(Ops[1]); 6930 TmpOps.push_back(Ops[2]); 6931 Function* F = CGM.getIntrinsic(Int, Ty); 6932 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true); 6933 Ops[0] = Builder.CreateBitCast(Ops[0], VTy); 6934 return Builder.CreateAdd(Ops[0], tmp); 6935 } 6936 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence 6937 // of an Align parameter here. 6938 case NEON::BI__builtin_neon_vld1_x2_v: 6939 case NEON::BI__builtin_neon_vld1q_x2_v: 6940 case NEON::BI__builtin_neon_vld1_x3_v: 6941 case NEON::BI__builtin_neon_vld1q_x3_v: 6942 case NEON::BI__builtin_neon_vld1_x4_v: 6943 case NEON::BI__builtin_neon_vld1q_x4_v: { 6944 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6945 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6946 llvm::Type *Tys[2] = { VTy, PTy }; 6947 unsigned Int; 6948 switch (BuiltinID) { 6949 case NEON::BI__builtin_neon_vld1_x2_v: 6950 case NEON::BI__builtin_neon_vld1q_x2_v: 6951 Int = Intrinsic::aarch64_neon_ld1x2; 6952 break; 6953 case NEON::BI__builtin_neon_vld1_x3_v: 6954 case NEON::BI__builtin_neon_vld1q_x3_v: 6955 Int = Intrinsic::aarch64_neon_ld1x3; 6956 break; 6957 case NEON::BI__builtin_neon_vld1_x4_v: 6958 case NEON::BI__builtin_neon_vld1q_x4_v: 6959 Int = Intrinsic::aarch64_neon_ld1x4; 6960 break; 6961 } 6962 Function *F = CGM.getIntrinsic(Int, Tys); 6963 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN"); 6964 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6965 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6966 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6967 } 6968 case NEON::BI__builtin_neon_vst1_x2_v: 6969 case NEON::BI__builtin_neon_vst1q_x2_v: 6970 case NEON::BI__builtin_neon_vst1_x3_v: 6971 case NEON::BI__builtin_neon_vst1q_x3_v: 6972 case NEON::BI__builtin_neon_vst1_x4_v: 6973 case NEON::BI__builtin_neon_vst1q_x4_v: { 6974 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6975 llvm::Type *Tys[2] = { VTy, PTy }; 6976 unsigned Int; 6977 switch (BuiltinID) { 6978 case NEON::BI__builtin_neon_vst1_x2_v: 6979 case NEON::BI__builtin_neon_vst1q_x2_v: 6980 Int = Intrinsic::aarch64_neon_st1x2; 6981 break; 6982 case NEON::BI__builtin_neon_vst1_x3_v: 6983 case NEON::BI__builtin_neon_vst1q_x3_v: 6984 Int = Intrinsic::aarch64_neon_st1x3; 6985 break; 6986 case NEON::BI__builtin_neon_vst1_x4_v: 6987 case NEON::BI__builtin_neon_vst1q_x4_v: 6988 Int = Intrinsic::aarch64_neon_st1x4; 6989 break; 6990 } 6991 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end()); 6992 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 6993 } 6994 case NEON::BI__builtin_neon_vld1_v: 6995 case NEON::BI__builtin_neon_vld1q_v: { 6996 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 6997 auto Alignment = CharUnits::fromQuantity( 6998 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16); 6999 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment); 7000 } 7001 case NEON::BI__builtin_neon_vst1_v: 7002 case NEON::BI__builtin_neon_vst1q_v: 7003 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 7004 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 7005 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7006 case NEON::BI__builtin_neon_vld1_lane_v: 7007 case NEON::BI__builtin_neon_vld1q_lane_v: { 7008 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7009 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7010 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7011 auto Alignment = CharUnits::fromQuantity( 7012 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16); 7013 Ops[0] = 7014 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7015 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane"); 7016 } 7017 case NEON::BI__builtin_neon_vld1_dup_v: 7018 case NEON::BI__builtin_neon_vld1q_dup_v: { 7019 Value *V = UndefValue::get(Ty); 7020 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7021 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7022 auto Alignment = CharUnits::fromQuantity( 7023 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16); 7024 Ops[0] = 7025 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7026 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 7027 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI); 7028 return EmitNeonSplat(Ops[0], CI); 7029 } 7030 case NEON::BI__builtin_neon_vst1_lane_v: 7031 case NEON::BI__builtin_neon_vst1q_lane_v: 7032 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7033 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 7034 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7035 return Builder.CreateDefaultAlignedStore(Ops[1], 7036 Builder.CreateBitCast(Ops[0], Ty)); 7037 case NEON::BI__builtin_neon_vld2_v: 7038 case NEON::BI__builtin_neon_vld2q_v: { 7039 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7040 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7041 llvm::Type *Tys[2] = { VTy, PTy }; 7042 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys); 7043 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7044 Ops[0] = Builder.CreateBitCast(Ops[0], 7045 llvm::PointerType::getUnqual(Ops[1]->getType())); 7046 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7047 } 7048 case NEON::BI__builtin_neon_vld3_v: 7049 case NEON::BI__builtin_neon_vld3q_v: { 7050 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7051 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7052 llvm::Type *Tys[2] = { VTy, PTy }; 7053 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys); 7054 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7055 Ops[0] = Builder.CreateBitCast(Ops[0], 7056 llvm::PointerType::getUnqual(Ops[1]->getType())); 7057 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7058 } 7059 case NEON::BI__builtin_neon_vld4_v: 7060 case NEON::BI__builtin_neon_vld4q_v: { 7061 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7062 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7063 llvm::Type *Tys[2] = { VTy, PTy }; 7064 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys); 7065 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7066 Ops[0] = Builder.CreateBitCast(Ops[0], 7067 llvm::PointerType::getUnqual(Ops[1]->getType())); 7068 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7069 } 7070 case NEON::BI__builtin_neon_vld2_dup_v: 7071 case NEON::BI__builtin_neon_vld2q_dup_v: { 7072 llvm::Type *PTy = 7073 llvm::PointerType::getUnqual(VTy->getElementType()); 7074 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7075 llvm::Type *Tys[2] = { VTy, PTy }; 7076 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys); 7077 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7078 Ops[0] = Builder.CreateBitCast(Ops[0], 7079 llvm::PointerType::getUnqual(Ops[1]->getType())); 7080 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7081 } 7082 case NEON::BI__builtin_neon_vld3_dup_v: 7083 case NEON::BI__builtin_neon_vld3q_dup_v: { 7084 llvm::Type *PTy = 7085 llvm::PointerType::getUnqual(VTy->getElementType()); 7086 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7087 llvm::Type *Tys[2] = { VTy, PTy }; 7088 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys); 7089 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7090 Ops[0] = Builder.CreateBitCast(Ops[0], 7091 llvm::PointerType::getUnqual(Ops[1]->getType())); 7092 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7093 } 7094 case NEON::BI__builtin_neon_vld4_dup_v: 7095 case NEON::BI__builtin_neon_vld4q_dup_v: { 7096 llvm::Type *PTy = 7097 llvm::PointerType::getUnqual(VTy->getElementType()); 7098 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7099 llvm::Type *Tys[2] = { VTy, PTy }; 7100 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys); 7101 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7102 Ops[0] = Builder.CreateBitCast(Ops[0], 7103 llvm::PointerType::getUnqual(Ops[1]->getType())); 7104 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7105 } 7106 case NEON::BI__builtin_neon_vld2_lane_v: 7107 case NEON::BI__builtin_neon_vld2q_lane_v: { 7108 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7109 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys); 7110 Ops.push_back(Ops[1]); 7111 Ops.erase(Ops.begin()+1); 7112 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7113 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7114 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7115 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 7116 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7117 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7118 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7119 } 7120 case NEON::BI__builtin_neon_vld3_lane_v: 7121 case NEON::BI__builtin_neon_vld3q_lane_v: { 7122 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7123 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys); 7124 Ops.push_back(Ops[1]); 7125 Ops.erase(Ops.begin()+1); 7126 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7127 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7128 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7129 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7130 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 7131 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7132 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7133 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7134 } 7135 case NEON::BI__builtin_neon_vld4_lane_v: 7136 case NEON::BI__builtin_neon_vld4q_lane_v: { 7137 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7138 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys); 7139 Ops.push_back(Ops[1]); 7140 Ops.erase(Ops.begin()+1); 7141 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7142 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7143 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7144 Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 7145 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty); 7146 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane"); 7147 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7148 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7149 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7150 } 7151 case NEON::BI__builtin_neon_vst2_v: 7152 case NEON::BI__builtin_neon_vst2q_v: { 7153 Ops.push_back(Ops[0]); 7154 Ops.erase(Ops.begin()); 7155 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() }; 7156 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys), 7157 Ops, ""); 7158 } 7159 case NEON::BI__builtin_neon_vst2_lane_v: 7160 case NEON::BI__builtin_neon_vst2q_lane_v: { 7161 Ops.push_back(Ops[0]); 7162 Ops.erase(Ops.begin()); 7163 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty); 7164 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7165 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys), 7166 Ops, ""); 7167 } 7168 case NEON::BI__builtin_neon_vst3_v: 7169 case NEON::BI__builtin_neon_vst3q_v: { 7170 Ops.push_back(Ops[0]); 7171 Ops.erase(Ops.begin()); 7172 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7173 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys), 7174 Ops, ""); 7175 } 7176 case NEON::BI__builtin_neon_vst3_lane_v: 7177 case NEON::BI__builtin_neon_vst3q_lane_v: { 7178 Ops.push_back(Ops[0]); 7179 Ops.erase(Ops.begin()); 7180 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7181 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7182 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys), 7183 Ops, ""); 7184 } 7185 case NEON::BI__builtin_neon_vst4_v: 7186 case NEON::BI__builtin_neon_vst4q_v: { 7187 Ops.push_back(Ops[0]); 7188 Ops.erase(Ops.begin()); 7189 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7190 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys), 7191 Ops, ""); 7192 } 7193 case NEON::BI__builtin_neon_vst4_lane_v: 7194 case NEON::BI__builtin_neon_vst4q_lane_v: { 7195 Ops.push_back(Ops[0]); 7196 Ops.erase(Ops.begin()); 7197 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7198 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() }; 7199 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys), 7200 Ops, ""); 7201 } 7202 case NEON::BI__builtin_neon_vtrn_v: 7203 case NEON::BI__builtin_neon_vtrnq_v: { 7204 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7205 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7206 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7207 Value *SV = nullptr; 7208 7209 for (unsigned vi = 0; vi != 2; ++vi) { 7210 SmallVector<uint32_t, 16> Indices; 7211 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7212 Indices.push_back(i+vi); 7213 Indices.push_back(i+e+vi); 7214 } 7215 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7216 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 7217 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7218 } 7219 return SV; 7220 } 7221 case NEON::BI__builtin_neon_vuzp_v: 7222 case NEON::BI__builtin_neon_vuzpq_v: { 7223 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7224 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7225 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7226 Value *SV = nullptr; 7227 7228 for (unsigned vi = 0; vi != 2; ++vi) { 7229 SmallVector<uint32_t, 16> Indices; 7230 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 7231 Indices.push_back(2*i+vi); 7232 7233 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7234 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 7235 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7236 } 7237 return SV; 7238 } 7239 case NEON::BI__builtin_neon_vzip_v: 7240 case NEON::BI__builtin_neon_vzipq_v: { 7241 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7242 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7243 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7244 Value *SV = nullptr; 7245 7246 for (unsigned vi = 0; vi != 2; ++vi) { 7247 SmallVector<uint32_t, 16> Indices; 7248 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7249 Indices.push_back((i + vi*e) >> 1); 7250 Indices.push_back(((i + vi*e) >> 1)+e); 7251 } 7252 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7253 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 7254 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7255 } 7256 return SV; 7257 } 7258 case NEON::BI__builtin_neon_vqtbl1q_v: { 7259 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty), 7260 Ops, "vtbl1"); 7261 } 7262 case NEON::BI__builtin_neon_vqtbl2q_v: { 7263 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty), 7264 Ops, "vtbl2"); 7265 } 7266 case NEON::BI__builtin_neon_vqtbl3q_v: { 7267 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty), 7268 Ops, "vtbl3"); 7269 } 7270 case NEON::BI__builtin_neon_vqtbl4q_v: { 7271 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty), 7272 Ops, "vtbl4"); 7273 } 7274 case NEON::BI__builtin_neon_vqtbx1q_v: { 7275 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty), 7276 Ops, "vtbx1"); 7277 } 7278 case NEON::BI__builtin_neon_vqtbx2q_v: { 7279 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty), 7280 Ops, "vtbx2"); 7281 } 7282 case NEON::BI__builtin_neon_vqtbx3q_v: { 7283 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty), 7284 Ops, "vtbx3"); 7285 } 7286 case NEON::BI__builtin_neon_vqtbx4q_v: { 7287 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty), 7288 Ops, "vtbx4"); 7289 } 7290 case NEON::BI__builtin_neon_vsqadd_v: 7291 case NEON::BI__builtin_neon_vsqaddq_v: { 7292 Int = Intrinsic::aarch64_neon_usqadd; 7293 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); 7294 } 7295 case NEON::BI__builtin_neon_vuqadd_v: 7296 case NEON::BI__builtin_neon_vuqaddq_v: { 7297 Int = Intrinsic::aarch64_neon_suqadd; 7298 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); 7299 } 7300 } 7301 } 7302 7303 llvm::Value *CodeGenFunction:: 7304 BuildVector(ArrayRef<llvm::Value*> Ops) { 7305 assert((Ops.size() & (Ops.size() - 1)) == 0 && 7306 "Not a power-of-two sized vector!"); 7307 bool AllConstants = true; 7308 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 7309 AllConstants &= isa<Constant>(Ops[i]); 7310 7311 // If this is a constant vector, create a ConstantVector. 7312 if (AllConstants) { 7313 SmallVector<llvm::Constant*, 16> CstOps; 7314 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7315 CstOps.push_back(cast<Constant>(Ops[i])); 7316 return llvm::ConstantVector::get(CstOps); 7317 } 7318 7319 // Otherwise, insertelement the values to build the vector. 7320 Value *Result = 7321 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 7322 7323 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7324 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 7325 7326 return Result; 7327 } 7328 7329 // Convert the mask from an integer type to a vector of i1. 7330 static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask, 7331 unsigned NumElts) { 7332 7333 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(), 7334 cast<IntegerType>(Mask->getType())->getBitWidth()); 7335 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy); 7336 7337 // If we have less than 8 elements, then the starting mask was an i8 and 7338 // we need to extract down to the right number of elements. 7339 if (NumElts < 8) { 7340 uint32_t Indices[4]; 7341 for (unsigned i = 0; i != NumElts; ++i) 7342 Indices[i] = i; 7343 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec, 7344 makeArrayRef(Indices, NumElts), 7345 "extract"); 7346 } 7347 return MaskVec; 7348 } 7349 7350 static Value *EmitX86MaskedStore(CodeGenFunction &CGF, 7351 SmallVectorImpl<Value *> &Ops, 7352 unsigned Align) { 7353 // Cast the pointer to right type. 7354 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7355 llvm::PointerType::getUnqual(Ops[1]->getType())); 7356 7357 // If the mask is all ones just emit a regular store. 7358 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7359 if (C->isAllOnesValue()) 7360 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align); 7361 7362 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7363 Ops[1]->getType()->getVectorNumElements()); 7364 7365 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec); 7366 } 7367 7368 static Value *EmitX86MaskedLoad(CodeGenFunction &CGF, 7369 SmallVectorImpl<Value *> &Ops, unsigned Align) { 7370 // Cast the pointer to right type. 7371 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7372 llvm::PointerType::getUnqual(Ops[1]->getType())); 7373 7374 // If the mask is all ones just emit a regular store. 7375 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7376 if (C->isAllOnesValue()) 7377 return CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7378 7379 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7380 Ops[1]->getType()->getVectorNumElements()); 7381 7382 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]); 7383 } 7384 7385 static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF, 7386 SmallVectorImpl<Value *> &Ops, 7387 llvm::Type *DstTy, 7388 unsigned SrcSizeInBits, 7389 unsigned Align) { 7390 // Load the subvector. 7391 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7392 7393 // Create broadcast mask. 7394 unsigned NumDstElts = DstTy->getVectorNumElements(); 7395 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits(); 7396 7397 SmallVector<uint32_t, 8> Mask; 7398 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts) 7399 for (unsigned j = 0; j != NumSrcElts; ++j) 7400 Mask.push_back(j); 7401 7402 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst"); 7403 } 7404 7405 static Value *EmitX86Select(CodeGenFunction &CGF, 7406 Value *Mask, Value *Op0, Value *Op1) { 7407 7408 // If the mask is all ones just return first argument. 7409 if (const auto *C = dyn_cast<Constant>(Mask)) 7410 if (C->isAllOnesValue()) 7411 return Op0; 7412 7413 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements()); 7414 7415 return CGF.Builder.CreateSelect(Mask, Op0, Op1); 7416 } 7417 7418 static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC, 7419 bool Signed, SmallVectorImpl<Value *> &Ops) { 7420 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 7421 Value *Cmp; 7422 7423 if (CC == 3) { 7424 Cmp = Constant::getNullValue( 7425 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7426 } else if (CC == 7) { 7427 Cmp = Constant::getAllOnesValue( 7428 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7429 } else { 7430 ICmpInst::Predicate Pred; 7431 switch (CC) { 7432 default: llvm_unreachable("Unknown condition code"); 7433 case 0: Pred = ICmpInst::ICMP_EQ; break; 7434 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; 7435 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; 7436 case 4: Pred = ICmpInst::ICMP_NE; break; 7437 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; 7438 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; 7439 } 7440 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7441 } 7442 7443 const auto *C = dyn_cast<Constant>(Ops.back()); 7444 if (!C || !C->isAllOnesValue()) 7445 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts)); 7446 7447 if (NumElts < 8) { 7448 uint32_t Indices[8]; 7449 for (unsigned i = 0; i != NumElts; ++i) 7450 Indices[i] = i; 7451 for (unsigned i = NumElts; i != 8; ++i) 7452 Indices[i] = i % NumElts + NumElts; 7453 Cmp = CGF.Builder.CreateShuffleVector( 7454 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices); 7455 } 7456 return CGF.Builder.CreateBitCast(Cmp, 7457 IntegerType::get(CGF.getLLVMContext(), 7458 std::max(NumElts, 8U))); 7459 } 7460 7461 static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef<Value *> Ops) { 7462 7463 llvm::Type *Ty = Ops[0]->getType(); 7464 Value *Zero = llvm::Constant::getNullValue(Ty); 7465 Value *Sub = CGF.Builder.CreateSub(Zero, Ops[0]); 7466 Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Zero); 7467 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Sub); 7468 if (Ops.size() == 1) 7469 return Res; 7470 return EmitX86Select(CGF, Ops[2], Res, Ops[1]); 7471 } 7472 7473 static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred, 7474 ArrayRef<Value *> Ops) { 7475 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7476 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]); 7477 7478 if (Ops.size() == 2) 7479 return Res; 7480 7481 assert(Ops.size() == 4); 7482 return EmitX86Select(CGF, Ops[3], Res, Ops[2]); 7483 } 7484 7485 static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, 7486 llvm::Type *DstTy) { 7487 unsigned NumberOfElements = DstTy->getVectorNumElements(); 7488 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements); 7489 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); 7490 } 7491 7492 Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { 7493 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); 7494 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString(); 7495 return EmitX86CpuIs(CPUStr); 7496 } 7497 7498 Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { 7499 7500 // This enum contains the vendor, type, and subtype enums from the 7501 // runtime library concatenated together. The _START labels mark 7502 // the start and are used to adjust the value into the correct 7503 // encoding space. 7504 enum X86CPUs { 7505 INTEL = 1, 7506 AMD, 7507 CPU_TYPE_START, 7508 INTEL_BONNELL, 7509 INTEL_CORE2, 7510 INTEL_COREI7, 7511 AMDFAM10H, 7512 AMDFAM15H, 7513 INTEL_SILVERMONT, 7514 INTEL_KNL, 7515 AMD_BTVER1, 7516 AMD_BTVER2, 7517 AMDFAM17H, 7518 CPU_SUBTYPE_START, 7519 INTEL_COREI7_NEHALEM, 7520 INTEL_COREI7_WESTMERE, 7521 INTEL_COREI7_SANDYBRIDGE, 7522 AMDFAM10H_BARCELONA, 7523 AMDFAM10H_SHANGHAI, 7524 AMDFAM10H_ISTANBUL, 7525 AMDFAM15H_BDVER1, 7526 AMDFAM15H_BDVER2, 7527 AMDFAM15H_BDVER3, 7528 AMDFAM15H_BDVER4, 7529 AMDFAM17H_ZNVER1, 7530 INTEL_COREI7_IVYBRIDGE, 7531 INTEL_COREI7_HASWELL, 7532 INTEL_COREI7_BROADWELL, 7533 INTEL_COREI7_SKYLAKE, 7534 INTEL_COREI7_SKYLAKE_AVX512, 7535 }; 7536 7537 X86CPUs CPU = 7538 StringSwitch<X86CPUs>(CPUStr) 7539 .Case("amd", AMD) 7540 .Case("amdfam10h", AMDFAM10H) 7541 .Case("amdfam10", AMDFAM10H) 7542 .Case("amdfam15h", AMDFAM15H) 7543 .Case("amdfam15", AMDFAM15H) 7544 .Case("amdfam17h", AMDFAM17H) 7545 .Case("atom", INTEL_BONNELL) 7546 .Case("barcelona", AMDFAM10H_BARCELONA) 7547 .Case("bdver1", AMDFAM15H_BDVER1) 7548 .Case("bdver2", AMDFAM15H_BDVER2) 7549 .Case("bdver3", AMDFAM15H_BDVER3) 7550 .Case("bdver4", AMDFAM15H_BDVER4) 7551 .Case("bonnell", INTEL_BONNELL) 7552 .Case("broadwell", INTEL_COREI7_BROADWELL) 7553 .Case("btver1", AMD_BTVER1) 7554 .Case("btver2", AMD_BTVER2) 7555 .Case("core2", INTEL_CORE2) 7556 .Case("corei7", INTEL_COREI7) 7557 .Case("haswell", INTEL_COREI7_HASWELL) 7558 .Case("intel", INTEL) 7559 .Case("istanbul", AMDFAM10H_ISTANBUL) 7560 .Case("ivybridge", INTEL_COREI7_IVYBRIDGE) 7561 .Case("knl", INTEL_KNL) 7562 .Case("nehalem", INTEL_COREI7_NEHALEM) 7563 .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE) 7564 .Case("shanghai", AMDFAM10H_SHANGHAI) 7565 .Case("silvermont", INTEL_SILVERMONT) 7566 .Case("skylake", INTEL_COREI7_SKYLAKE) 7567 .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512) 7568 .Case("slm", INTEL_SILVERMONT) 7569 .Case("westmere", INTEL_COREI7_WESTMERE) 7570 .Case("znver1", AMDFAM17H_ZNVER1); 7571 7572 llvm::Type *Int32Ty = Builder.getInt32Ty(); 7573 7574 // Matching the struct layout from the compiler-rt/libgcc structure that is 7575 // filled in: 7576 // unsigned int __cpu_vendor; 7577 // unsigned int __cpu_type; 7578 // unsigned int __cpu_subtype; 7579 // unsigned int __cpu_features[1]; 7580 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7581 llvm::ArrayType::get(Int32Ty, 1)); 7582 7583 // Grab the global __cpu_model. 7584 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7585 7586 // Calculate the index needed to access the correct field based on the 7587 // range. Also adjust the expected value. 7588 unsigned Index; 7589 unsigned Value; 7590 if (CPU > CPU_SUBTYPE_START) { 7591 Index = 2; 7592 Value = CPU - CPU_SUBTYPE_START; 7593 } else if (CPU > CPU_TYPE_START) { 7594 Index = 1; 7595 Value = CPU - CPU_TYPE_START; 7596 } else { 7597 Index = 0; 7598 Value = CPU; 7599 } 7600 7601 // Grab the appropriate field from __cpu_model. 7602 llvm::Value *Idxs[] = { 7603 ConstantInt::get(Int32Ty, 0), 7604 ConstantInt::get(Int32Ty, Index) 7605 }; 7606 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); 7607 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); 7608 7609 // Check the value of the field against the requested value. 7610 return Builder.CreateICmpEQ(CpuValue, 7611 llvm::ConstantInt::get(Int32Ty, Value)); 7612 } 7613 7614 Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { 7615 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); 7616 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString(); 7617 return EmitX86CpuSupports(FeatureStr); 7618 } 7619 7620 Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) { 7621 // TODO: When/if this becomes more than x86 specific then use a TargetInfo 7622 // based mapping. 7623 // Processor features and mapping to processor feature value. 7624 enum X86Features { 7625 CMOV = 0, 7626 MMX, 7627 POPCNT, 7628 SSE, 7629 SSE2, 7630 SSE3, 7631 SSSE3, 7632 SSE4_1, 7633 SSE4_2, 7634 AVX, 7635 AVX2, 7636 SSE4_A, 7637 FMA4, 7638 XOP, 7639 FMA, 7640 AVX512F, 7641 BMI, 7642 BMI2, 7643 AES, 7644 PCLMUL, 7645 AVX512VL, 7646 AVX512BW, 7647 AVX512DQ, 7648 AVX512CD, 7649 AVX512ER, 7650 AVX512PF, 7651 AVX512VBMI, 7652 AVX512IFMA, 7653 AVX5124VNNIW, 7654 AVX5124FMAPS, 7655 AVX512VPOPCNTDQ, 7656 MAX 7657 }; 7658 7659 uint32_t FeaturesMask = 0; 7660 7661 for (const StringRef &FeatureStr : FeatureStrs) { 7662 X86Features Feature = 7663 StringSwitch<X86Features>(FeatureStr) 7664 .Case("cmov", X86Features::CMOV) 7665 .Case("mmx", X86Features::MMX) 7666 .Case("popcnt", X86Features::POPCNT) 7667 .Case("sse", X86Features::SSE) 7668 .Case("sse2", X86Features::SSE2) 7669 .Case("sse3", X86Features::SSE3) 7670 .Case("ssse3", X86Features::SSSE3) 7671 .Case("sse4.1", X86Features::SSE4_1) 7672 .Case("sse4.2", X86Features::SSE4_2) 7673 .Case("avx", X86Features::AVX) 7674 .Case("avx2", X86Features::AVX2) 7675 .Case("sse4a", X86Features::SSE4_A) 7676 .Case("fma4", X86Features::FMA4) 7677 .Case("xop", X86Features::XOP) 7678 .Case("fma", X86Features::FMA) 7679 .Case("avx512f", X86Features::AVX512F) 7680 .Case("bmi", X86Features::BMI) 7681 .Case("bmi2", X86Features::BMI2) 7682 .Case("aes", X86Features::AES) 7683 .Case("pclmul", X86Features::PCLMUL) 7684 .Case("avx512vl", X86Features::AVX512VL) 7685 .Case("avx512bw", X86Features::AVX512BW) 7686 .Case("avx512dq", X86Features::AVX512DQ) 7687 .Case("avx512cd", X86Features::AVX512CD) 7688 .Case("avx512er", X86Features::AVX512ER) 7689 .Case("avx512pf", X86Features::AVX512PF) 7690 .Case("avx512vbmi", X86Features::AVX512VBMI) 7691 .Case("avx512ifma", X86Features::AVX512IFMA) 7692 .Case("avx5124vnniw", X86Features::AVX5124VNNIW) 7693 .Case("avx5124fmaps", X86Features::AVX5124FMAPS) 7694 .Case("avx512vpopcntdq", X86Features::AVX512VPOPCNTDQ) 7695 .Default(X86Features::MAX); 7696 assert(Feature != X86Features::MAX && "Invalid feature!"); 7697 FeaturesMask |= (1U << Feature); 7698 } 7699 7700 // Matching the struct layout from the compiler-rt/libgcc structure that is 7701 // filled in: 7702 // unsigned int __cpu_vendor; 7703 // unsigned int __cpu_type; 7704 // unsigned int __cpu_subtype; 7705 // unsigned int __cpu_features[1]; 7706 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7707 llvm::ArrayType::get(Int32Ty, 1)); 7708 7709 // Grab the global __cpu_model. 7710 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7711 7712 // Grab the first (0th) element from the field __cpu_features off of the 7713 // global in the struct STy. 7714 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3), 7715 ConstantInt::get(Int32Ty, 0)}; 7716 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs); 7717 Value *Features = 7718 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4)); 7719 7720 // Check the value of the bit corresponding to the feature requested. 7721 Value *Bitset = Builder.CreateAnd( 7722 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask)); 7723 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0)); 7724 } 7725 7726 Value *CodeGenFunction::EmitX86CpuInit() { 7727 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, 7728 /*Variadic*/ false); 7729 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init"); 7730 return Builder.CreateCall(Func); 7731 } 7732 7733 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 7734 const CallExpr *E) { 7735 if (BuiltinID == X86::BI__builtin_cpu_is) 7736 return EmitX86CpuIs(E); 7737 if (BuiltinID == X86::BI__builtin_cpu_supports) 7738 return EmitX86CpuSupports(E); 7739 if (BuiltinID == X86::BI__builtin_cpu_init) 7740 return EmitX86CpuInit(); 7741 7742 SmallVector<Value*, 4> Ops; 7743 7744 // Find out if any arguments are required to be integer constant expressions. 7745 unsigned ICEArguments = 0; 7746 ASTContext::GetBuiltinTypeError Error; 7747 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 7748 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 7749 7750 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 7751 // If this is a normal argument, just emit it as a scalar. 7752 if ((ICEArguments & (1 << i)) == 0) { 7753 Ops.push_back(EmitScalarExpr(E->getArg(i))); 7754 continue; 7755 } 7756 7757 // If this is required to be a constant, constant fold it so that we know 7758 // that the generated intrinsic gets a ConstantInt. 7759 llvm::APSInt Result; 7760 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 7761 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 7762 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 7763 } 7764 7765 // These exist so that the builtin that takes an immediate can be bounds 7766 // checked by clang to avoid passing bad immediates to the backend. Since 7767 // AVX has a larger immediate than SSE we would need separate builtins to 7768 // do the different bounds checking. Rather than create a clang specific 7769 // SSE only builtin, this implements eight separate builtins to match gcc 7770 // implementation. 7771 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) { 7772 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm)); 7773 llvm::Function *F = CGM.getIntrinsic(ID); 7774 return Builder.CreateCall(F, Ops); 7775 }; 7776 7777 // For the vector forms of FP comparisons, translate the builtins directly to 7778 // IR. 7779 // TODO: The builtins could be removed if the SSE header files used vector 7780 // extension comparisons directly (vector ordered/unordered may need 7781 // additional support via __builtin_isnan()). 7782 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) { 7783 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]); 7784 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType()); 7785 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy); 7786 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy); 7787 return Builder.CreateBitCast(Sext, FPVecTy); 7788 }; 7789 7790 switch (BuiltinID) { 7791 default: return nullptr; 7792 case X86::BI_mm_prefetch: { 7793 Value *Address = Ops[0]; 7794 Value *RW = ConstantInt::get(Int32Ty, 0); 7795 Value *Locality = Ops[1]; 7796 Value *Data = ConstantInt::get(Int32Ty, 1); 7797 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 7798 return Builder.CreateCall(F, {Address, RW, Locality, Data}); 7799 } 7800 case X86::BI_mm_clflush: { 7801 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush), 7802 Ops[0]); 7803 } 7804 case X86::BI_mm_lfence: { 7805 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence)); 7806 } 7807 case X86::BI_mm_mfence: { 7808 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence)); 7809 } 7810 case X86::BI_mm_sfence: { 7811 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence)); 7812 } 7813 case X86::BI_mm_pause: { 7814 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause)); 7815 } 7816 case X86::BI__rdtsc: { 7817 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc)); 7818 } 7819 case X86::BI__builtin_ia32_undef128: 7820 case X86::BI__builtin_ia32_undef256: 7821 case X86::BI__builtin_ia32_undef512: 7822 // The x86 definition of "undef" is not the same as the LLVM definition 7823 // (PR32176). We leave optimizing away an unnecessary zero constant to the 7824 // IR optimizer and backend. 7825 // TODO: If we had a "freeze" IR instruction to generate a fixed undef 7826 // value, we should use that here instead of a zero. 7827 return llvm::Constant::getNullValue(ConvertType(E->getType())); 7828 case X86::BI__builtin_ia32_vec_init_v8qi: 7829 case X86::BI__builtin_ia32_vec_init_v4hi: 7830 case X86::BI__builtin_ia32_vec_init_v2si: 7831 return Builder.CreateBitCast(BuildVector(Ops), 7832 llvm::Type::getX86_MMXTy(getLLVMContext())); 7833 case X86::BI__builtin_ia32_vec_ext_v2si: 7834 return Builder.CreateExtractElement(Ops[0], 7835 llvm::ConstantInt::get(Ops[1]->getType(), 0)); 7836 case X86::BI_mm_setcsr: 7837 case X86::BI__builtin_ia32_ldmxcsr: { 7838 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 7839 Builder.CreateStore(Ops[0], Tmp); 7840 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 7841 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7842 } 7843 case X86::BI_mm_getcsr: 7844 case X86::BI__builtin_ia32_stmxcsr: { 7845 Address Tmp = CreateMemTemp(E->getType()); 7846 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 7847 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7848 return Builder.CreateLoad(Tmp, "stmxcsr"); 7849 } 7850 case X86::BI__builtin_ia32_xsave: 7851 case X86::BI__builtin_ia32_xsave64: 7852 case X86::BI__builtin_ia32_xrstor: 7853 case X86::BI__builtin_ia32_xrstor64: 7854 case X86::BI__builtin_ia32_xsaveopt: 7855 case X86::BI__builtin_ia32_xsaveopt64: 7856 case X86::BI__builtin_ia32_xrstors: 7857 case X86::BI__builtin_ia32_xrstors64: 7858 case X86::BI__builtin_ia32_xsavec: 7859 case X86::BI__builtin_ia32_xsavec64: 7860 case X86::BI__builtin_ia32_xsaves: 7861 case X86::BI__builtin_ia32_xsaves64: { 7862 Intrinsic::ID ID; 7863 #define INTRINSIC_X86_XSAVE_ID(NAME) \ 7864 case X86::BI__builtin_ia32_##NAME: \ 7865 ID = Intrinsic::x86_##NAME; \ 7866 break 7867 switch (BuiltinID) { 7868 default: llvm_unreachable("Unsupported intrinsic!"); 7869 INTRINSIC_X86_XSAVE_ID(xsave); 7870 INTRINSIC_X86_XSAVE_ID(xsave64); 7871 INTRINSIC_X86_XSAVE_ID(xrstor); 7872 INTRINSIC_X86_XSAVE_ID(xrstor64); 7873 INTRINSIC_X86_XSAVE_ID(xsaveopt); 7874 INTRINSIC_X86_XSAVE_ID(xsaveopt64); 7875 INTRINSIC_X86_XSAVE_ID(xrstors); 7876 INTRINSIC_X86_XSAVE_ID(xrstors64); 7877 INTRINSIC_X86_XSAVE_ID(xsavec); 7878 INTRINSIC_X86_XSAVE_ID(xsavec64); 7879 INTRINSIC_X86_XSAVE_ID(xsaves); 7880 INTRINSIC_X86_XSAVE_ID(xsaves64); 7881 } 7882 #undef INTRINSIC_X86_XSAVE_ID 7883 Value *Mhi = Builder.CreateTrunc( 7884 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty); 7885 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty); 7886 Ops[1] = Mhi; 7887 Ops.push_back(Mlo); 7888 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 7889 } 7890 case X86::BI__builtin_ia32_storedqudi128_mask: 7891 case X86::BI__builtin_ia32_storedqusi128_mask: 7892 case X86::BI__builtin_ia32_storedquhi128_mask: 7893 case X86::BI__builtin_ia32_storedquqi128_mask: 7894 case X86::BI__builtin_ia32_storeupd128_mask: 7895 case X86::BI__builtin_ia32_storeups128_mask: 7896 case X86::BI__builtin_ia32_storedqudi256_mask: 7897 case X86::BI__builtin_ia32_storedqusi256_mask: 7898 case X86::BI__builtin_ia32_storedquhi256_mask: 7899 case X86::BI__builtin_ia32_storedquqi256_mask: 7900 case X86::BI__builtin_ia32_storeupd256_mask: 7901 case X86::BI__builtin_ia32_storeups256_mask: 7902 case X86::BI__builtin_ia32_storedqudi512_mask: 7903 case X86::BI__builtin_ia32_storedqusi512_mask: 7904 case X86::BI__builtin_ia32_storedquhi512_mask: 7905 case X86::BI__builtin_ia32_storedquqi512_mask: 7906 case X86::BI__builtin_ia32_storeupd512_mask: 7907 case X86::BI__builtin_ia32_storeups512_mask: 7908 return EmitX86MaskedStore(*this, Ops, 1); 7909 7910 case X86::BI__builtin_ia32_storess128_mask: 7911 case X86::BI__builtin_ia32_storesd128_mask: { 7912 return EmitX86MaskedStore(*this, Ops, 16); 7913 } 7914 case X86::BI__builtin_ia32_vpopcntd_512: 7915 case X86::BI__builtin_ia32_vpopcntq_512: { 7916 llvm::Type *ResultType = ConvertType(E->getType()); 7917 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 7918 return Builder.CreateCall(F, Ops); 7919 } 7920 case X86::BI__builtin_ia32_cvtmask2b128: 7921 case X86::BI__builtin_ia32_cvtmask2b256: 7922 case X86::BI__builtin_ia32_cvtmask2b512: 7923 case X86::BI__builtin_ia32_cvtmask2w128: 7924 case X86::BI__builtin_ia32_cvtmask2w256: 7925 case X86::BI__builtin_ia32_cvtmask2w512: 7926 case X86::BI__builtin_ia32_cvtmask2d128: 7927 case X86::BI__builtin_ia32_cvtmask2d256: 7928 case X86::BI__builtin_ia32_cvtmask2d512: 7929 case X86::BI__builtin_ia32_cvtmask2q128: 7930 case X86::BI__builtin_ia32_cvtmask2q256: 7931 case X86::BI__builtin_ia32_cvtmask2q512: 7932 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType())); 7933 7934 case X86::BI__builtin_ia32_movdqa32store128_mask: 7935 case X86::BI__builtin_ia32_movdqa64store128_mask: 7936 case X86::BI__builtin_ia32_storeaps128_mask: 7937 case X86::BI__builtin_ia32_storeapd128_mask: 7938 case X86::BI__builtin_ia32_movdqa32store256_mask: 7939 case X86::BI__builtin_ia32_movdqa64store256_mask: 7940 case X86::BI__builtin_ia32_storeaps256_mask: 7941 case X86::BI__builtin_ia32_storeapd256_mask: 7942 case X86::BI__builtin_ia32_movdqa32store512_mask: 7943 case X86::BI__builtin_ia32_movdqa64store512_mask: 7944 case X86::BI__builtin_ia32_storeaps512_mask: 7945 case X86::BI__builtin_ia32_storeapd512_mask: { 7946 unsigned Align = 7947 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7948 return EmitX86MaskedStore(*this, Ops, Align); 7949 } 7950 case X86::BI__builtin_ia32_loadups128_mask: 7951 case X86::BI__builtin_ia32_loadups256_mask: 7952 case X86::BI__builtin_ia32_loadups512_mask: 7953 case X86::BI__builtin_ia32_loadupd128_mask: 7954 case X86::BI__builtin_ia32_loadupd256_mask: 7955 case X86::BI__builtin_ia32_loadupd512_mask: 7956 case X86::BI__builtin_ia32_loaddquqi128_mask: 7957 case X86::BI__builtin_ia32_loaddquqi256_mask: 7958 case X86::BI__builtin_ia32_loaddquqi512_mask: 7959 case X86::BI__builtin_ia32_loaddquhi128_mask: 7960 case X86::BI__builtin_ia32_loaddquhi256_mask: 7961 case X86::BI__builtin_ia32_loaddquhi512_mask: 7962 case X86::BI__builtin_ia32_loaddqusi128_mask: 7963 case X86::BI__builtin_ia32_loaddqusi256_mask: 7964 case X86::BI__builtin_ia32_loaddqusi512_mask: 7965 case X86::BI__builtin_ia32_loaddqudi128_mask: 7966 case X86::BI__builtin_ia32_loaddqudi256_mask: 7967 case X86::BI__builtin_ia32_loaddqudi512_mask: 7968 return EmitX86MaskedLoad(*this, Ops, 1); 7969 7970 case X86::BI__builtin_ia32_loadss128_mask: 7971 case X86::BI__builtin_ia32_loadsd128_mask: 7972 return EmitX86MaskedLoad(*this, Ops, 16); 7973 7974 case X86::BI__builtin_ia32_loadaps128_mask: 7975 case X86::BI__builtin_ia32_loadaps256_mask: 7976 case X86::BI__builtin_ia32_loadaps512_mask: 7977 case X86::BI__builtin_ia32_loadapd128_mask: 7978 case X86::BI__builtin_ia32_loadapd256_mask: 7979 case X86::BI__builtin_ia32_loadapd512_mask: 7980 case X86::BI__builtin_ia32_movdqa32load128_mask: 7981 case X86::BI__builtin_ia32_movdqa32load256_mask: 7982 case X86::BI__builtin_ia32_movdqa32load512_mask: 7983 case X86::BI__builtin_ia32_movdqa64load128_mask: 7984 case X86::BI__builtin_ia32_movdqa64load256_mask: 7985 case X86::BI__builtin_ia32_movdqa64load512_mask: { 7986 unsigned Align = 7987 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7988 return EmitX86MaskedLoad(*this, Ops, Align); 7989 } 7990 7991 case X86::BI__builtin_ia32_vbroadcastf128_pd256: 7992 case X86::BI__builtin_ia32_vbroadcastf128_ps256: { 7993 llvm::Type *DstTy = ConvertType(E->getType()); 7994 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1); 7995 } 7996 7997 case X86::BI__builtin_ia32_storehps: 7998 case X86::BI__builtin_ia32_storelps: { 7999 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 8000 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 8001 8002 // cast val v2i64 8003 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 8004 8005 // extract (0, 1) 8006 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 8007 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index); 8008 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 8009 8010 // cast pointer to i64 & store 8011 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 8012 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 8013 } 8014 case X86::BI__builtin_ia32_palignr128: 8015 case X86::BI__builtin_ia32_palignr256: 8016 case X86::BI__builtin_ia32_palignr512_mask: { 8017 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8018 8019 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 8020 assert(NumElts % 16 == 0); 8021 8022 // If palignr is shifting the pair of vectors more than the size of two 8023 // lanes, emit zero. 8024 if (ShiftVal >= 32) 8025 return llvm::Constant::getNullValue(ConvertType(E->getType())); 8026 8027 // If palignr is shifting the pair of input vectors more than one lane, 8028 // but less than two lanes, convert to shifting in zeroes. 8029 if (ShiftVal > 16) { 8030 ShiftVal -= 16; 8031 Ops[1] = Ops[0]; 8032 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType()); 8033 } 8034 8035 uint32_t Indices[64]; 8036 // 256-bit palignr operates on 128-bit lanes so we need to handle that 8037 for (unsigned l = 0; l != NumElts; l += 16) { 8038 for (unsigned i = 0; i != 16; ++i) { 8039 unsigned Idx = ShiftVal + i; 8040 if (Idx >= 16) 8041 Idx += NumElts - 16; // End of lane, switch operand. 8042 Indices[l + i] = Idx + l; 8043 } 8044 } 8045 8046 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0], 8047 makeArrayRef(Indices, NumElts), 8048 "palignr"); 8049 8050 // If this isn't a masked builtin, just return the align operation. 8051 if (Ops.size() == 3) 8052 return Align; 8053 8054 return EmitX86Select(*this, Ops[4], Align, Ops[3]); 8055 } 8056 8057 case X86::BI__builtin_ia32_vperm2f128_pd256: 8058 case X86::BI__builtin_ia32_vperm2f128_ps256: 8059 case X86::BI__builtin_ia32_vperm2f128_si256: 8060 case X86::BI__builtin_ia32_permti256: { 8061 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8062 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 8063 8064 // This takes a very simple approach since there are two lanes and a 8065 // shuffle can have 2 inputs. So we reserve the first input for the first 8066 // lane and the second input for the second lane. This may result in 8067 // duplicate sources, but this can be dealt with in the backend. 8068 8069 Value *OutOps[2]; 8070 uint32_t Indices[8]; 8071 for (unsigned l = 0; l != 2; ++l) { 8072 // Determine the source for this lane. 8073 if (Imm & (1 << ((l * 4) + 3))) 8074 OutOps[l] = llvm::ConstantAggregateZero::get(Ops[0]->getType()); 8075 else if (Imm & (1 << ((l * 4) + 1))) 8076 OutOps[l] = Ops[1]; 8077 else 8078 OutOps[l] = Ops[0]; 8079 8080 for (unsigned i = 0; i != NumElts/2; ++i) { 8081 // Start with ith element of the source for this lane. 8082 unsigned Idx = (l * NumElts) + i; 8083 // If bit 0 of the immediate half is set, switch to the high half of 8084 // the source. 8085 if (Imm & (1 << (l * 4))) 8086 Idx += NumElts/2; 8087 Indices[(l * (NumElts/2)) + i] = Idx; 8088 } 8089 } 8090 8091 return Builder.CreateShuffleVector(OutOps[0], OutOps[1], 8092 makeArrayRef(Indices, NumElts), 8093 "vperm"); 8094 } 8095 8096 case X86::BI__builtin_ia32_movnti: 8097 case X86::BI__builtin_ia32_movnti64: 8098 case X86::BI__builtin_ia32_movntsd: 8099 case X86::BI__builtin_ia32_movntss: { 8100 llvm::MDNode *Node = llvm::MDNode::get( 8101 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); 8102 8103 Value *Ptr = Ops[0]; 8104 Value *Src = Ops[1]; 8105 8106 // Extract the 0'th element of the source vector. 8107 if (BuiltinID == X86::BI__builtin_ia32_movntsd || 8108 BuiltinID == X86::BI__builtin_ia32_movntss) 8109 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract"); 8110 8111 // Convert the type of the pointer to a pointer to the stored type. 8112 Value *BC = Builder.CreateBitCast( 8113 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast"); 8114 8115 // Unaligned nontemporal store of the scalar value. 8116 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC); 8117 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 8118 SI->setAlignment(1); 8119 return SI; 8120 } 8121 8122 case X86::BI__builtin_ia32_selectb_128: 8123 case X86::BI__builtin_ia32_selectb_256: 8124 case X86::BI__builtin_ia32_selectb_512: 8125 case X86::BI__builtin_ia32_selectw_128: 8126 case X86::BI__builtin_ia32_selectw_256: 8127 case X86::BI__builtin_ia32_selectw_512: 8128 case X86::BI__builtin_ia32_selectd_128: 8129 case X86::BI__builtin_ia32_selectd_256: 8130 case X86::BI__builtin_ia32_selectd_512: 8131 case X86::BI__builtin_ia32_selectq_128: 8132 case X86::BI__builtin_ia32_selectq_256: 8133 case X86::BI__builtin_ia32_selectq_512: 8134 case X86::BI__builtin_ia32_selectps_128: 8135 case X86::BI__builtin_ia32_selectps_256: 8136 case X86::BI__builtin_ia32_selectps_512: 8137 case X86::BI__builtin_ia32_selectpd_128: 8138 case X86::BI__builtin_ia32_selectpd_256: 8139 case X86::BI__builtin_ia32_selectpd_512: 8140 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]); 8141 case X86::BI__builtin_ia32_cmpb128_mask: 8142 case X86::BI__builtin_ia32_cmpb256_mask: 8143 case X86::BI__builtin_ia32_cmpb512_mask: 8144 case X86::BI__builtin_ia32_cmpw128_mask: 8145 case X86::BI__builtin_ia32_cmpw256_mask: 8146 case X86::BI__builtin_ia32_cmpw512_mask: 8147 case X86::BI__builtin_ia32_cmpd128_mask: 8148 case X86::BI__builtin_ia32_cmpd256_mask: 8149 case X86::BI__builtin_ia32_cmpd512_mask: 8150 case X86::BI__builtin_ia32_cmpq128_mask: 8151 case X86::BI__builtin_ia32_cmpq256_mask: 8152 case X86::BI__builtin_ia32_cmpq512_mask: { 8153 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8154 return EmitX86MaskedCompare(*this, CC, true, Ops); 8155 } 8156 case X86::BI__builtin_ia32_ucmpb128_mask: 8157 case X86::BI__builtin_ia32_ucmpb256_mask: 8158 case X86::BI__builtin_ia32_ucmpb512_mask: 8159 case X86::BI__builtin_ia32_ucmpw128_mask: 8160 case X86::BI__builtin_ia32_ucmpw256_mask: 8161 case X86::BI__builtin_ia32_ucmpw512_mask: 8162 case X86::BI__builtin_ia32_ucmpd128_mask: 8163 case X86::BI__builtin_ia32_ucmpd256_mask: 8164 case X86::BI__builtin_ia32_ucmpd512_mask: 8165 case X86::BI__builtin_ia32_ucmpq128_mask: 8166 case X86::BI__builtin_ia32_ucmpq256_mask: 8167 case X86::BI__builtin_ia32_ucmpq512_mask: { 8168 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8169 return EmitX86MaskedCompare(*this, CC, false, Ops); 8170 } 8171 8172 case X86::BI__builtin_ia32_vplzcntd_128_mask: 8173 case X86::BI__builtin_ia32_vplzcntd_256_mask: 8174 case X86::BI__builtin_ia32_vplzcntd_512_mask: 8175 case X86::BI__builtin_ia32_vplzcntq_128_mask: 8176 case X86::BI__builtin_ia32_vplzcntq_256_mask: 8177 case X86::BI__builtin_ia32_vplzcntq_512_mask: { 8178 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType()); 8179 return EmitX86Select(*this, Ops[2], 8180 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}), 8181 Ops[1]); 8182 } 8183 8184 case X86::BI__builtin_ia32_pabsb128: 8185 case X86::BI__builtin_ia32_pabsw128: 8186 case X86::BI__builtin_ia32_pabsd128: 8187 case X86::BI__builtin_ia32_pabsb256: 8188 case X86::BI__builtin_ia32_pabsw256: 8189 case X86::BI__builtin_ia32_pabsd256: 8190 case X86::BI__builtin_ia32_pabsq128_mask: 8191 case X86::BI__builtin_ia32_pabsq256_mask: 8192 case X86::BI__builtin_ia32_pabsb512_mask: 8193 case X86::BI__builtin_ia32_pabsw512_mask: 8194 case X86::BI__builtin_ia32_pabsd512_mask: 8195 case X86::BI__builtin_ia32_pabsq512_mask: 8196 return EmitX86Abs(*this, Ops); 8197 8198 case X86::BI__builtin_ia32_pmaxsb128: 8199 case X86::BI__builtin_ia32_pmaxsw128: 8200 case X86::BI__builtin_ia32_pmaxsd128: 8201 case X86::BI__builtin_ia32_pmaxsq128_mask: 8202 case X86::BI__builtin_ia32_pmaxsb256: 8203 case X86::BI__builtin_ia32_pmaxsw256: 8204 case X86::BI__builtin_ia32_pmaxsd256: 8205 case X86::BI__builtin_ia32_pmaxsq256_mask: 8206 case X86::BI__builtin_ia32_pmaxsb512_mask: 8207 case X86::BI__builtin_ia32_pmaxsw512_mask: 8208 case X86::BI__builtin_ia32_pmaxsd512_mask: 8209 case X86::BI__builtin_ia32_pmaxsq512_mask: 8210 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops); 8211 case X86::BI__builtin_ia32_pmaxub128: 8212 case X86::BI__builtin_ia32_pmaxuw128: 8213 case X86::BI__builtin_ia32_pmaxud128: 8214 case X86::BI__builtin_ia32_pmaxuq128_mask: 8215 case X86::BI__builtin_ia32_pmaxub256: 8216 case X86::BI__builtin_ia32_pmaxuw256: 8217 case X86::BI__builtin_ia32_pmaxud256: 8218 case X86::BI__builtin_ia32_pmaxuq256_mask: 8219 case X86::BI__builtin_ia32_pmaxub512_mask: 8220 case X86::BI__builtin_ia32_pmaxuw512_mask: 8221 case X86::BI__builtin_ia32_pmaxud512_mask: 8222 case X86::BI__builtin_ia32_pmaxuq512_mask: 8223 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops); 8224 case X86::BI__builtin_ia32_pminsb128: 8225 case X86::BI__builtin_ia32_pminsw128: 8226 case X86::BI__builtin_ia32_pminsd128: 8227 case X86::BI__builtin_ia32_pminsq128_mask: 8228 case X86::BI__builtin_ia32_pminsb256: 8229 case X86::BI__builtin_ia32_pminsw256: 8230 case X86::BI__builtin_ia32_pminsd256: 8231 case X86::BI__builtin_ia32_pminsq256_mask: 8232 case X86::BI__builtin_ia32_pminsb512_mask: 8233 case X86::BI__builtin_ia32_pminsw512_mask: 8234 case X86::BI__builtin_ia32_pminsd512_mask: 8235 case X86::BI__builtin_ia32_pminsq512_mask: 8236 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops); 8237 case X86::BI__builtin_ia32_pminub128: 8238 case X86::BI__builtin_ia32_pminuw128: 8239 case X86::BI__builtin_ia32_pminud128: 8240 case X86::BI__builtin_ia32_pminuq128_mask: 8241 case X86::BI__builtin_ia32_pminub256: 8242 case X86::BI__builtin_ia32_pminuw256: 8243 case X86::BI__builtin_ia32_pminud256: 8244 case X86::BI__builtin_ia32_pminuq256_mask: 8245 case X86::BI__builtin_ia32_pminub512_mask: 8246 case X86::BI__builtin_ia32_pminuw512_mask: 8247 case X86::BI__builtin_ia32_pminud512_mask: 8248 case X86::BI__builtin_ia32_pminuq512_mask: 8249 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops); 8250 8251 // 3DNow! 8252 case X86::BI__builtin_ia32_pswapdsf: 8253 case X86::BI__builtin_ia32_pswapdsi: { 8254 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 8255 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 8256 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd); 8257 return Builder.CreateCall(F, Ops, "pswapd"); 8258 } 8259 case X86::BI__builtin_ia32_rdrand16_step: 8260 case X86::BI__builtin_ia32_rdrand32_step: 8261 case X86::BI__builtin_ia32_rdrand64_step: 8262 case X86::BI__builtin_ia32_rdseed16_step: 8263 case X86::BI__builtin_ia32_rdseed32_step: 8264 case X86::BI__builtin_ia32_rdseed64_step: { 8265 Intrinsic::ID ID; 8266 switch (BuiltinID) { 8267 default: llvm_unreachable("Unsupported intrinsic!"); 8268 case X86::BI__builtin_ia32_rdrand16_step: 8269 ID = Intrinsic::x86_rdrand_16; 8270 break; 8271 case X86::BI__builtin_ia32_rdrand32_step: 8272 ID = Intrinsic::x86_rdrand_32; 8273 break; 8274 case X86::BI__builtin_ia32_rdrand64_step: 8275 ID = Intrinsic::x86_rdrand_64; 8276 break; 8277 case X86::BI__builtin_ia32_rdseed16_step: 8278 ID = Intrinsic::x86_rdseed_16; 8279 break; 8280 case X86::BI__builtin_ia32_rdseed32_step: 8281 ID = Intrinsic::x86_rdseed_32; 8282 break; 8283 case X86::BI__builtin_ia32_rdseed64_step: 8284 ID = Intrinsic::x86_rdseed_64; 8285 break; 8286 } 8287 8288 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 8289 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0), 8290 Ops[0]); 8291 return Builder.CreateExtractValue(Call, 1); 8292 } 8293 8294 // SSE packed comparison intrinsics 8295 case X86::BI__builtin_ia32_cmpeqps: 8296 case X86::BI__builtin_ia32_cmpeqpd: 8297 return getVectorFCmpIR(CmpInst::FCMP_OEQ); 8298 case X86::BI__builtin_ia32_cmpltps: 8299 case X86::BI__builtin_ia32_cmpltpd: 8300 return getVectorFCmpIR(CmpInst::FCMP_OLT); 8301 case X86::BI__builtin_ia32_cmpleps: 8302 case X86::BI__builtin_ia32_cmplepd: 8303 return getVectorFCmpIR(CmpInst::FCMP_OLE); 8304 case X86::BI__builtin_ia32_cmpunordps: 8305 case X86::BI__builtin_ia32_cmpunordpd: 8306 return getVectorFCmpIR(CmpInst::FCMP_UNO); 8307 case X86::BI__builtin_ia32_cmpneqps: 8308 case X86::BI__builtin_ia32_cmpneqpd: 8309 return getVectorFCmpIR(CmpInst::FCMP_UNE); 8310 case X86::BI__builtin_ia32_cmpnltps: 8311 case X86::BI__builtin_ia32_cmpnltpd: 8312 return getVectorFCmpIR(CmpInst::FCMP_UGE); 8313 case X86::BI__builtin_ia32_cmpnleps: 8314 case X86::BI__builtin_ia32_cmpnlepd: 8315 return getVectorFCmpIR(CmpInst::FCMP_UGT); 8316 case X86::BI__builtin_ia32_cmpordps: 8317 case X86::BI__builtin_ia32_cmpordpd: 8318 return getVectorFCmpIR(CmpInst::FCMP_ORD); 8319 case X86::BI__builtin_ia32_cmpps: 8320 case X86::BI__builtin_ia32_cmpps256: 8321 case X86::BI__builtin_ia32_cmppd: 8322 case X86::BI__builtin_ia32_cmppd256: { 8323 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8324 // If this one of the SSE immediates, we can use native IR. 8325 if (CC < 8) { 8326 FCmpInst::Predicate Pred; 8327 switch (CC) { 8328 case 0: Pred = FCmpInst::FCMP_OEQ; break; 8329 case 1: Pred = FCmpInst::FCMP_OLT; break; 8330 case 2: Pred = FCmpInst::FCMP_OLE; break; 8331 case 3: Pred = FCmpInst::FCMP_UNO; break; 8332 case 4: Pred = FCmpInst::FCMP_UNE; break; 8333 case 5: Pred = FCmpInst::FCMP_UGE; break; 8334 case 6: Pred = FCmpInst::FCMP_UGT; break; 8335 case 7: Pred = FCmpInst::FCMP_ORD; break; 8336 } 8337 return getVectorFCmpIR(Pred); 8338 } 8339 8340 // We can't handle 8-31 immediates with native IR, use the intrinsic. 8341 // Except for predicates that create constants. 8342 Intrinsic::ID ID; 8343 switch (BuiltinID) { 8344 default: llvm_unreachable("Unsupported intrinsic!"); 8345 case X86::BI__builtin_ia32_cmpps: 8346 ID = Intrinsic::x86_sse_cmp_ps; 8347 break; 8348 case X86::BI__builtin_ia32_cmpps256: 8349 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8350 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8351 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8352 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8353 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) : 8354 llvm::Constant::getNullValue(Builder.getInt32Ty()); 8355 Value *Vec = Builder.CreateVectorSplat( 8356 Ops[0]->getType()->getVectorNumElements(), Constant); 8357 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8358 } 8359 ID = Intrinsic::x86_avx_cmp_ps_256; 8360 break; 8361 case X86::BI__builtin_ia32_cmppd: 8362 ID = Intrinsic::x86_sse2_cmp_pd; 8363 break; 8364 case X86::BI__builtin_ia32_cmppd256: 8365 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8366 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8367 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8368 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8369 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) : 8370 llvm::Constant::getNullValue(Builder.getInt64Ty()); 8371 Value *Vec = Builder.CreateVectorSplat( 8372 Ops[0]->getType()->getVectorNumElements(), Constant); 8373 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8374 } 8375 ID = Intrinsic::x86_avx_cmp_pd_256; 8376 break; 8377 } 8378 8379 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 8380 } 8381 8382 // SSE scalar comparison intrinsics 8383 case X86::BI__builtin_ia32_cmpeqss: 8384 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0); 8385 case X86::BI__builtin_ia32_cmpltss: 8386 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1); 8387 case X86::BI__builtin_ia32_cmpless: 8388 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2); 8389 case X86::BI__builtin_ia32_cmpunordss: 8390 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3); 8391 case X86::BI__builtin_ia32_cmpneqss: 8392 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4); 8393 case X86::BI__builtin_ia32_cmpnltss: 8394 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5); 8395 case X86::BI__builtin_ia32_cmpnless: 8396 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6); 8397 case X86::BI__builtin_ia32_cmpordss: 8398 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7); 8399 case X86::BI__builtin_ia32_cmpeqsd: 8400 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0); 8401 case X86::BI__builtin_ia32_cmpltsd: 8402 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1); 8403 case X86::BI__builtin_ia32_cmplesd: 8404 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2); 8405 case X86::BI__builtin_ia32_cmpunordsd: 8406 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3); 8407 case X86::BI__builtin_ia32_cmpneqsd: 8408 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4); 8409 case X86::BI__builtin_ia32_cmpnltsd: 8410 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5); 8411 case X86::BI__builtin_ia32_cmpnlesd: 8412 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); 8413 case X86::BI__builtin_ia32_cmpordsd: 8414 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); 8415 8416 case X86::BI__emul: 8417 case X86::BI__emulu: { 8418 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64); 8419 bool isSigned = (BuiltinID == X86::BI__emul); 8420 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned); 8421 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned); 8422 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned); 8423 } 8424 case X86::BI__mulh: 8425 case X86::BI__umulh: 8426 case X86::BI_mul128: 8427 case X86::BI_umul128: { 8428 llvm::Type *ResType = ConvertType(E->getType()); 8429 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 8430 8431 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128); 8432 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned); 8433 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned); 8434 8435 Value *MulResult, *HigherBits; 8436 if (IsSigned) { 8437 MulResult = Builder.CreateNSWMul(LHS, RHS); 8438 HigherBits = Builder.CreateAShr(MulResult, 64); 8439 } else { 8440 MulResult = Builder.CreateNUWMul(LHS, RHS); 8441 HigherBits = Builder.CreateLShr(MulResult, 64); 8442 } 8443 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); 8444 8445 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh) 8446 return HigherBits; 8447 8448 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2)); 8449 Builder.CreateStore(HigherBits, HighBitsAddress); 8450 return Builder.CreateIntCast(MulResult, ResType, IsSigned); 8451 } 8452 8453 case X86::BI__faststorefence: { 8454 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8455 llvm::SyncScope::System); 8456 } 8457 case X86::BI_ReadWriteBarrier: 8458 case X86::BI_ReadBarrier: 8459 case X86::BI_WriteBarrier: { 8460 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8461 llvm::SyncScope::SingleThread); 8462 } 8463 case X86::BI_BitScanForward: 8464 case X86::BI_BitScanForward64: 8465 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 8466 case X86::BI_BitScanReverse: 8467 case X86::BI_BitScanReverse64: 8468 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 8469 8470 case X86::BI_InterlockedAnd64: 8471 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 8472 case X86::BI_InterlockedExchange64: 8473 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 8474 case X86::BI_InterlockedExchangeAdd64: 8475 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 8476 case X86::BI_InterlockedExchangeSub64: 8477 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 8478 case X86::BI_InterlockedOr64: 8479 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 8480 case X86::BI_InterlockedXor64: 8481 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 8482 case X86::BI_InterlockedDecrement64: 8483 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 8484 case X86::BI_InterlockedIncrement64: 8485 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 8486 8487 case X86::BI_AddressOfReturnAddress: { 8488 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); 8489 return Builder.CreateCall(F); 8490 } 8491 case X86::BI__stosb: { 8492 // We treat __stosb as a volatile memset - it may not generate "rep stosb" 8493 // instruction, but it will create a memset that won't be optimized away. 8494 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); 8495 } 8496 case X86::BI__ud2: 8497 // llvm.trap makes a ud2a instruction on x86. 8498 return EmitTrapCall(Intrinsic::trap); 8499 case X86::BI__int2c: { 8500 // This syscall signals a driver assertion failure in x86 NT kernels. 8501 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 8502 llvm::InlineAsm *IA = 8503 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true); 8504 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get( 8505 getLLVMContext(), llvm::AttributeList::FunctionIndex, 8506 llvm::Attribute::NoReturn); 8507 CallSite CS = Builder.CreateCall(IA); 8508 CS.setAttributes(NoReturnAttr); 8509 return CS.getInstruction(); 8510 } 8511 case X86::BI__readfsbyte: 8512 case X86::BI__readfsword: 8513 case X86::BI__readfsdword: 8514 case X86::BI__readfsqword: { 8515 llvm::Type *IntTy = ConvertType(E->getType()); 8516 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8517 llvm::PointerType::get(IntTy, 257)); 8518 LoadInst *Load = Builder.CreateAlignedLoad( 8519 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8520 Load->setVolatile(true); 8521 return Load; 8522 } 8523 case X86::BI__readgsbyte: 8524 case X86::BI__readgsword: 8525 case X86::BI__readgsdword: 8526 case X86::BI__readgsqword: { 8527 llvm::Type *IntTy = ConvertType(E->getType()); 8528 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8529 llvm::PointerType::get(IntTy, 256)); 8530 LoadInst *Load = Builder.CreateAlignedLoad( 8531 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8532 Load->setVolatile(true); 8533 return Load; 8534 } 8535 } 8536 } 8537 8538 8539 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 8540 const CallExpr *E) { 8541 SmallVector<Value*, 4> Ops; 8542 8543 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 8544 Ops.push_back(EmitScalarExpr(E->getArg(i))); 8545 8546 Intrinsic::ID ID = Intrinsic::not_intrinsic; 8547 8548 switch (BuiltinID) { 8549 default: return nullptr; 8550 8551 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we 8552 // call __builtin_readcyclecounter. 8553 case PPC::BI__builtin_ppc_get_timebase: 8554 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter)); 8555 8556 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr 8557 case PPC::BI__builtin_altivec_lvx: 8558 case PPC::BI__builtin_altivec_lvxl: 8559 case PPC::BI__builtin_altivec_lvebx: 8560 case PPC::BI__builtin_altivec_lvehx: 8561 case PPC::BI__builtin_altivec_lvewx: 8562 case PPC::BI__builtin_altivec_lvsl: 8563 case PPC::BI__builtin_altivec_lvsr: 8564 case PPC::BI__builtin_vsx_lxvd2x: 8565 case PPC::BI__builtin_vsx_lxvw4x: 8566 case PPC::BI__builtin_vsx_lxvd2x_be: 8567 case PPC::BI__builtin_vsx_lxvw4x_be: 8568 case PPC::BI__builtin_vsx_lxvl: 8569 case PPC::BI__builtin_vsx_lxvll: 8570 { 8571 if(BuiltinID == PPC::BI__builtin_vsx_lxvl || 8572 BuiltinID == PPC::BI__builtin_vsx_lxvll){ 8573 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy); 8574 }else { 8575 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8576 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 8577 Ops.pop_back(); 8578 } 8579 8580 switch (BuiltinID) { 8581 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 8582 case PPC::BI__builtin_altivec_lvx: 8583 ID = Intrinsic::ppc_altivec_lvx; 8584 break; 8585 case PPC::BI__builtin_altivec_lvxl: 8586 ID = Intrinsic::ppc_altivec_lvxl; 8587 break; 8588 case PPC::BI__builtin_altivec_lvebx: 8589 ID = Intrinsic::ppc_altivec_lvebx; 8590 break; 8591 case PPC::BI__builtin_altivec_lvehx: 8592 ID = Intrinsic::ppc_altivec_lvehx; 8593 break; 8594 case PPC::BI__builtin_altivec_lvewx: 8595 ID = Intrinsic::ppc_altivec_lvewx; 8596 break; 8597 case PPC::BI__builtin_altivec_lvsl: 8598 ID = Intrinsic::ppc_altivec_lvsl; 8599 break; 8600 case PPC::BI__builtin_altivec_lvsr: 8601 ID = Intrinsic::ppc_altivec_lvsr; 8602 break; 8603 case PPC::BI__builtin_vsx_lxvd2x: 8604 ID = Intrinsic::ppc_vsx_lxvd2x; 8605 break; 8606 case PPC::BI__builtin_vsx_lxvw4x: 8607 ID = Intrinsic::ppc_vsx_lxvw4x; 8608 break; 8609 case PPC::BI__builtin_vsx_lxvd2x_be: 8610 ID = Intrinsic::ppc_vsx_lxvd2x_be; 8611 break; 8612 case PPC::BI__builtin_vsx_lxvw4x_be: 8613 ID = Intrinsic::ppc_vsx_lxvw4x_be; 8614 break; 8615 case PPC::BI__builtin_vsx_lxvl: 8616 ID = Intrinsic::ppc_vsx_lxvl; 8617 break; 8618 case PPC::BI__builtin_vsx_lxvll: 8619 ID = Intrinsic::ppc_vsx_lxvll; 8620 break; 8621 } 8622 llvm::Function *F = CGM.getIntrinsic(ID); 8623 return Builder.CreateCall(F, Ops, ""); 8624 } 8625 8626 // vec_st, vec_xst_be 8627 case PPC::BI__builtin_altivec_stvx: 8628 case PPC::BI__builtin_altivec_stvxl: 8629 case PPC::BI__builtin_altivec_stvebx: 8630 case PPC::BI__builtin_altivec_stvehx: 8631 case PPC::BI__builtin_altivec_stvewx: 8632 case PPC::BI__builtin_vsx_stxvd2x: 8633 case PPC::BI__builtin_vsx_stxvw4x: 8634 case PPC::BI__builtin_vsx_stxvd2x_be: 8635 case PPC::BI__builtin_vsx_stxvw4x_be: 8636 case PPC::BI__builtin_vsx_stxvl: 8637 case PPC::BI__builtin_vsx_stxvll: 8638 { 8639 if(BuiltinID == PPC::BI__builtin_vsx_stxvl || 8640 BuiltinID == PPC::BI__builtin_vsx_stxvll ){ 8641 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8642 }else { 8643 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 8644 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 8645 Ops.pop_back(); 8646 } 8647 8648 switch (BuiltinID) { 8649 default: llvm_unreachable("Unsupported st intrinsic!"); 8650 case PPC::BI__builtin_altivec_stvx: 8651 ID = Intrinsic::ppc_altivec_stvx; 8652 break; 8653 case PPC::BI__builtin_altivec_stvxl: 8654 ID = Intrinsic::ppc_altivec_stvxl; 8655 break; 8656 case PPC::BI__builtin_altivec_stvebx: 8657 ID = Intrinsic::ppc_altivec_stvebx; 8658 break; 8659 case PPC::BI__builtin_altivec_stvehx: 8660 ID = Intrinsic::ppc_altivec_stvehx; 8661 break; 8662 case PPC::BI__builtin_altivec_stvewx: 8663 ID = Intrinsic::ppc_altivec_stvewx; 8664 break; 8665 case PPC::BI__builtin_vsx_stxvd2x: 8666 ID = Intrinsic::ppc_vsx_stxvd2x; 8667 break; 8668 case PPC::BI__builtin_vsx_stxvw4x: 8669 ID = Intrinsic::ppc_vsx_stxvw4x; 8670 break; 8671 case PPC::BI__builtin_vsx_stxvd2x_be: 8672 ID = Intrinsic::ppc_vsx_stxvd2x_be; 8673 break; 8674 case PPC::BI__builtin_vsx_stxvw4x_be: 8675 ID = Intrinsic::ppc_vsx_stxvw4x_be; 8676 break; 8677 case PPC::BI__builtin_vsx_stxvl: 8678 ID = Intrinsic::ppc_vsx_stxvl; 8679 break; 8680 case PPC::BI__builtin_vsx_stxvll: 8681 ID = Intrinsic::ppc_vsx_stxvll; 8682 break; 8683 } 8684 llvm::Function *F = CGM.getIntrinsic(ID); 8685 return Builder.CreateCall(F, Ops, ""); 8686 } 8687 // Square root 8688 case PPC::BI__builtin_vsx_xvsqrtsp: 8689 case PPC::BI__builtin_vsx_xvsqrtdp: { 8690 llvm::Type *ResultType = ConvertType(E->getType()); 8691 Value *X = EmitScalarExpr(E->getArg(0)); 8692 ID = Intrinsic::sqrt; 8693 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8694 return Builder.CreateCall(F, X); 8695 } 8696 // Count leading zeros 8697 case PPC::BI__builtin_altivec_vclzb: 8698 case PPC::BI__builtin_altivec_vclzh: 8699 case PPC::BI__builtin_altivec_vclzw: 8700 case PPC::BI__builtin_altivec_vclzd: { 8701 llvm::Type *ResultType = ConvertType(E->getType()); 8702 Value *X = EmitScalarExpr(E->getArg(0)); 8703 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8704 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 8705 return Builder.CreateCall(F, {X, Undef}); 8706 } 8707 case PPC::BI__builtin_altivec_vctzb: 8708 case PPC::BI__builtin_altivec_vctzh: 8709 case PPC::BI__builtin_altivec_vctzw: 8710 case PPC::BI__builtin_altivec_vctzd: { 8711 llvm::Type *ResultType = ConvertType(E->getType()); 8712 Value *X = EmitScalarExpr(E->getArg(0)); 8713 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8714 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 8715 return Builder.CreateCall(F, {X, Undef}); 8716 } 8717 case PPC::BI__builtin_altivec_vpopcntb: 8718 case PPC::BI__builtin_altivec_vpopcnth: 8719 case PPC::BI__builtin_altivec_vpopcntw: 8720 case PPC::BI__builtin_altivec_vpopcntd: { 8721 llvm::Type *ResultType = ConvertType(E->getType()); 8722 Value *X = EmitScalarExpr(E->getArg(0)); 8723 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 8724 return Builder.CreateCall(F, X); 8725 } 8726 // Copy sign 8727 case PPC::BI__builtin_vsx_xvcpsgnsp: 8728 case PPC::BI__builtin_vsx_xvcpsgndp: { 8729 llvm::Type *ResultType = ConvertType(E->getType()); 8730 Value *X = EmitScalarExpr(E->getArg(0)); 8731 Value *Y = EmitScalarExpr(E->getArg(1)); 8732 ID = Intrinsic::copysign; 8733 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8734 return Builder.CreateCall(F, {X, Y}); 8735 } 8736 // Rounding/truncation 8737 case PPC::BI__builtin_vsx_xvrspip: 8738 case PPC::BI__builtin_vsx_xvrdpip: 8739 case PPC::BI__builtin_vsx_xvrdpim: 8740 case PPC::BI__builtin_vsx_xvrspim: 8741 case PPC::BI__builtin_vsx_xvrdpi: 8742 case PPC::BI__builtin_vsx_xvrspi: 8743 case PPC::BI__builtin_vsx_xvrdpic: 8744 case PPC::BI__builtin_vsx_xvrspic: 8745 case PPC::BI__builtin_vsx_xvrdpiz: 8746 case PPC::BI__builtin_vsx_xvrspiz: { 8747 llvm::Type *ResultType = ConvertType(E->getType()); 8748 Value *X = EmitScalarExpr(E->getArg(0)); 8749 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim || 8750 BuiltinID == PPC::BI__builtin_vsx_xvrspim) 8751 ID = Intrinsic::floor; 8752 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi || 8753 BuiltinID == PPC::BI__builtin_vsx_xvrspi) 8754 ID = Intrinsic::round; 8755 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic || 8756 BuiltinID == PPC::BI__builtin_vsx_xvrspic) 8757 ID = Intrinsic::nearbyint; 8758 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip || 8759 BuiltinID == PPC::BI__builtin_vsx_xvrspip) 8760 ID = Intrinsic::ceil; 8761 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz || 8762 BuiltinID == PPC::BI__builtin_vsx_xvrspiz) 8763 ID = Intrinsic::trunc; 8764 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8765 return Builder.CreateCall(F, X); 8766 } 8767 8768 // Absolute value 8769 case PPC::BI__builtin_vsx_xvabsdp: 8770 case PPC::BI__builtin_vsx_xvabssp: { 8771 llvm::Type *ResultType = ConvertType(E->getType()); 8772 Value *X = EmitScalarExpr(E->getArg(0)); 8773 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 8774 return Builder.CreateCall(F, X); 8775 } 8776 8777 // FMA variations 8778 case PPC::BI__builtin_vsx_xvmaddadp: 8779 case PPC::BI__builtin_vsx_xvmaddasp: 8780 case PPC::BI__builtin_vsx_xvnmaddadp: 8781 case PPC::BI__builtin_vsx_xvnmaddasp: 8782 case PPC::BI__builtin_vsx_xvmsubadp: 8783 case PPC::BI__builtin_vsx_xvmsubasp: 8784 case PPC::BI__builtin_vsx_xvnmsubadp: 8785 case PPC::BI__builtin_vsx_xvnmsubasp: { 8786 llvm::Type *ResultType = ConvertType(E->getType()); 8787 Value *X = EmitScalarExpr(E->getArg(0)); 8788 Value *Y = EmitScalarExpr(E->getArg(1)); 8789 Value *Z = EmitScalarExpr(E->getArg(2)); 8790 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 8791 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 8792 switch (BuiltinID) { 8793 case PPC::BI__builtin_vsx_xvmaddadp: 8794 case PPC::BI__builtin_vsx_xvmaddasp: 8795 return Builder.CreateCall(F, {X, Y, Z}); 8796 case PPC::BI__builtin_vsx_xvnmaddadp: 8797 case PPC::BI__builtin_vsx_xvnmaddasp: 8798 return Builder.CreateFSub(Zero, 8799 Builder.CreateCall(F, {X, Y, Z}), "sub"); 8800 case PPC::BI__builtin_vsx_xvmsubadp: 8801 case PPC::BI__builtin_vsx_xvmsubasp: 8802 return Builder.CreateCall(F, 8803 {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8804 case PPC::BI__builtin_vsx_xvnmsubadp: 8805 case PPC::BI__builtin_vsx_xvnmsubasp: 8806 Value *FsubRes = 8807 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8808 return Builder.CreateFSub(Zero, FsubRes, "sub"); 8809 } 8810 llvm_unreachable("Unknown FMA operation"); 8811 return nullptr; // Suppress no-return warning 8812 } 8813 8814 case PPC::BI__builtin_vsx_insertword: { 8815 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw); 8816 8817 // Third argument is a compile time constant int. It must be clamped to 8818 // to the range [0, 12]. 8819 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8820 assert(ArgCI && 8821 "Third arg to xxinsertw intrinsic must be constant integer"); 8822 const int64_t MaxIndex = 12; 8823 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8824 8825 // The builtin semantics don't exactly match the xxinsertw instructions 8826 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the 8827 // word from the first argument, and inserts it in the second argument. The 8828 // instruction extracts the word from its second input register and inserts 8829 // it into its first input register, so swap the first and second arguments. 8830 std::swap(Ops[0], Ops[1]); 8831 8832 // Need to cast the second argument from a vector of unsigned int to a 8833 // vector of long long. 8834 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8835 8836 if (getTarget().isLittleEndian()) { 8837 // Create a shuffle mask of (1, 0) 8838 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8839 ConstantInt::get(Int32Ty, 0) 8840 }; 8841 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8842 8843 // Reverse the double words in the vector we will extract from. 8844 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8845 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask); 8846 8847 // Reverse the index. 8848 Index = MaxIndex - Index; 8849 } 8850 8851 // Intrinsic expects the first arg to be a vector of int. 8852 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8853 Ops[2] = ConstantInt::getSigned(Int32Ty, Index); 8854 return Builder.CreateCall(F, Ops); 8855 } 8856 8857 case PPC::BI__builtin_vsx_extractuword: { 8858 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw); 8859 8860 // Intrinsic expects the first argument to be a vector of doublewords. 8861 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8862 8863 // The second argument is a compile time constant int that needs to 8864 // be clamped to the range [0, 12]. 8865 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]); 8866 assert(ArgCI && 8867 "Second Arg to xxextractuw intrinsic must be a constant integer!"); 8868 const int64_t MaxIndex = 12; 8869 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8870 8871 if (getTarget().isLittleEndian()) { 8872 // Reverse the index. 8873 Index = MaxIndex - Index; 8874 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8875 8876 // Emit the call, then reverse the double words of the results vector. 8877 Value *Call = Builder.CreateCall(F, Ops); 8878 8879 // Create a shuffle mask of (1, 0) 8880 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8881 ConstantInt::get(Int32Ty, 0) 8882 }; 8883 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8884 8885 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask); 8886 return ShuffleCall; 8887 } else { 8888 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8889 return Builder.CreateCall(F, Ops); 8890 } 8891 } 8892 8893 case PPC::BI__builtin_vsx_xxpermdi: { 8894 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8895 assert(ArgCI && "Third arg must be constant integer!"); 8896 8897 unsigned Index = ArgCI->getZExtValue(); 8898 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8899 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8900 8901 // Element zero comes from the first input vector and element one comes from 8902 // the second. The element indices within each vector are numbered in big 8903 // endian order so the shuffle mask must be adjusted for this on little 8904 // endian platforms (i.e. index is complemented and source vector reversed). 8905 unsigned ElemIdx0; 8906 unsigned ElemIdx1; 8907 if (getTarget().isLittleEndian()) { 8908 ElemIdx0 = (~Index & 1) + 2; 8909 ElemIdx1 = (~Index & 2) >> 1; 8910 } else { // BigEndian 8911 ElemIdx0 = (Index & 2) >> 1; 8912 ElemIdx1 = 2 + (Index & 1); 8913 } 8914 8915 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0), 8916 ConstantInt::get(Int32Ty, ElemIdx1)}; 8917 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8918 8919 Value *ShuffleCall = 8920 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8921 QualType BIRetType = E->getType(); 8922 auto RetTy = ConvertType(BIRetType); 8923 return Builder.CreateBitCast(ShuffleCall, RetTy); 8924 } 8925 8926 case PPC::BI__builtin_vsx_xxsldwi: { 8927 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8928 assert(ArgCI && "Third argument must be a compile time constant"); 8929 unsigned Index = ArgCI->getZExtValue() & 0x3; 8930 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8931 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4)); 8932 8933 // Create a shuffle mask 8934 unsigned ElemIdx0; 8935 unsigned ElemIdx1; 8936 unsigned ElemIdx2; 8937 unsigned ElemIdx3; 8938 if (getTarget().isLittleEndian()) { 8939 // Little endian element N comes from element 8+N-Index of the 8940 // concatenated wide vector (of course, using modulo arithmetic on 8941 // the total number of elements). 8942 ElemIdx0 = (8 - Index) % 8; 8943 ElemIdx1 = (9 - Index) % 8; 8944 ElemIdx2 = (10 - Index) % 8; 8945 ElemIdx3 = (11 - Index) % 8; 8946 } else { 8947 // Big endian ElemIdx<N> = Index + N 8948 ElemIdx0 = Index; 8949 ElemIdx1 = Index + 1; 8950 ElemIdx2 = Index + 2; 8951 ElemIdx3 = Index + 3; 8952 } 8953 8954 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0), 8955 ConstantInt::get(Int32Ty, ElemIdx1), 8956 ConstantInt::get(Int32Ty, ElemIdx2), 8957 ConstantInt::get(Int32Ty, ElemIdx3)}; 8958 8959 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8960 Value *ShuffleCall = 8961 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8962 QualType BIRetType = E->getType(); 8963 auto RetTy = ConvertType(BIRetType); 8964 return Builder.CreateBitCast(ShuffleCall, RetTy); 8965 } 8966 } 8967 } 8968 8969 Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, 8970 const CallExpr *E) { 8971 switch (BuiltinID) { 8972 case AMDGPU::BI__builtin_amdgcn_div_scale: 8973 case AMDGPU::BI__builtin_amdgcn_div_scalef: { 8974 // Translate from the intrinsics's struct return to the builtin's out 8975 // argument. 8976 8977 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3)); 8978 8979 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 8980 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 8981 llvm::Value *Z = EmitScalarExpr(E->getArg(2)); 8982 8983 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale, 8984 X->getType()); 8985 8986 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z}); 8987 8988 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0); 8989 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1); 8990 8991 llvm::Type *RealFlagType 8992 = FlagOutPtr.getPointer()->getType()->getPointerElementType(); 8993 8994 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType); 8995 Builder.CreateStore(FlagExt, FlagOutPtr); 8996 return Result; 8997 } 8998 case AMDGPU::BI__builtin_amdgcn_div_fmas: 8999 case AMDGPU::BI__builtin_amdgcn_div_fmasf: { 9000 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0)); 9001 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1)); 9002 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2)); 9003 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3)); 9004 9005 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas, 9006 Src0->getType()); 9007 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3); 9008 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool}); 9009 } 9010 9011 case AMDGPU::BI__builtin_amdgcn_ds_swizzle: 9012 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle); 9013 case AMDGPU::BI__builtin_amdgcn_mov_dpp: { 9014 llvm::SmallVector<llvm::Value *, 5> Args; 9015 for (unsigned I = 0; I != 5; ++I) 9016 Args.push_back(EmitScalarExpr(E->getArg(I))); 9017 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp, 9018 Args[0]->getType()); 9019 return Builder.CreateCall(F, Args); 9020 } 9021 case AMDGPU::BI__builtin_amdgcn_div_fixup: 9022 case AMDGPU::BI__builtin_amdgcn_div_fixupf: 9023 case AMDGPU::BI__builtin_amdgcn_div_fixuph: 9024 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup); 9025 case AMDGPU::BI__builtin_amdgcn_trig_preop: 9026 case AMDGPU::BI__builtin_amdgcn_trig_preopf: 9027 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop); 9028 case AMDGPU::BI__builtin_amdgcn_rcp: 9029 case AMDGPU::BI__builtin_amdgcn_rcpf: 9030 case AMDGPU::BI__builtin_amdgcn_rcph: 9031 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp); 9032 case AMDGPU::BI__builtin_amdgcn_rsq: 9033 case AMDGPU::BI__builtin_amdgcn_rsqf: 9034 case AMDGPU::BI__builtin_amdgcn_rsqh: 9035 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq); 9036 case AMDGPU::BI__builtin_amdgcn_rsq_clamp: 9037 case AMDGPU::BI__builtin_amdgcn_rsq_clampf: 9038 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp); 9039 case AMDGPU::BI__builtin_amdgcn_sinf: 9040 case AMDGPU::BI__builtin_amdgcn_sinh: 9041 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin); 9042 case AMDGPU::BI__builtin_amdgcn_cosf: 9043 case AMDGPU::BI__builtin_amdgcn_cosh: 9044 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos); 9045 case AMDGPU::BI__builtin_amdgcn_log_clampf: 9046 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp); 9047 case AMDGPU::BI__builtin_amdgcn_ldexp: 9048 case AMDGPU::BI__builtin_amdgcn_ldexpf: 9049 case AMDGPU::BI__builtin_amdgcn_ldexph: 9050 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp); 9051 case AMDGPU::BI__builtin_amdgcn_frexp_mant: 9052 case AMDGPU::BI__builtin_amdgcn_frexp_mantf: 9053 case AMDGPU::BI__builtin_amdgcn_frexp_manth: 9054 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant); 9055 case AMDGPU::BI__builtin_amdgcn_frexp_exp: 9056 case AMDGPU::BI__builtin_amdgcn_frexp_expf: { 9057 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9058 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9059 { Builder.getInt32Ty(), Src0->getType() }); 9060 return Builder.CreateCall(F, Src0); 9061 } 9062 case AMDGPU::BI__builtin_amdgcn_frexp_exph: { 9063 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9064 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9065 { Builder.getInt16Ty(), Src0->getType() }); 9066 return Builder.CreateCall(F, Src0); 9067 } 9068 case AMDGPU::BI__builtin_amdgcn_fract: 9069 case AMDGPU::BI__builtin_amdgcn_fractf: 9070 case AMDGPU::BI__builtin_amdgcn_fracth: 9071 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract); 9072 case AMDGPU::BI__builtin_amdgcn_lerp: 9073 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp); 9074 case AMDGPU::BI__builtin_amdgcn_uicmp: 9075 case AMDGPU::BI__builtin_amdgcn_uicmpl: 9076 case AMDGPU::BI__builtin_amdgcn_sicmp: 9077 case AMDGPU::BI__builtin_amdgcn_sicmpl: 9078 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp); 9079 case AMDGPU::BI__builtin_amdgcn_fcmp: 9080 case AMDGPU::BI__builtin_amdgcn_fcmpf: 9081 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp); 9082 case AMDGPU::BI__builtin_amdgcn_class: 9083 case AMDGPU::BI__builtin_amdgcn_classf: 9084 case AMDGPU::BI__builtin_amdgcn_classh: 9085 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class); 9086 case AMDGPU::BI__builtin_amdgcn_fmed3f: 9087 case AMDGPU::BI__builtin_amdgcn_fmed3h: 9088 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3); 9089 case AMDGPU::BI__builtin_amdgcn_read_exec: { 9090 CallInst *CI = cast<CallInst>( 9091 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec")); 9092 CI->setConvergent(); 9093 return CI; 9094 } 9095 case AMDGPU::BI__builtin_amdgcn_read_exec_lo: 9096 case AMDGPU::BI__builtin_amdgcn_read_exec_hi: { 9097 StringRef RegName = BuiltinID == AMDGPU::BI__builtin_amdgcn_read_exec_lo ? 9098 "exec_lo" : "exec_hi"; 9099 CallInst *CI = cast<CallInst>( 9100 EmitSpecialRegisterBuiltin(*this, E, Int32Ty, Int32Ty, true, RegName)); 9101 CI->setConvergent(); 9102 return CI; 9103 } 9104 9105 // amdgcn workitem 9106 case AMDGPU::BI__builtin_amdgcn_workitem_id_x: 9107 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024); 9108 case AMDGPU::BI__builtin_amdgcn_workitem_id_y: 9109 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024); 9110 case AMDGPU::BI__builtin_amdgcn_workitem_id_z: 9111 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024); 9112 9113 // r600 intrinsics 9114 case AMDGPU::BI__builtin_r600_recipsqrt_ieee: 9115 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef: 9116 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee); 9117 case AMDGPU::BI__builtin_r600_read_tidig_x: 9118 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024); 9119 case AMDGPU::BI__builtin_r600_read_tidig_y: 9120 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024); 9121 case AMDGPU::BI__builtin_r600_read_tidig_z: 9122 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024); 9123 default: 9124 return nullptr; 9125 } 9126 } 9127 9128 /// Handle a SystemZ function in which the final argument is a pointer 9129 /// to an int that receives the post-instruction CC value. At the LLVM level 9130 /// this is represented as a function that returns a {result, cc} pair. 9131 static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF, 9132 unsigned IntrinsicID, 9133 const CallExpr *E) { 9134 unsigned NumArgs = E->getNumArgs() - 1; 9135 SmallVector<Value *, 8> Args(NumArgs); 9136 for (unsigned I = 0; I < NumArgs; ++I) 9137 Args[I] = CGF.EmitScalarExpr(E->getArg(I)); 9138 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs)); 9139 Value *F = CGF.CGM.getIntrinsic(IntrinsicID); 9140 Value *Call = CGF.Builder.CreateCall(F, Args); 9141 Value *CC = CGF.Builder.CreateExtractValue(Call, 1); 9142 CGF.Builder.CreateStore(CC, CCPtr); 9143 return CGF.Builder.CreateExtractValue(Call, 0); 9144 } 9145 9146 Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, 9147 const CallExpr *E) { 9148 switch (BuiltinID) { 9149 case SystemZ::BI__builtin_tbegin: { 9150 Value *TDB = EmitScalarExpr(E->getArg(0)); 9151 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9152 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin); 9153 return Builder.CreateCall(F, {TDB, Control}); 9154 } 9155 case SystemZ::BI__builtin_tbegin_nofloat: { 9156 Value *TDB = EmitScalarExpr(E->getArg(0)); 9157 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9158 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat); 9159 return Builder.CreateCall(F, {TDB, Control}); 9160 } 9161 case SystemZ::BI__builtin_tbeginc: { 9162 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy); 9163 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08); 9164 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc); 9165 return Builder.CreateCall(F, {TDB, Control}); 9166 } 9167 case SystemZ::BI__builtin_tabort: { 9168 Value *Data = EmitScalarExpr(E->getArg(0)); 9169 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort); 9170 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort")); 9171 } 9172 case SystemZ::BI__builtin_non_tx_store: { 9173 Value *Address = EmitScalarExpr(E->getArg(0)); 9174 Value *Data = EmitScalarExpr(E->getArg(1)); 9175 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); 9176 return Builder.CreateCall(F, {Data, Address}); 9177 } 9178 9179 // Vector builtins. Note that most vector builtins are mapped automatically 9180 // to target-specific LLVM intrinsics. The ones handled specially here can 9181 // be represented via standard LLVM IR, which is preferable to enable common 9182 // LLVM optimizations. 9183 9184 case SystemZ::BI__builtin_s390_vpopctb: 9185 case SystemZ::BI__builtin_s390_vpopcth: 9186 case SystemZ::BI__builtin_s390_vpopctf: 9187 case SystemZ::BI__builtin_s390_vpopctg: { 9188 llvm::Type *ResultType = ConvertType(E->getType()); 9189 Value *X = EmitScalarExpr(E->getArg(0)); 9190 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 9191 return Builder.CreateCall(F, X); 9192 } 9193 9194 case SystemZ::BI__builtin_s390_vclzb: 9195 case SystemZ::BI__builtin_s390_vclzh: 9196 case SystemZ::BI__builtin_s390_vclzf: 9197 case SystemZ::BI__builtin_s390_vclzg: { 9198 llvm::Type *ResultType = ConvertType(E->getType()); 9199 Value *X = EmitScalarExpr(E->getArg(0)); 9200 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9201 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 9202 return Builder.CreateCall(F, {X, Undef}); 9203 } 9204 9205 case SystemZ::BI__builtin_s390_vctzb: 9206 case SystemZ::BI__builtin_s390_vctzh: 9207 case SystemZ::BI__builtin_s390_vctzf: 9208 case SystemZ::BI__builtin_s390_vctzg: { 9209 llvm::Type *ResultType = ConvertType(E->getType()); 9210 Value *X = EmitScalarExpr(E->getArg(0)); 9211 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9212 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 9213 return Builder.CreateCall(F, {X, Undef}); 9214 } 9215 9216 case SystemZ::BI__builtin_s390_vfsqsb: 9217 case SystemZ::BI__builtin_s390_vfsqdb: { 9218 llvm::Type *ResultType = ConvertType(E->getType()); 9219 Value *X = EmitScalarExpr(E->getArg(0)); 9220 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType); 9221 return Builder.CreateCall(F, X); 9222 } 9223 case SystemZ::BI__builtin_s390_vfmasb: 9224 case SystemZ::BI__builtin_s390_vfmadb: { 9225 llvm::Type *ResultType = ConvertType(E->getType()); 9226 Value *X = EmitScalarExpr(E->getArg(0)); 9227 Value *Y = EmitScalarExpr(E->getArg(1)); 9228 Value *Z = EmitScalarExpr(E->getArg(2)); 9229 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9230 return Builder.CreateCall(F, {X, Y, Z}); 9231 } 9232 case SystemZ::BI__builtin_s390_vfmssb: 9233 case SystemZ::BI__builtin_s390_vfmsdb: { 9234 llvm::Type *ResultType = ConvertType(E->getType()); 9235 Value *X = EmitScalarExpr(E->getArg(0)); 9236 Value *Y = EmitScalarExpr(E->getArg(1)); 9237 Value *Z = EmitScalarExpr(E->getArg(2)); 9238 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9239 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9240 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 9241 } 9242 case SystemZ::BI__builtin_s390_vfnmasb: 9243 case SystemZ::BI__builtin_s390_vfnmadb: { 9244 llvm::Type *ResultType = ConvertType(E->getType()); 9245 Value *X = EmitScalarExpr(E->getArg(0)); 9246 Value *Y = EmitScalarExpr(E->getArg(1)); 9247 Value *Z = EmitScalarExpr(E->getArg(2)); 9248 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9249 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9250 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub"); 9251 } 9252 case SystemZ::BI__builtin_s390_vfnmssb: 9253 case SystemZ::BI__builtin_s390_vfnmsdb: { 9254 llvm::Type *ResultType = ConvertType(E->getType()); 9255 Value *X = EmitScalarExpr(E->getArg(0)); 9256 Value *Y = EmitScalarExpr(E->getArg(1)); 9257 Value *Z = EmitScalarExpr(E->getArg(2)); 9258 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9259 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9260 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub"); 9261 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ})); 9262 } 9263 case SystemZ::BI__builtin_s390_vflpsb: 9264 case SystemZ::BI__builtin_s390_vflpdb: { 9265 llvm::Type *ResultType = ConvertType(E->getType()); 9266 Value *X = EmitScalarExpr(E->getArg(0)); 9267 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9268 return Builder.CreateCall(F, X); 9269 } 9270 case SystemZ::BI__builtin_s390_vflnsb: 9271 case SystemZ::BI__builtin_s390_vflndb: { 9272 llvm::Type *ResultType = ConvertType(E->getType()); 9273 Value *X = EmitScalarExpr(E->getArg(0)); 9274 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9275 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9276 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub"); 9277 } 9278 case SystemZ::BI__builtin_s390_vfisb: 9279 case SystemZ::BI__builtin_s390_vfidb: { 9280 llvm::Type *ResultType = ConvertType(E->getType()); 9281 Value *X = EmitScalarExpr(E->getArg(0)); 9282 // Constant-fold the M4 and M5 mask arguments. 9283 llvm::APSInt M4, M5; 9284 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext()); 9285 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext()); 9286 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?"); 9287 (void)IsConstM4; (void)IsConstM5; 9288 // Check whether this instance can be represented via a LLVM standard 9289 // intrinsic. We only support some combinations of M4 and M5. 9290 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9291 switch (M4.getZExtValue()) { 9292 default: break; 9293 case 0: // IEEE-inexact exception allowed 9294 switch (M5.getZExtValue()) { 9295 default: break; 9296 case 0: ID = Intrinsic::rint; break; 9297 } 9298 break; 9299 case 4: // IEEE-inexact exception suppressed 9300 switch (M5.getZExtValue()) { 9301 default: break; 9302 case 0: ID = Intrinsic::nearbyint; break; 9303 case 1: ID = Intrinsic::round; break; 9304 case 5: ID = Intrinsic::trunc; break; 9305 case 6: ID = Intrinsic::ceil; break; 9306 case 7: ID = Intrinsic::floor; break; 9307 } 9308 break; 9309 } 9310 if (ID != Intrinsic::not_intrinsic) { 9311 Function *F = CGM.getIntrinsic(ID, ResultType); 9312 return Builder.CreateCall(F, X); 9313 } 9314 switch (BuiltinID) { 9315 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break; 9316 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break; 9317 default: llvm_unreachable("Unknown BuiltinID"); 9318 } 9319 Function *F = CGM.getIntrinsic(ID); 9320 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9321 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5); 9322 return Builder.CreateCall(F, {X, M4Value, M5Value}); 9323 } 9324 case SystemZ::BI__builtin_s390_vfmaxsb: 9325 case SystemZ::BI__builtin_s390_vfmaxdb: { 9326 llvm::Type *ResultType = ConvertType(E->getType()); 9327 Value *X = EmitScalarExpr(E->getArg(0)); 9328 Value *Y = EmitScalarExpr(E->getArg(1)); 9329 // Constant-fold the M4 mask argument. 9330 llvm::APSInt M4; 9331 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9332 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9333 (void)IsConstM4; 9334 // Check whether this instance can be represented via a LLVM standard 9335 // intrinsic. We only support some values of M4. 9336 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9337 switch (M4.getZExtValue()) { 9338 default: break; 9339 case 4: ID = Intrinsic::maxnum; break; 9340 } 9341 if (ID != Intrinsic::not_intrinsic) { 9342 Function *F = CGM.getIntrinsic(ID, ResultType); 9343 return Builder.CreateCall(F, {X, Y}); 9344 } 9345 switch (BuiltinID) { 9346 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break; 9347 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break; 9348 default: llvm_unreachable("Unknown BuiltinID"); 9349 } 9350 Function *F = CGM.getIntrinsic(ID); 9351 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9352 return Builder.CreateCall(F, {X, Y, M4Value}); 9353 } 9354 case SystemZ::BI__builtin_s390_vfminsb: 9355 case SystemZ::BI__builtin_s390_vfmindb: { 9356 llvm::Type *ResultType = ConvertType(E->getType()); 9357 Value *X = EmitScalarExpr(E->getArg(0)); 9358 Value *Y = EmitScalarExpr(E->getArg(1)); 9359 // Constant-fold the M4 mask argument. 9360 llvm::APSInt M4; 9361 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9362 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9363 (void)IsConstM4; 9364 // Check whether this instance can be represented via a LLVM standard 9365 // intrinsic. We only support some values of M4. 9366 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9367 switch (M4.getZExtValue()) { 9368 default: break; 9369 case 4: ID = Intrinsic::minnum; break; 9370 } 9371 if (ID != Intrinsic::not_intrinsic) { 9372 Function *F = CGM.getIntrinsic(ID, ResultType); 9373 return Builder.CreateCall(F, {X, Y}); 9374 } 9375 switch (BuiltinID) { 9376 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break; 9377 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break; 9378 default: llvm_unreachable("Unknown BuiltinID"); 9379 } 9380 Function *F = CGM.getIntrinsic(ID); 9381 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9382 return Builder.CreateCall(F, {X, Y, M4Value}); 9383 } 9384 9385 // Vector intrisincs that output the post-instruction CC value. 9386 9387 #define INTRINSIC_WITH_CC(NAME) \ 9388 case SystemZ::BI__builtin_##NAME: \ 9389 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E) 9390 9391 INTRINSIC_WITH_CC(s390_vpkshs); 9392 INTRINSIC_WITH_CC(s390_vpksfs); 9393 INTRINSIC_WITH_CC(s390_vpksgs); 9394 9395 INTRINSIC_WITH_CC(s390_vpklshs); 9396 INTRINSIC_WITH_CC(s390_vpklsfs); 9397 INTRINSIC_WITH_CC(s390_vpklsgs); 9398 9399 INTRINSIC_WITH_CC(s390_vceqbs); 9400 INTRINSIC_WITH_CC(s390_vceqhs); 9401 INTRINSIC_WITH_CC(s390_vceqfs); 9402 INTRINSIC_WITH_CC(s390_vceqgs); 9403 9404 INTRINSIC_WITH_CC(s390_vchbs); 9405 INTRINSIC_WITH_CC(s390_vchhs); 9406 INTRINSIC_WITH_CC(s390_vchfs); 9407 INTRINSIC_WITH_CC(s390_vchgs); 9408 9409 INTRINSIC_WITH_CC(s390_vchlbs); 9410 INTRINSIC_WITH_CC(s390_vchlhs); 9411 INTRINSIC_WITH_CC(s390_vchlfs); 9412 INTRINSIC_WITH_CC(s390_vchlgs); 9413 9414 INTRINSIC_WITH_CC(s390_vfaebs); 9415 INTRINSIC_WITH_CC(s390_vfaehs); 9416 INTRINSIC_WITH_CC(s390_vfaefs); 9417 9418 INTRINSIC_WITH_CC(s390_vfaezbs); 9419 INTRINSIC_WITH_CC(s390_vfaezhs); 9420 INTRINSIC_WITH_CC(s390_vfaezfs); 9421 9422 INTRINSIC_WITH_CC(s390_vfeebs); 9423 INTRINSIC_WITH_CC(s390_vfeehs); 9424 INTRINSIC_WITH_CC(s390_vfeefs); 9425 9426 INTRINSIC_WITH_CC(s390_vfeezbs); 9427 INTRINSIC_WITH_CC(s390_vfeezhs); 9428 INTRINSIC_WITH_CC(s390_vfeezfs); 9429 9430 INTRINSIC_WITH_CC(s390_vfenebs); 9431 INTRINSIC_WITH_CC(s390_vfenehs); 9432 INTRINSIC_WITH_CC(s390_vfenefs); 9433 9434 INTRINSIC_WITH_CC(s390_vfenezbs); 9435 INTRINSIC_WITH_CC(s390_vfenezhs); 9436 INTRINSIC_WITH_CC(s390_vfenezfs); 9437 9438 INTRINSIC_WITH_CC(s390_vistrbs); 9439 INTRINSIC_WITH_CC(s390_vistrhs); 9440 INTRINSIC_WITH_CC(s390_vistrfs); 9441 9442 INTRINSIC_WITH_CC(s390_vstrcbs); 9443 INTRINSIC_WITH_CC(s390_vstrchs); 9444 INTRINSIC_WITH_CC(s390_vstrcfs); 9445 9446 INTRINSIC_WITH_CC(s390_vstrczbs); 9447 INTRINSIC_WITH_CC(s390_vstrczhs); 9448 INTRINSIC_WITH_CC(s390_vstrczfs); 9449 9450 INTRINSIC_WITH_CC(s390_vfcesbs); 9451 INTRINSIC_WITH_CC(s390_vfcedbs); 9452 INTRINSIC_WITH_CC(s390_vfchsbs); 9453 INTRINSIC_WITH_CC(s390_vfchdbs); 9454 INTRINSIC_WITH_CC(s390_vfchesbs); 9455 INTRINSIC_WITH_CC(s390_vfchedbs); 9456 9457 INTRINSIC_WITH_CC(s390_vftcisb); 9458 INTRINSIC_WITH_CC(s390_vftcidb); 9459 9460 #undef INTRINSIC_WITH_CC 9461 9462 default: 9463 return nullptr; 9464 } 9465 } 9466 9467 Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, 9468 const CallExpr *E) { 9469 auto MakeLdg = [&](unsigned IntrinsicID) { 9470 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9471 clang::CharUnits Align = 9472 getNaturalPointeeTypeAlignment(E->getArg(0)->getType()); 9473 return Builder.CreateCall( 9474 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9475 Ptr->getType()}), 9476 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())}); 9477 }; 9478 auto MakeScopedAtomic = [&](unsigned IntrinsicID) { 9479 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9480 return Builder.CreateCall( 9481 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9482 Ptr->getType()}), 9483 {Ptr, EmitScalarExpr(E->getArg(1))}); 9484 }; 9485 switch (BuiltinID) { 9486 case NVPTX::BI__nvvm_atom_add_gen_i: 9487 case NVPTX::BI__nvvm_atom_add_gen_l: 9488 case NVPTX::BI__nvvm_atom_add_gen_ll: 9489 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E); 9490 9491 case NVPTX::BI__nvvm_atom_sub_gen_i: 9492 case NVPTX::BI__nvvm_atom_sub_gen_l: 9493 case NVPTX::BI__nvvm_atom_sub_gen_ll: 9494 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E); 9495 9496 case NVPTX::BI__nvvm_atom_and_gen_i: 9497 case NVPTX::BI__nvvm_atom_and_gen_l: 9498 case NVPTX::BI__nvvm_atom_and_gen_ll: 9499 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E); 9500 9501 case NVPTX::BI__nvvm_atom_or_gen_i: 9502 case NVPTX::BI__nvvm_atom_or_gen_l: 9503 case NVPTX::BI__nvvm_atom_or_gen_ll: 9504 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E); 9505 9506 case NVPTX::BI__nvvm_atom_xor_gen_i: 9507 case NVPTX::BI__nvvm_atom_xor_gen_l: 9508 case NVPTX::BI__nvvm_atom_xor_gen_ll: 9509 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E); 9510 9511 case NVPTX::BI__nvvm_atom_xchg_gen_i: 9512 case NVPTX::BI__nvvm_atom_xchg_gen_l: 9513 case NVPTX::BI__nvvm_atom_xchg_gen_ll: 9514 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E); 9515 9516 case NVPTX::BI__nvvm_atom_max_gen_i: 9517 case NVPTX::BI__nvvm_atom_max_gen_l: 9518 case NVPTX::BI__nvvm_atom_max_gen_ll: 9519 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E); 9520 9521 case NVPTX::BI__nvvm_atom_max_gen_ui: 9522 case NVPTX::BI__nvvm_atom_max_gen_ul: 9523 case NVPTX::BI__nvvm_atom_max_gen_ull: 9524 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E); 9525 9526 case NVPTX::BI__nvvm_atom_min_gen_i: 9527 case NVPTX::BI__nvvm_atom_min_gen_l: 9528 case NVPTX::BI__nvvm_atom_min_gen_ll: 9529 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E); 9530 9531 case NVPTX::BI__nvvm_atom_min_gen_ui: 9532 case NVPTX::BI__nvvm_atom_min_gen_ul: 9533 case NVPTX::BI__nvvm_atom_min_gen_ull: 9534 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E); 9535 9536 case NVPTX::BI__nvvm_atom_cas_gen_i: 9537 case NVPTX::BI__nvvm_atom_cas_gen_l: 9538 case NVPTX::BI__nvvm_atom_cas_gen_ll: 9539 // __nvvm_atom_cas_gen_* should return the old value rather than the 9540 // success flag. 9541 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false); 9542 9543 case NVPTX::BI__nvvm_atom_add_gen_f: { 9544 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9545 Value *Val = EmitScalarExpr(E->getArg(1)); 9546 // atomicrmw only deals with integer arguments so we need to use 9547 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that. 9548 Value *FnALAF32 = 9549 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType()); 9550 return Builder.CreateCall(FnALAF32, {Ptr, Val}); 9551 } 9552 9553 case NVPTX::BI__nvvm_atom_add_gen_d: { 9554 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9555 Value *Val = EmitScalarExpr(E->getArg(1)); 9556 // atomicrmw only deals with integer arguments, so we need to use 9557 // LLVM's nvvm_atomic_load_add_f64 intrinsic. 9558 Value *FnALAF64 = 9559 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f64, Ptr->getType()); 9560 return Builder.CreateCall(FnALAF64, {Ptr, Val}); 9561 } 9562 9563 case NVPTX::BI__nvvm_atom_inc_gen_ui: { 9564 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9565 Value *Val = EmitScalarExpr(E->getArg(1)); 9566 Value *FnALI32 = 9567 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType()); 9568 return Builder.CreateCall(FnALI32, {Ptr, Val}); 9569 } 9570 9571 case NVPTX::BI__nvvm_atom_dec_gen_ui: { 9572 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9573 Value *Val = EmitScalarExpr(E->getArg(1)); 9574 Value *FnALD32 = 9575 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType()); 9576 return Builder.CreateCall(FnALD32, {Ptr, Val}); 9577 } 9578 9579 case NVPTX::BI__nvvm_ldg_c: 9580 case NVPTX::BI__nvvm_ldg_c2: 9581 case NVPTX::BI__nvvm_ldg_c4: 9582 case NVPTX::BI__nvvm_ldg_s: 9583 case NVPTX::BI__nvvm_ldg_s2: 9584 case NVPTX::BI__nvvm_ldg_s4: 9585 case NVPTX::BI__nvvm_ldg_i: 9586 case NVPTX::BI__nvvm_ldg_i2: 9587 case NVPTX::BI__nvvm_ldg_i4: 9588 case NVPTX::BI__nvvm_ldg_l: 9589 case NVPTX::BI__nvvm_ldg_ll: 9590 case NVPTX::BI__nvvm_ldg_ll2: 9591 case NVPTX::BI__nvvm_ldg_uc: 9592 case NVPTX::BI__nvvm_ldg_uc2: 9593 case NVPTX::BI__nvvm_ldg_uc4: 9594 case NVPTX::BI__nvvm_ldg_us: 9595 case NVPTX::BI__nvvm_ldg_us2: 9596 case NVPTX::BI__nvvm_ldg_us4: 9597 case NVPTX::BI__nvvm_ldg_ui: 9598 case NVPTX::BI__nvvm_ldg_ui2: 9599 case NVPTX::BI__nvvm_ldg_ui4: 9600 case NVPTX::BI__nvvm_ldg_ul: 9601 case NVPTX::BI__nvvm_ldg_ull: 9602 case NVPTX::BI__nvvm_ldg_ull2: 9603 // PTX Interoperability section 2.2: "For a vector with an even number of 9604 // elements, its alignment is set to number of elements times the alignment 9605 // of its member: n*alignof(t)." 9606 return MakeLdg(Intrinsic::nvvm_ldg_global_i); 9607 case NVPTX::BI__nvvm_ldg_f: 9608 case NVPTX::BI__nvvm_ldg_f2: 9609 case NVPTX::BI__nvvm_ldg_f4: 9610 case NVPTX::BI__nvvm_ldg_d: 9611 case NVPTX::BI__nvvm_ldg_d2: 9612 return MakeLdg(Intrinsic::nvvm_ldg_global_f); 9613 9614 case NVPTX::BI__nvvm_atom_cta_add_gen_i: 9615 case NVPTX::BI__nvvm_atom_cta_add_gen_l: 9616 case NVPTX::BI__nvvm_atom_cta_add_gen_ll: 9617 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta); 9618 case NVPTX::BI__nvvm_atom_sys_add_gen_i: 9619 case NVPTX::BI__nvvm_atom_sys_add_gen_l: 9620 case NVPTX::BI__nvvm_atom_sys_add_gen_ll: 9621 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys); 9622 case NVPTX::BI__nvvm_atom_cta_add_gen_f: 9623 case NVPTX::BI__nvvm_atom_cta_add_gen_d: 9624 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta); 9625 case NVPTX::BI__nvvm_atom_sys_add_gen_f: 9626 case NVPTX::BI__nvvm_atom_sys_add_gen_d: 9627 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys); 9628 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i: 9629 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l: 9630 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll: 9631 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta); 9632 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i: 9633 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l: 9634 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll: 9635 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys); 9636 case NVPTX::BI__nvvm_atom_cta_max_gen_i: 9637 case NVPTX::BI__nvvm_atom_cta_max_gen_ui: 9638 case NVPTX::BI__nvvm_atom_cta_max_gen_l: 9639 case NVPTX::BI__nvvm_atom_cta_max_gen_ul: 9640 case NVPTX::BI__nvvm_atom_cta_max_gen_ll: 9641 case NVPTX::BI__nvvm_atom_cta_max_gen_ull: 9642 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta); 9643 case NVPTX::BI__nvvm_atom_sys_max_gen_i: 9644 case NVPTX::BI__nvvm_atom_sys_max_gen_ui: 9645 case NVPTX::BI__nvvm_atom_sys_max_gen_l: 9646 case NVPTX::BI__nvvm_atom_sys_max_gen_ul: 9647 case NVPTX::BI__nvvm_atom_sys_max_gen_ll: 9648 case NVPTX::BI__nvvm_atom_sys_max_gen_ull: 9649 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys); 9650 case NVPTX::BI__nvvm_atom_cta_min_gen_i: 9651 case NVPTX::BI__nvvm_atom_cta_min_gen_ui: 9652 case NVPTX::BI__nvvm_atom_cta_min_gen_l: 9653 case NVPTX::BI__nvvm_atom_cta_min_gen_ul: 9654 case NVPTX::BI__nvvm_atom_cta_min_gen_ll: 9655 case NVPTX::BI__nvvm_atom_cta_min_gen_ull: 9656 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta); 9657 case NVPTX::BI__nvvm_atom_sys_min_gen_i: 9658 case NVPTX::BI__nvvm_atom_sys_min_gen_ui: 9659 case NVPTX::BI__nvvm_atom_sys_min_gen_l: 9660 case NVPTX::BI__nvvm_atom_sys_min_gen_ul: 9661 case NVPTX::BI__nvvm_atom_sys_min_gen_ll: 9662 case NVPTX::BI__nvvm_atom_sys_min_gen_ull: 9663 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys); 9664 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui: 9665 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta); 9666 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui: 9667 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta); 9668 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui: 9669 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys); 9670 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui: 9671 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys); 9672 case NVPTX::BI__nvvm_atom_cta_and_gen_i: 9673 case NVPTX::BI__nvvm_atom_cta_and_gen_l: 9674 case NVPTX::BI__nvvm_atom_cta_and_gen_ll: 9675 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta); 9676 case NVPTX::BI__nvvm_atom_sys_and_gen_i: 9677 case NVPTX::BI__nvvm_atom_sys_and_gen_l: 9678 case NVPTX::BI__nvvm_atom_sys_and_gen_ll: 9679 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys); 9680 case NVPTX::BI__nvvm_atom_cta_or_gen_i: 9681 case NVPTX::BI__nvvm_atom_cta_or_gen_l: 9682 case NVPTX::BI__nvvm_atom_cta_or_gen_ll: 9683 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta); 9684 case NVPTX::BI__nvvm_atom_sys_or_gen_i: 9685 case NVPTX::BI__nvvm_atom_sys_or_gen_l: 9686 case NVPTX::BI__nvvm_atom_sys_or_gen_ll: 9687 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys); 9688 case NVPTX::BI__nvvm_atom_cta_xor_gen_i: 9689 case NVPTX::BI__nvvm_atom_cta_xor_gen_l: 9690 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll: 9691 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta); 9692 case NVPTX::BI__nvvm_atom_sys_xor_gen_i: 9693 case NVPTX::BI__nvvm_atom_sys_xor_gen_l: 9694 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll: 9695 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys); 9696 case NVPTX::BI__nvvm_atom_cta_cas_gen_i: 9697 case NVPTX::BI__nvvm_atom_cta_cas_gen_l: 9698 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: { 9699 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9700 return Builder.CreateCall( 9701 CGM.getIntrinsic( 9702 Intrinsic::nvvm_atomic_cas_gen_i_cta, 9703 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9704 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9705 } 9706 case NVPTX::BI__nvvm_atom_sys_cas_gen_i: 9707 case NVPTX::BI__nvvm_atom_sys_cas_gen_l: 9708 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: { 9709 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9710 return Builder.CreateCall( 9711 CGM.getIntrinsic( 9712 Intrinsic::nvvm_atomic_cas_gen_i_sys, 9713 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9714 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9715 } 9716 case NVPTX::BI__nvvm_match_all_sync_i32p: 9717 case NVPTX::BI__nvvm_match_all_sync_i64p: { 9718 Value *Mask = EmitScalarExpr(E->getArg(0)); 9719 Value *Val = EmitScalarExpr(E->getArg(1)); 9720 Address PredOutPtr = EmitPointerWithAlignment(E->getArg(2)); 9721 Value *ResultPair = Builder.CreateCall( 9722 CGM.getIntrinsic(BuiltinID == NVPTX::BI__nvvm_match_all_sync_i32p 9723 ? Intrinsic::nvvm_match_all_sync_i32p 9724 : Intrinsic::nvvm_match_all_sync_i64p), 9725 {Mask, Val}); 9726 Value *Pred = Builder.CreateZExt(Builder.CreateExtractValue(ResultPair, 1), 9727 PredOutPtr.getElementType()); 9728 Builder.CreateStore(Pred, PredOutPtr); 9729 return Builder.CreateExtractValue(ResultPair, 0); 9730 } 9731 case NVPTX::BI__hmma_m16n16k16_ld_a: 9732 case NVPTX::BI__hmma_m16n16k16_ld_b: 9733 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9734 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: { 9735 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9736 Value *Src = EmitScalarExpr(E->getArg(1)); 9737 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9738 llvm::APSInt isColMajorArg; 9739 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9740 return nullptr; 9741 bool isColMajor = isColMajorArg.getSExtValue(); 9742 unsigned IID; 9743 unsigned NumResults; 9744 switch (BuiltinID) { 9745 case NVPTX::BI__hmma_m16n16k16_ld_a: 9746 IID = isColMajor ? Intrinsic::nvvm_wmma_load_a_f16_col_stride 9747 : Intrinsic::nvvm_wmma_load_a_f16_row_stride; 9748 NumResults = 8; 9749 break; 9750 case NVPTX::BI__hmma_m16n16k16_ld_b: 9751 IID = isColMajor ? Intrinsic::nvvm_wmma_load_b_f16_col_stride 9752 : Intrinsic::nvvm_wmma_load_b_f16_row_stride; 9753 NumResults = 8; 9754 break; 9755 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9756 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f16_col_stride 9757 : Intrinsic::nvvm_wmma_load_c_f16_row_stride; 9758 NumResults = 4; 9759 break; 9760 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: 9761 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f32_col_stride 9762 : Intrinsic::nvvm_wmma_load_c_f32_row_stride; 9763 NumResults = 8; 9764 break; 9765 default: 9766 llvm_unreachable("Unexpected builtin ID."); 9767 } 9768 Value *Result = 9769 Builder.CreateCall(CGM.getIntrinsic(IID), 9770 {Builder.CreatePointerCast(Src, VoidPtrTy), Ldm}); 9771 9772 // Save returned values. 9773 for (unsigned i = 0; i < NumResults; ++i) { 9774 Builder.CreateAlignedStore( 9775 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), 9776 Dst.getElementType()), 9777 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9778 CharUnits::fromQuantity(4)); 9779 } 9780 return Result; 9781 } 9782 9783 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9784 case NVPTX::BI__hmma_m16n16k16_st_c_f32: { 9785 Value *Dst = EmitScalarExpr(E->getArg(0)); 9786 Address Src = EmitPointerWithAlignment(E->getArg(1)); 9787 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9788 llvm::APSInt isColMajorArg; 9789 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9790 return nullptr; 9791 bool isColMajor = isColMajorArg.getSExtValue(); 9792 unsigned IID; 9793 unsigned NumResults = 8; 9794 // PTX Instructions (and LLVM instrinsics) are defined for slice _d_, yet 9795 // for some reason nvcc builtins use _c_. 9796 switch (BuiltinID) { 9797 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9798 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f16_col_stride 9799 : Intrinsic::nvvm_wmma_store_d_f16_row_stride; 9800 NumResults = 4; 9801 break; 9802 case NVPTX::BI__hmma_m16n16k16_st_c_f32: 9803 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f32_col_stride 9804 : Intrinsic::nvvm_wmma_store_d_f32_row_stride; 9805 break; 9806 default: 9807 llvm_unreachable("Unexpected builtin ID."); 9808 } 9809 Function *Intrinsic = CGM.getIntrinsic(IID); 9810 llvm::Type *ParamType = Intrinsic->getFunctionType()->getParamType(1); 9811 SmallVector<Value *, 10> Values; 9812 Values.push_back(Builder.CreatePointerCast(Dst, VoidPtrTy)); 9813 for (unsigned i = 0; i < NumResults; ++i) { 9814 Value *V = Builder.CreateAlignedLoad( 9815 Builder.CreateGEP(Src.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9816 CharUnits::fromQuantity(4)); 9817 Values.push_back(Builder.CreateBitCast(V, ParamType)); 9818 } 9819 Values.push_back(Ldm); 9820 Value *Result = Builder.CreateCall(Intrinsic, Values); 9821 return Result; 9822 } 9823 9824 // BI__hmma_m16n16k16_mma_<Dtype><CType>(d, a, b, c, layout, satf) 9825 // --> Intrinsic::nvvm_wmma_mma_sync<layout A,B><DType><CType><Satf> 9826 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9827 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9828 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9829 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: { 9830 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9831 Address SrcA = EmitPointerWithAlignment(E->getArg(1)); 9832 Address SrcB = EmitPointerWithAlignment(E->getArg(2)); 9833 Address SrcC = EmitPointerWithAlignment(E->getArg(3)); 9834 llvm::APSInt LayoutArg; 9835 if (!E->getArg(4)->isIntegerConstantExpr(LayoutArg, getContext())) 9836 return nullptr; 9837 int Layout = LayoutArg.getSExtValue(); 9838 if (Layout < 0 || Layout > 3) 9839 return nullptr; 9840 llvm::APSInt SatfArg; 9841 if (!E->getArg(5)->isIntegerConstantExpr(SatfArg, getContext())) 9842 return nullptr; 9843 bool Satf = SatfArg.getSExtValue(); 9844 9845 // clang-format off 9846 #define MMA_VARIANTS(type) {{ \ 9847 Intrinsic::nvvm_wmma_mma_sync_row_row_##type, \ 9848 Intrinsic::nvvm_wmma_mma_sync_row_row_##type##_satfinite, \ 9849 Intrinsic::nvvm_wmma_mma_sync_row_col_##type, \ 9850 Intrinsic::nvvm_wmma_mma_sync_row_col_##type##_satfinite, \ 9851 Intrinsic::nvvm_wmma_mma_sync_col_row_##type, \ 9852 Intrinsic::nvvm_wmma_mma_sync_col_row_##type##_satfinite, \ 9853 Intrinsic::nvvm_wmma_mma_sync_col_col_##type, \ 9854 Intrinsic::nvvm_wmma_mma_sync_col_col_##type##_satfinite \ 9855 }} 9856 // clang-format on 9857 9858 auto getMMAIntrinsic = [Layout, Satf](std::array<unsigned, 8> Variants) { 9859 unsigned Index = Layout * 2 + Satf; 9860 assert(Index < 8); 9861 return Variants[Index]; 9862 }; 9863 unsigned IID; 9864 unsigned NumEltsC; 9865 unsigned NumEltsD; 9866 switch (BuiltinID) { 9867 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9868 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f16)); 9869 NumEltsC = 4; 9870 NumEltsD = 4; 9871 break; 9872 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9873 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f16)); 9874 NumEltsC = 4; 9875 NumEltsD = 8; 9876 break; 9877 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: 9878 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f32)); 9879 NumEltsC = 8; 9880 NumEltsD = 4; 9881 break; 9882 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9883 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f32)); 9884 NumEltsC = 8; 9885 NumEltsD = 8; 9886 break; 9887 default: 9888 llvm_unreachable("Unexpected builtin ID."); 9889 } 9890 #undef MMA_VARIANTS 9891 9892 SmallVector<Value *, 24> Values; 9893 Function *Intrinsic = CGM.getIntrinsic(IID); 9894 llvm::Type *ABType = Intrinsic->getFunctionType()->getParamType(0); 9895 // Load A 9896 for (unsigned i = 0; i < 8; ++i) { 9897 Value *V = Builder.CreateAlignedLoad( 9898 Builder.CreateGEP(SrcA.getPointer(), 9899 llvm::ConstantInt::get(IntTy, i)), 9900 CharUnits::fromQuantity(4)); 9901 Values.push_back(Builder.CreateBitCast(V, ABType)); 9902 } 9903 // Load B 9904 for (unsigned i = 0; i < 8; ++i) { 9905 Value *V = Builder.CreateAlignedLoad( 9906 Builder.CreateGEP(SrcB.getPointer(), 9907 llvm::ConstantInt::get(IntTy, i)), 9908 CharUnits::fromQuantity(4)); 9909 Values.push_back(Builder.CreateBitCast(V, ABType)); 9910 } 9911 // Load C 9912 llvm::Type *CType = Intrinsic->getFunctionType()->getParamType(16); 9913 for (unsigned i = 0; i < NumEltsC; ++i) { 9914 Value *V = Builder.CreateAlignedLoad( 9915 Builder.CreateGEP(SrcC.getPointer(), 9916 llvm::ConstantInt::get(IntTy, i)), 9917 CharUnits::fromQuantity(4)); 9918 Values.push_back(Builder.CreateBitCast(V, CType)); 9919 } 9920 Value *Result = Builder.CreateCall(Intrinsic, Values); 9921 llvm::Type *DType = Dst.getElementType(); 9922 for (unsigned i = 0; i < NumEltsD; ++i) 9923 Builder.CreateAlignedStore( 9924 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType), 9925 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9926 CharUnits::fromQuantity(4)); 9927 return Result; 9928 } 9929 default: 9930 return nullptr; 9931 } 9932 } 9933 9934 Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 9935 const CallExpr *E) { 9936 switch (BuiltinID) { 9937 case WebAssembly::BI__builtin_wasm_current_memory: { 9938 llvm::Type *ResultType = ConvertType(E->getType()); 9939 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType); 9940 return Builder.CreateCall(Callee); 9941 } 9942 case WebAssembly::BI__builtin_wasm_grow_memory: { 9943 Value *X = EmitScalarExpr(E->getArg(0)); 9944 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType()); 9945 return Builder.CreateCall(Callee, X); 9946 } 9947 case WebAssembly::BI__builtin_wasm_throw: { 9948 Value *Tag = EmitScalarExpr(E->getArg(0)); 9949 Value *Obj = EmitScalarExpr(E->getArg(1)); 9950 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw); 9951 return Builder.CreateCall(Callee, {Tag, Obj}); 9952 } 9953 case WebAssembly::BI__builtin_wasm_rethrow: { 9954 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow); 9955 return Builder.CreateCall(Callee); 9956 } 9957 9958 default: 9959 return nullptr; 9960 } 9961 } 9962