1 //===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This contains code to emit Builtin calls as LLVM code. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CGCXXABI.h" 15 #include "CGObjCRuntime.h" 16 #include "CGOpenCLRuntime.h" 17 #include "CodeGenFunction.h" 18 #include "CodeGenModule.h" 19 #include "ConstantEmitter.h" 20 #include "TargetInfo.h" 21 #include "clang/AST/ASTContext.h" 22 #include "clang/AST/Decl.h" 23 #include "clang/Analysis/Analyses/OSLog.h" 24 #include "clang/Basic/TargetBuiltins.h" 25 #include "clang/Basic/TargetInfo.h" 26 #include "clang/CodeGen/CGFunctionInfo.h" 27 #include "llvm/ADT/StringExtras.h" 28 #include "llvm/IR/CallSite.h" 29 #include "llvm/IR/DataLayout.h" 30 #include "llvm/IR/InlineAsm.h" 31 #include "llvm/IR/Intrinsics.h" 32 #include "llvm/IR/MDBuilder.h" 33 #include "llvm/Support/ScopedPrinter.h" 34 #include "llvm/Support/ConvertUTF.h" 35 #include <sstream> 36 37 using namespace clang; 38 using namespace CodeGen; 39 using namespace llvm; 40 41 static 42 int64_t clamp(int64_t Value, int64_t Low, int64_t High) { 43 return std::min(High, std::max(Low, Value)); 44 } 45 46 /// getBuiltinLibFunction - Given a builtin id for a function like 47 /// "__builtin_fabsf", return a Function* for "fabsf". 48 llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, 49 unsigned BuiltinID) { 50 assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); 51 52 // Get the name, skip over the __builtin_ prefix (if necessary). 53 StringRef Name; 54 GlobalDecl D(FD); 55 56 // If the builtin has been declared explicitly with an assembler label, 57 // use the mangled name. This differs from the plain label on platforms 58 // that prefix labels. 59 if (FD->hasAttr<AsmLabelAttr>()) 60 Name = getMangledName(D); 61 else 62 Name = Context.BuiltinInfo.getName(BuiltinID) + 10; 63 64 llvm::FunctionType *Ty = 65 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); 66 67 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); 68 } 69 70 /// Emit the conversions required to turn the given value into an 71 /// integer of the given size. 72 static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V, 73 QualType T, llvm::IntegerType *IntType) { 74 V = CGF.EmitToMemory(V, T); 75 76 if (V->getType()->isPointerTy()) 77 return CGF.Builder.CreatePtrToInt(V, IntType); 78 79 assert(V->getType() == IntType); 80 return V; 81 } 82 83 static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V, 84 QualType T, llvm::Type *ResultType) { 85 V = CGF.EmitFromMemory(V, T); 86 87 if (ResultType->isPointerTy()) 88 return CGF.Builder.CreateIntToPtr(V, ResultType); 89 90 assert(V->getType() == ResultType); 91 return V; 92 } 93 94 /// Utility to insert an atomic instruction based on Instrinsic::ID 95 /// and the expression node. 96 static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF, 97 llvm::AtomicRMWInst::BinOp Kind, 98 const CallExpr *E) { 99 QualType T = E->getType(); 100 assert(E->getArg(0)->getType()->isPointerType()); 101 assert(CGF.getContext().hasSameUnqualifiedType(T, 102 E->getArg(0)->getType()->getPointeeType())); 103 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 104 105 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 106 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 107 108 llvm::IntegerType *IntType = 109 llvm::IntegerType::get(CGF.getLLVMContext(), 110 CGF.getContext().getTypeSize(T)); 111 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 112 113 llvm::Value *Args[2]; 114 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 115 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 116 llvm::Type *ValueType = Args[1]->getType(); 117 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 118 119 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 120 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 121 return EmitFromInt(CGF, Result, T, ValueType); 122 } 123 124 static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) { 125 Value *Val = CGF.EmitScalarExpr(E->getArg(0)); 126 Value *Address = CGF.EmitScalarExpr(E->getArg(1)); 127 128 // Convert the type of the pointer to a pointer to the stored type. 129 Val = CGF.EmitToMemory(Val, E->getArg(0)->getType()); 130 Value *BC = CGF.Builder.CreateBitCast( 131 Address, llvm::PointerType::getUnqual(Val->getType()), "cast"); 132 LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType()); 133 LV.setNontemporal(true); 134 CGF.EmitStoreOfScalar(Val, LV, false); 135 return nullptr; 136 } 137 138 static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) { 139 Value *Address = CGF.EmitScalarExpr(E->getArg(0)); 140 141 LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType()); 142 LV.setNontemporal(true); 143 return CGF.EmitLoadOfScalar(LV, E->getExprLoc()); 144 } 145 146 static RValue EmitBinaryAtomic(CodeGenFunction &CGF, 147 llvm::AtomicRMWInst::BinOp Kind, 148 const CallExpr *E) { 149 return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E)); 150 } 151 152 /// Utility to insert an atomic instruction based Instrinsic::ID and 153 /// the expression node, where the return value is the result of the 154 /// operation. 155 static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF, 156 llvm::AtomicRMWInst::BinOp Kind, 157 const CallExpr *E, 158 Instruction::BinaryOps Op, 159 bool Invert = false) { 160 QualType T = E->getType(); 161 assert(E->getArg(0)->getType()->isPointerType()); 162 assert(CGF.getContext().hasSameUnqualifiedType(T, 163 E->getArg(0)->getType()->getPointeeType())); 164 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType())); 165 166 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 167 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 168 169 llvm::IntegerType *IntType = 170 llvm::IntegerType::get(CGF.getLLVMContext(), 171 CGF.getContext().getTypeSize(T)); 172 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 173 174 llvm::Value *Args[2]; 175 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 176 llvm::Type *ValueType = Args[1]->getType(); 177 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 178 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 179 180 llvm::Value *Result = CGF.Builder.CreateAtomicRMW( 181 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent); 182 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]); 183 if (Invert) 184 Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result, 185 llvm::ConstantInt::get(IntType, -1)); 186 Result = EmitFromInt(CGF, Result, T, ValueType); 187 return RValue::get(Result); 188 } 189 190 /// @brief Utility to insert an atomic cmpxchg instruction. 191 /// 192 /// @param CGF The current codegen function. 193 /// @param E Builtin call expression to convert to cmpxchg. 194 /// arg0 - address to operate on 195 /// arg1 - value to compare with 196 /// arg2 - new value 197 /// @param ReturnBool Specifies whether to return success flag of 198 /// cmpxchg result or the old value. 199 /// 200 /// @returns result of cmpxchg, according to ReturnBool 201 static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E, 202 bool ReturnBool) { 203 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType(); 204 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0)); 205 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace(); 206 207 llvm::IntegerType *IntType = llvm::IntegerType::get( 208 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T)); 209 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace); 210 211 Value *Args[3]; 212 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType); 213 Args[1] = CGF.EmitScalarExpr(E->getArg(1)); 214 llvm::Type *ValueType = Args[1]->getType(); 215 Args[1] = EmitToInt(CGF, Args[1], T, IntType); 216 Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType); 217 218 Value *Pair = CGF.Builder.CreateAtomicCmpXchg( 219 Args[0], Args[1], Args[2], llvm::AtomicOrdering::SequentiallyConsistent, 220 llvm::AtomicOrdering::SequentiallyConsistent); 221 if (ReturnBool) 222 // Extract boolean success flag and zext it to int. 223 return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1), 224 CGF.ConvertType(E->getType())); 225 else 226 // Extract old value and emit it using the same type as compare value. 227 return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T, 228 ValueType); 229 } 230 231 // Emit a simple mangled intrinsic that has 1 argument and a return type 232 // matching the argument type. 233 static Value *emitUnaryBuiltin(CodeGenFunction &CGF, 234 const CallExpr *E, 235 unsigned IntrinsicID) { 236 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 237 238 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 239 return CGF.Builder.CreateCall(F, Src0); 240 } 241 242 // Emit an intrinsic that has 2 operands of the same type as its result. 243 static Value *emitBinaryBuiltin(CodeGenFunction &CGF, 244 const CallExpr *E, 245 unsigned IntrinsicID) { 246 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 247 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 248 249 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 250 return CGF.Builder.CreateCall(F, { Src0, Src1 }); 251 } 252 253 // Emit an intrinsic that has 3 operands of the same type as its result. 254 static Value *emitTernaryBuiltin(CodeGenFunction &CGF, 255 const CallExpr *E, 256 unsigned IntrinsicID) { 257 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 258 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 259 llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2)); 260 261 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 262 return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 }); 263 } 264 265 // Emit an intrinsic that has 1 float or double operand, and 1 integer. 266 static Value *emitFPIntBuiltin(CodeGenFunction &CGF, 267 const CallExpr *E, 268 unsigned IntrinsicID) { 269 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0)); 270 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1)); 271 272 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType()); 273 return CGF.Builder.CreateCall(F, {Src0, Src1}); 274 } 275 276 /// EmitFAbs - Emit a call to @llvm.fabs(). 277 static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) { 278 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType()); 279 llvm::CallInst *Call = CGF.Builder.CreateCall(F, V); 280 Call->setDoesNotAccessMemory(); 281 return Call; 282 } 283 284 /// Emit the computation of the sign bit for a floating point value. Returns 285 /// the i1 sign bit value. 286 static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) { 287 LLVMContext &C = CGF.CGM.getLLVMContext(); 288 289 llvm::Type *Ty = V->getType(); 290 int Width = Ty->getPrimitiveSizeInBits(); 291 llvm::Type *IntTy = llvm::IntegerType::get(C, Width); 292 V = CGF.Builder.CreateBitCast(V, IntTy); 293 if (Ty->isPPC_FP128Ty()) { 294 // We want the sign bit of the higher-order double. The bitcast we just 295 // did works as if the double-double was stored to memory and then 296 // read as an i128. The "store" will put the higher-order double in the 297 // lower address in both little- and big-Endian modes, but the "load" 298 // will treat those bits as a different part of the i128: the low bits in 299 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian 300 // we need to shift the high bits down to the low before truncating. 301 Width >>= 1; 302 if (CGF.getTarget().isBigEndian()) { 303 Value *ShiftCst = llvm::ConstantInt::get(IntTy, Width); 304 V = CGF.Builder.CreateLShr(V, ShiftCst); 305 } 306 // We are truncating value in order to extract the higher-order 307 // double, which we will be using to extract the sign from. 308 IntTy = llvm::IntegerType::get(C, Width); 309 V = CGF.Builder.CreateTrunc(V, IntTy); 310 } 311 Value *Zero = llvm::Constant::getNullValue(IntTy); 312 return CGF.Builder.CreateICmpSLT(V, Zero); 313 } 314 315 static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD, 316 const CallExpr *E, llvm::Constant *calleeValue) { 317 CGCallee callee = CGCallee::forDirect(calleeValue, FD); 318 return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot()); 319 } 320 321 /// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.* 322 /// depending on IntrinsicID. 323 /// 324 /// \arg CGF The current codegen function. 325 /// \arg IntrinsicID The ID for the Intrinsic we wish to generate. 326 /// \arg X The first argument to the llvm.*.with.overflow.*. 327 /// \arg Y The second argument to the llvm.*.with.overflow.*. 328 /// \arg Carry The carry returned by the llvm.*.with.overflow.*. 329 /// \returns The result (i.e. sum/product) returned by the intrinsic. 330 static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF, 331 const llvm::Intrinsic::ID IntrinsicID, 332 llvm::Value *X, llvm::Value *Y, 333 llvm::Value *&Carry) { 334 // Make sure we have integers of the same width. 335 assert(X->getType() == Y->getType() && 336 "Arguments must be the same type. (Did you forget to make sure both " 337 "arguments have the same integer width?)"); 338 339 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType()); 340 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y}); 341 Carry = CGF.Builder.CreateExtractValue(Tmp, 1); 342 return CGF.Builder.CreateExtractValue(Tmp, 0); 343 } 344 345 static Value *emitRangedBuiltin(CodeGenFunction &CGF, 346 unsigned IntrinsicID, 347 int low, int high) { 348 llvm::MDBuilder MDHelper(CGF.getLLVMContext()); 349 llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high)); 350 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {}); 351 llvm::Instruction *Call = CGF.Builder.CreateCall(F); 352 Call->setMetadata(llvm::LLVMContext::MD_range, RNode); 353 return Call; 354 } 355 356 namespace { 357 struct WidthAndSignedness { 358 unsigned Width; 359 bool Signed; 360 }; 361 } 362 363 static WidthAndSignedness 364 getIntegerWidthAndSignedness(const clang::ASTContext &context, 365 const clang::QualType Type) { 366 assert(Type->isIntegerType() && "Given type is not an integer."); 367 unsigned Width = Type->isBooleanType() ? 1 : context.getTypeInfo(Type).Width; 368 bool Signed = Type->isSignedIntegerType(); 369 return {Width, Signed}; 370 } 371 372 // Given one or more integer types, this function produces an integer type that 373 // encompasses them: any value in one of the given types could be expressed in 374 // the encompassing type. 375 static struct WidthAndSignedness 376 EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) { 377 assert(Types.size() > 0 && "Empty list of types."); 378 379 // If any of the given types is signed, we must return a signed type. 380 bool Signed = false; 381 for (const auto &Type : Types) { 382 Signed |= Type.Signed; 383 } 384 385 // The encompassing type must have a width greater than or equal to the width 386 // of the specified types. Aditionally, if the encompassing type is signed, 387 // its width must be strictly greater than the width of any unsigned types 388 // given. 389 unsigned Width = 0; 390 for (const auto &Type : Types) { 391 unsigned MinWidth = Type.Width + (Signed && !Type.Signed); 392 if (Width < MinWidth) { 393 Width = MinWidth; 394 } 395 } 396 397 return {Width, Signed}; 398 } 399 400 Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) { 401 llvm::Type *DestType = Int8PtrTy; 402 if (ArgValue->getType() != DestType) 403 ArgValue = 404 Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data()); 405 406 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend; 407 return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue); 408 } 409 410 /// Checks if using the result of __builtin_object_size(p, @p From) in place of 411 /// __builtin_object_size(p, @p To) is correct 412 static bool areBOSTypesCompatible(int From, int To) { 413 // Note: Our __builtin_object_size implementation currently treats Type=0 and 414 // Type=2 identically. Encoding this implementation detail here may make 415 // improving __builtin_object_size difficult in the future, so it's omitted. 416 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2); 417 } 418 419 static llvm::Value * 420 getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) { 421 return ConstantInt::get(ResType, (Type & 2) ? 0 : -1, /*isSigned=*/true); 422 } 423 424 llvm::Value * 425 CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type, 426 llvm::IntegerType *ResType, 427 llvm::Value *EmittedE) { 428 uint64_t ObjectSize; 429 if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type)) 430 return emitBuiltinObjectSize(E, Type, ResType, EmittedE); 431 return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true); 432 } 433 434 /// Returns a Value corresponding to the size of the given expression. 435 /// This Value may be either of the following: 436 /// - A llvm::Argument (if E is a param with the pass_object_size attribute on 437 /// it) 438 /// - A call to the @llvm.objectsize intrinsic 439 /// 440 /// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null 441 /// and we wouldn't otherwise try to reference a pass_object_size parameter, 442 /// we'll call @llvm.objectsize on EmittedE, rather than emitting E. 443 llvm::Value * 444 CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type, 445 llvm::IntegerType *ResType, 446 llvm::Value *EmittedE) { 447 // We need to reference an argument if the pointer is a parameter with the 448 // pass_object_size attribute. 449 if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) { 450 auto *Param = dyn_cast<ParmVarDecl>(D->getDecl()); 451 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>(); 452 if (Param != nullptr && PS != nullptr && 453 areBOSTypesCompatible(PS->getType(), Type)) { 454 auto Iter = SizeArguments.find(Param); 455 assert(Iter != SizeArguments.end()); 456 457 const ImplicitParamDecl *D = Iter->second; 458 auto DIter = LocalDeclMap.find(D); 459 assert(DIter != LocalDeclMap.end()); 460 461 return EmitLoadOfScalar(DIter->second, /*volatile=*/false, 462 getContext().getSizeType(), E->getLocStart()); 463 } 464 } 465 466 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't 467 // evaluate E for side-effects. In either case, we shouldn't lower to 468 // @llvm.objectsize. 469 if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext()))) 470 return getDefaultBuiltinObjectSizeResult(Type, ResType); 471 472 Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E); 473 assert(Ptr->getType()->isPointerTy() && 474 "Non-pointer passed to __builtin_object_size?"); 475 476 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()}); 477 478 // LLVM only supports 0 and 2, make sure that we pass along that as a boolean. 479 Value *Min = Builder.getInt1((Type & 2) != 0); 480 // For GCC compatability, __builtin_object_size treat NULL as unknown size. 481 Value *NullIsUnknown = Builder.getTrue(); 482 return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown}); 483 } 484 485 // Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we 486 // handle them here. 487 enum class CodeGenFunction::MSVCIntrin { 488 _BitScanForward, 489 _BitScanReverse, 490 _InterlockedAnd, 491 _InterlockedDecrement, 492 _InterlockedExchange, 493 _InterlockedExchangeAdd, 494 _InterlockedExchangeSub, 495 _InterlockedIncrement, 496 _InterlockedOr, 497 _InterlockedXor, 498 _interlockedbittestandset, 499 __fastfail, 500 }; 501 502 Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, 503 const CallExpr *E) { 504 switch (BuiltinID) { 505 case MSVCIntrin::_BitScanForward: 506 case MSVCIntrin::_BitScanReverse: { 507 Value *ArgValue = EmitScalarExpr(E->getArg(1)); 508 509 llvm::Type *ArgType = ArgValue->getType(); 510 llvm::Type *IndexType = 511 EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType(); 512 llvm::Type *ResultType = ConvertType(E->getType()); 513 514 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 515 Value *ResZero = llvm::Constant::getNullValue(ResultType); 516 Value *ResOne = llvm::ConstantInt::get(ResultType, 1); 517 518 BasicBlock *Begin = Builder.GetInsertBlock(); 519 BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn); 520 Builder.SetInsertPoint(End); 521 PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result"); 522 523 Builder.SetInsertPoint(Begin); 524 Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero); 525 BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn); 526 Builder.CreateCondBr(IsZero, End, NotZero); 527 Result->addIncoming(ResZero, Begin); 528 529 Builder.SetInsertPoint(NotZero); 530 Address IndexAddress = EmitPointerWithAlignment(E->getArg(0)); 531 532 if (BuiltinID == MSVCIntrin::_BitScanForward) { 533 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 534 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 535 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 536 Builder.CreateStore(ZeroCount, IndexAddress, false); 537 } else { 538 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 539 Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1); 540 541 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 542 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()}); 543 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false); 544 Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount); 545 Builder.CreateStore(Index, IndexAddress, false); 546 } 547 Builder.CreateBr(End); 548 Result->addIncoming(ResOne, NotZero); 549 550 Builder.SetInsertPoint(End); 551 return Result; 552 } 553 case MSVCIntrin::_InterlockedAnd: 554 return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E); 555 case MSVCIntrin::_InterlockedExchange: 556 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E); 557 case MSVCIntrin::_InterlockedExchangeAdd: 558 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E); 559 case MSVCIntrin::_InterlockedExchangeSub: 560 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Sub, E); 561 case MSVCIntrin::_InterlockedOr: 562 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E); 563 case MSVCIntrin::_InterlockedXor: 564 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E); 565 566 case MSVCIntrin::_interlockedbittestandset: { 567 llvm::Value *Addr = EmitScalarExpr(E->getArg(0)); 568 llvm::Value *Bit = EmitScalarExpr(E->getArg(1)); 569 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 570 AtomicRMWInst::Or, Addr, 571 Builder.CreateShl(ConstantInt::get(Bit->getType(), 1), Bit), 572 llvm::AtomicOrdering::SequentiallyConsistent); 573 // Shift the relevant bit to the least significant position, truncate to 574 // the result type, and test the low bit. 575 llvm::Value *Shifted = Builder.CreateLShr(RMWI, Bit); 576 llvm::Value *Truncated = 577 Builder.CreateTrunc(Shifted, ConvertType(E->getType())); 578 return Builder.CreateAnd(Truncated, 579 ConstantInt::get(Truncated->getType(), 1)); 580 } 581 582 case MSVCIntrin::_InterlockedDecrement: { 583 llvm::Type *IntTy = ConvertType(E->getType()); 584 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 585 AtomicRMWInst::Sub, 586 EmitScalarExpr(E->getArg(0)), 587 ConstantInt::get(IntTy, 1), 588 llvm::AtomicOrdering::SequentiallyConsistent); 589 return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1)); 590 } 591 case MSVCIntrin::_InterlockedIncrement: { 592 llvm::Type *IntTy = ConvertType(E->getType()); 593 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW( 594 AtomicRMWInst::Add, 595 EmitScalarExpr(E->getArg(0)), 596 ConstantInt::get(IntTy, 1), 597 llvm::AtomicOrdering::SequentiallyConsistent); 598 return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1)); 599 } 600 601 case MSVCIntrin::__fastfail: { 602 // Request immediate process termination from the kernel. The instruction 603 // sequences to do this are documented on MSDN: 604 // https://msdn.microsoft.com/en-us/library/dn774154.aspx 605 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch(); 606 StringRef Asm, Constraints; 607 switch (ISA) { 608 default: 609 ErrorUnsupported(E, "__fastfail call for this architecture"); 610 break; 611 case llvm::Triple::x86: 612 case llvm::Triple::x86_64: 613 Asm = "int $$0x29"; 614 Constraints = "{cx}"; 615 break; 616 case llvm::Triple::thumb: 617 Asm = "udf #251"; 618 Constraints = "{r0}"; 619 break; 620 } 621 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false); 622 llvm::InlineAsm *IA = 623 llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true); 624 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get( 625 getLLVMContext(), llvm::AttributeList::FunctionIndex, 626 llvm::Attribute::NoReturn); 627 CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0))); 628 CS.setAttributes(NoReturnAttr); 629 return CS.getInstruction(); 630 } 631 } 632 llvm_unreachable("Incorrect MSVC intrinsic!"); 633 } 634 635 namespace { 636 // ARC cleanup for __builtin_os_log_format 637 struct CallObjCArcUse final : EHScopeStack::Cleanup { 638 CallObjCArcUse(llvm::Value *object) : object(object) {} 639 llvm::Value *object; 640 641 void Emit(CodeGenFunction &CGF, Flags flags) override { 642 CGF.EmitARCIntrinsicUse(object); 643 } 644 }; 645 } 646 647 Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E, 648 BuiltinCheckKind Kind) { 649 assert((Kind == BCK_CLZPassedZero || Kind == BCK_CTZPassedZero) 650 && "Unsupported builtin check kind"); 651 652 Value *ArgValue = EmitScalarExpr(E); 653 if (!SanOpts.has(SanitizerKind::Builtin) || !getTarget().isCLZForZeroUndef()) 654 return ArgValue; 655 656 SanitizerScope SanScope(this); 657 Value *Cond = Builder.CreateICmpNE( 658 ArgValue, llvm::Constant::getNullValue(ArgValue->getType())); 659 EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin), 660 SanitizerHandler::InvalidBuiltin, 661 {EmitCheckSourceLocation(E->getExprLoc()), 662 llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)}, 663 None); 664 return ArgValue; 665 } 666 667 /// Get the argument type for arguments to os_log_helper. 668 static CanQualType getOSLogArgType(ASTContext &C, int Size) { 669 QualType UnsignedTy = C.getIntTypeForBitwidth(Size * 8, /*Signed=*/false); 670 return C.getCanonicalType(UnsignedTy); 671 } 672 673 llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction( 674 const analyze_os_log::OSLogBufferLayout &Layout, 675 CharUnits BufferAlignment) { 676 ASTContext &Ctx = getContext(); 677 678 llvm::SmallString<64> Name; 679 { 680 raw_svector_ostream OS(Name); 681 OS << "__os_log_helper"; 682 OS << "_" << BufferAlignment.getQuantity(); 683 OS << "_" << int(Layout.getSummaryByte()); 684 OS << "_" << int(Layout.getNumArgsByte()); 685 for (const auto &Item : Layout.Items) 686 OS << "_" << int(Item.getSizeByte()) << "_" 687 << int(Item.getDescriptorByte()); 688 } 689 690 if (llvm::Function *F = CGM.getModule().getFunction(Name)) 691 return F; 692 693 llvm::SmallVector<ImplicitParamDecl, 4> Params; 694 Params.emplace_back(Ctx, nullptr, SourceLocation(), &Ctx.Idents.get("buffer"), 695 Ctx.VoidPtrTy, ImplicitParamDecl::Other); 696 697 for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) { 698 char Size = Layout.Items[I].getSizeByte(); 699 if (!Size) 700 continue; 701 702 Params.emplace_back( 703 Ctx, nullptr, SourceLocation(), 704 &Ctx.Idents.get(std::string("arg") + llvm::to_string(I)), 705 getOSLogArgType(Ctx, Size), ImplicitParamDecl::Other); 706 } 707 708 FunctionArgList Args; 709 for (auto &P : Params) 710 Args.push_back(&P); 711 712 // The helper function has linkonce_odr linkage to enable the linker to merge 713 // identical functions. To ensure the merging always happens, 'noinline' is 714 // attached to the function when compiling with -Oz. 715 const CGFunctionInfo &FI = 716 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args); 717 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI); 718 llvm::Function *Fn = llvm::Function::Create( 719 FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule()); 720 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility); 721 CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn); 722 CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn); 723 724 // Attach 'noinline' at -Oz. 725 if (CGM.getCodeGenOpts().OptimizeSize == 2) 726 Fn->addFnAttr(llvm::Attribute::NoInline); 727 728 auto NL = ApplyDebugLocation::CreateEmpty(*this); 729 IdentifierInfo *II = &Ctx.Idents.get(Name); 730 FunctionDecl *FD = FunctionDecl::Create( 731 Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II, 732 Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false); 733 734 StartFunction(FD, Ctx.VoidTy, Fn, FI, Args); 735 736 // Create a scope with an artificial location for the body of this function. 737 auto AL = ApplyDebugLocation::CreateArtificial(*this); 738 739 CharUnits Offset; 740 Address BufAddr(Builder.CreateLoad(GetAddrOfLocalVar(&Params[0]), "buf"), 741 BufferAlignment); 742 Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()), 743 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary")); 744 Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()), 745 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs")); 746 747 unsigned I = 1; 748 for (const auto &Item : Layout.Items) { 749 Builder.CreateStore( 750 Builder.getInt8(Item.getDescriptorByte()), 751 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor")); 752 Builder.CreateStore( 753 Builder.getInt8(Item.getSizeByte()), 754 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize")); 755 756 CharUnits Size = Item.size(); 757 if (!Size.getQuantity()) 758 continue; 759 760 Address Arg = GetAddrOfLocalVar(&Params[I]); 761 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset, "argData"); 762 Addr = Builder.CreateBitCast(Addr, Arg.getPointer()->getType(), 763 "argDataCast"); 764 Builder.CreateStore(Builder.CreateLoad(Arg), Addr); 765 Offset += Size; 766 ++I; 767 } 768 769 FinishFunction(); 770 771 return Fn; 772 } 773 774 RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) { 775 assert(E.getNumArgs() >= 2 && 776 "__builtin_os_log_format takes at least 2 arguments"); 777 ASTContext &Ctx = getContext(); 778 analyze_os_log::OSLogBufferLayout Layout; 779 analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout); 780 Address BufAddr = EmitPointerWithAlignment(E.getArg(0)); 781 llvm::SmallVector<llvm::Value *, 4> RetainableOperands; 782 783 // Ignore argument 1, the format string. It is not currently used. 784 CallArgList Args; 785 Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy); 786 787 for (const auto &Item : Layout.Items) { 788 int Size = Item.getSizeByte(); 789 if (!Size) 790 continue; 791 792 llvm::Value *ArgVal; 793 794 if (const Expr *TheExpr = Item.getExpr()) { 795 ArgVal = EmitScalarExpr(TheExpr, /*Ignore*/ false); 796 797 // Check if this is a retainable type. 798 if (TheExpr->getType()->isObjCRetainableType()) { 799 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar && 800 "Only scalar can be a ObjC retainable type"); 801 // Check if the object is constant, if not, save it in 802 // RetainableOperands. 803 if (!isa<Constant>(ArgVal)) 804 RetainableOperands.push_back(ArgVal); 805 } 806 } else { 807 ArgVal = Builder.getInt32(Item.getConstValue().getQuantity()); 808 } 809 810 unsigned ArgValSize = 811 CGM.getDataLayout().getTypeSizeInBits(ArgVal->getType()); 812 llvm::IntegerType *IntTy = llvm::Type::getIntNTy(getLLVMContext(), 813 ArgValSize); 814 ArgVal = Builder.CreateBitOrPointerCast(ArgVal, IntTy); 815 CanQualType ArgTy = getOSLogArgType(Ctx, Size); 816 // If ArgVal has type x86_fp80, zero-extend ArgVal. 817 ArgVal = Builder.CreateZExtOrBitCast(ArgVal, ConvertType(ArgTy)); 818 Args.add(RValue::get(ArgVal), ArgTy); 819 } 820 821 const CGFunctionInfo &FI = 822 CGM.getTypes().arrangeBuiltinFunctionCall(Ctx.VoidTy, Args); 823 llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction( 824 Layout, BufAddr.getAlignment()); 825 EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args); 826 827 // Push a clang.arc.use cleanup for each object in RetainableOperands. The 828 // cleanup will cause the use to appear after the final log call, keeping 829 // the object valid while it’s held in the log buffer. Note that if there’s 830 // a release cleanup on the object, it will already be active; since 831 // cleanups are emitted in reverse order, the use will occur before the 832 // object is released. 833 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount && 834 CGM.getCodeGenOpts().OptimizationLevel != 0) 835 for (llvm::Value *Object : RetainableOperands) 836 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), Object); 837 838 return RValue::get(BufAddr.getPointer()); 839 } 840 841 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, 842 unsigned BuiltinID, const CallExpr *E, 843 ReturnValueSlot ReturnValue) { 844 // See if we can constant fold this builtin. If so, don't emit it at all. 845 Expr::EvalResult Result; 846 if (E->EvaluateAsRValue(Result, CGM.getContext()) && 847 !Result.hasSideEffects()) { 848 if (Result.Val.isInt()) 849 return RValue::get(llvm::ConstantInt::get(getLLVMContext(), 850 Result.Val.getInt())); 851 if (Result.Val.isFloat()) 852 return RValue::get(llvm::ConstantFP::get(getLLVMContext(), 853 Result.Val.getFloat())); 854 } 855 856 switch (BuiltinID) { 857 default: break; // Handle intrinsics and libm functions below. 858 case Builtin::BI__builtin___CFStringMakeConstantString: 859 case Builtin::BI__builtin___NSStringMakeConstantString: 860 return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType())); 861 case Builtin::BI__builtin_stdarg_start: 862 case Builtin::BI__builtin_va_start: 863 case Builtin::BI__va_start: 864 case Builtin::BI__builtin_va_end: 865 return RValue::get( 866 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start 867 ? EmitScalarExpr(E->getArg(0)) 868 : EmitVAListRef(E->getArg(0)).getPointer(), 869 BuiltinID != Builtin::BI__builtin_va_end)); 870 case Builtin::BI__builtin_va_copy: { 871 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer(); 872 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer(); 873 874 llvm::Type *Type = Int8PtrTy; 875 876 DstPtr = Builder.CreateBitCast(DstPtr, Type); 877 SrcPtr = Builder.CreateBitCast(SrcPtr, Type); 878 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy), 879 {DstPtr, SrcPtr})); 880 } 881 case Builtin::BI__builtin_abs: 882 case Builtin::BI__builtin_labs: 883 case Builtin::BI__builtin_llabs: { 884 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 885 886 Value *NegOp = Builder.CreateNeg(ArgValue, "neg"); 887 Value *CmpResult = 888 Builder.CreateICmpSGE(ArgValue, 889 llvm::Constant::getNullValue(ArgValue->getType()), 890 "abscond"); 891 Value *Result = 892 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs"); 893 894 return RValue::get(Result); 895 } 896 case Builtin::BI__builtin_fabs: 897 case Builtin::BI__builtin_fabsf: 898 case Builtin::BI__builtin_fabsl: { 899 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs)); 900 } 901 case Builtin::BI__builtin_fmod: 902 case Builtin::BI__builtin_fmodf: 903 case Builtin::BI__builtin_fmodl: { 904 Value *Arg1 = EmitScalarExpr(E->getArg(0)); 905 Value *Arg2 = EmitScalarExpr(E->getArg(1)); 906 Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod"); 907 return RValue::get(Result); 908 } 909 case Builtin::BI__builtin_copysign: 910 case Builtin::BI__builtin_copysignf: 911 case Builtin::BI__builtin_copysignl: { 912 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign)); 913 } 914 case Builtin::BI__builtin_ceil: 915 case Builtin::BI__builtin_ceilf: 916 case Builtin::BI__builtin_ceill: { 917 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil)); 918 } 919 case Builtin::BI__builtin_floor: 920 case Builtin::BI__builtin_floorf: 921 case Builtin::BI__builtin_floorl: { 922 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor)); 923 } 924 case Builtin::BI__builtin_trunc: 925 case Builtin::BI__builtin_truncf: 926 case Builtin::BI__builtin_truncl: { 927 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc)); 928 } 929 case Builtin::BI__builtin_rint: 930 case Builtin::BI__builtin_rintf: 931 case Builtin::BI__builtin_rintl: { 932 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint)); 933 } 934 case Builtin::BI__builtin_nearbyint: 935 case Builtin::BI__builtin_nearbyintf: 936 case Builtin::BI__builtin_nearbyintl: { 937 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint)); 938 } 939 case Builtin::BI__builtin_round: 940 case Builtin::BI__builtin_roundf: 941 case Builtin::BI__builtin_roundl: { 942 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round)); 943 } 944 case Builtin::BI__builtin_fmin: 945 case Builtin::BI__builtin_fminf: 946 case Builtin::BI__builtin_fminl: { 947 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum)); 948 } 949 case Builtin::BI__builtin_fmax: 950 case Builtin::BI__builtin_fmaxf: 951 case Builtin::BI__builtin_fmaxl: { 952 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum)); 953 } 954 case Builtin::BI__builtin_conj: 955 case Builtin::BI__builtin_conjf: 956 case Builtin::BI__builtin_conjl: { 957 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 958 Value *Real = ComplexVal.first; 959 Value *Imag = ComplexVal.second; 960 Value *Zero = 961 Imag->getType()->isFPOrFPVectorTy() 962 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) 963 : llvm::Constant::getNullValue(Imag->getType()); 964 965 Imag = Builder.CreateFSub(Zero, Imag, "sub"); 966 return RValue::getComplex(std::make_pair(Real, Imag)); 967 } 968 case Builtin::BI__builtin_creal: 969 case Builtin::BI__builtin_crealf: 970 case Builtin::BI__builtin_creall: 971 case Builtin::BIcreal: 972 case Builtin::BIcrealf: 973 case Builtin::BIcreall: { 974 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 975 return RValue::get(ComplexVal.first); 976 } 977 978 case Builtin::BI__builtin_cimag: 979 case Builtin::BI__builtin_cimagf: 980 case Builtin::BI__builtin_cimagl: 981 case Builtin::BIcimag: 982 case Builtin::BIcimagf: 983 case Builtin::BIcimagl: { 984 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); 985 return RValue::get(ComplexVal.second); 986 } 987 988 case Builtin::BI__builtin_ctzs: 989 case Builtin::BI__builtin_ctz: 990 case Builtin::BI__builtin_ctzl: 991 case Builtin::BI__builtin_ctzll: { 992 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero); 993 994 llvm::Type *ArgType = ArgValue->getType(); 995 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 996 997 llvm::Type *ResultType = ConvertType(E->getType()); 998 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 999 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 1000 if (Result->getType() != ResultType) 1001 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1002 "cast"); 1003 return RValue::get(Result); 1004 } 1005 case Builtin::BI__builtin_clzs: 1006 case Builtin::BI__builtin_clz: 1007 case Builtin::BI__builtin_clzl: 1008 case Builtin::BI__builtin_clzll: { 1009 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero); 1010 1011 llvm::Type *ArgType = ArgValue->getType(); 1012 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType); 1013 1014 llvm::Type *ResultType = ConvertType(E->getType()); 1015 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef()); 1016 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef}); 1017 if (Result->getType() != ResultType) 1018 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1019 "cast"); 1020 return RValue::get(Result); 1021 } 1022 case Builtin::BI__builtin_ffs: 1023 case Builtin::BI__builtin_ffsl: 1024 case Builtin::BI__builtin_ffsll: { 1025 // ffs(x) -> x ? cttz(x) + 1 : 0 1026 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1027 1028 llvm::Type *ArgType = ArgValue->getType(); 1029 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType); 1030 1031 llvm::Type *ResultType = ConvertType(E->getType()); 1032 Value *Tmp = 1033 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}), 1034 llvm::ConstantInt::get(ArgType, 1)); 1035 Value *Zero = llvm::Constant::getNullValue(ArgType); 1036 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero"); 1037 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs"); 1038 if (Result->getType() != ResultType) 1039 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1040 "cast"); 1041 return RValue::get(Result); 1042 } 1043 case Builtin::BI__builtin_parity: 1044 case Builtin::BI__builtin_parityl: 1045 case Builtin::BI__builtin_parityll: { 1046 // parity(x) -> ctpop(x) & 1 1047 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1048 1049 llvm::Type *ArgType = ArgValue->getType(); 1050 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 1051 1052 llvm::Type *ResultType = ConvertType(E->getType()); 1053 Value *Tmp = Builder.CreateCall(F, ArgValue); 1054 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1)); 1055 if (Result->getType() != ResultType) 1056 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1057 "cast"); 1058 return RValue::get(Result); 1059 } 1060 case Builtin::BI__popcnt16: 1061 case Builtin::BI__popcnt: 1062 case Builtin::BI__popcnt64: 1063 case Builtin::BI__builtin_popcount: 1064 case Builtin::BI__builtin_popcountl: 1065 case Builtin::BI__builtin_popcountll: { 1066 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1067 1068 llvm::Type *ArgType = ArgValue->getType(); 1069 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType); 1070 1071 llvm::Type *ResultType = ConvertType(E->getType()); 1072 Value *Result = Builder.CreateCall(F, ArgValue); 1073 if (Result->getType() != ResultType) 1074 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true, 1075 "cast"); 1076 return RValue::get(Result); 1077 } 1078 case Builtin::BI_rotr8: 1079 case Builtin::BI_rotr16: 1080 case Builtin::BI_rotr: 1081 case Builtin::BI_lrotr: 1082 case Builtin::BI_rotr64: { 1083 Value *Val = EmitScalarExpr(E->getArg(0)); 1084 Value *Shift = EmitScalarExpr(E->getArg(1)); 1085 1086 llvm::Type *ArgType = Val->getType(); 1087 Shift = Builder.CreateIntCast(Shift, ArgType, false); 1088 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 1089 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 1090 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 1091 1092 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 1093 Shift = Builder.CreateAnd(Shift, Mask); 1094 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift); 1095 1096 Value *RightShifted = Builder.CreateLShr(Val, Shift); 1097 Value *LeftShifted = Builder.CreateShl(Val, LeftShift); 1098 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 1099 1100 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 1101 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 1102 return RValue::get(Result); 1103 } 1104 case Builtin::BI_rotl8: 1105 case Builtin::BI_rotl16: 1106 case Builtin::BI_rotl: 1107 case Builtin::BI_lrotl: 1108 case Builtin::BI_rotl64: { 1109 Value *Val = EmitScalarExpr(E->getArg(0)); 1110 Value *Shift = EmitScalarExpr(E->getArg(1)); 1111 1112 llvm::Type *ArgType = Val->getType(); 1113 Shift = Builder.CreateIntCast(Shift, ArgType, false); 1114 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth(); 1115 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth); 1116 Value *ArgZero = llvm::Constant::getNullValue(ArgType); 1117 1118 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1); 1119 Shift = Builder.CreateAnd(Shift, Mask); 1120 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift); 1121 1122 Value *LeftShifted = Builder.CreateShl(Val, Shift); 1123 Value *RightShifted = Builder.CreateLShr(Val, RightShift); 1124 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted); 1125 1126 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero); 1127 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated); 1128 return RValue::get(Result); 1129 } 1130 case Builtin::BI__builtin_unpredictable: { 1131 // Always return the argument of __builtin_unpredictable. LLVM does not 1132 // handle this builtin. Metadata for this builtin should be added directly 1133 // to instructions such as branches or switches that use it. 1134 return RValue::get(EmitScalarExpr(E->getArg(0))); 1135 } 1136 case Builtin::BI__builtin_expect: { 1137 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1138 llvm::Type *ArgType = ArgValue->getType(); 1139 1140 Value *ExpectedValue = EmitScalarExpr(E->getArg(1)); 1141 // Don't generate llvm.expect on -O0 as the backend won't use it for 1142 // anything. 1143 // Note, we still IRGen ExpectedValue because it could have side-effects. 1144 if (CGM.getCodeGenOpts().OptimizationLevel == 0) 1145 return RValue::get(ArgValue); 1146 1147 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType); 1148 Value *Result = 1149 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval"); 1150 return RValue::get(Result); 1151 } 1152 case Builtin::BI__builtin_assume_aligned: { 1153 Value *PtrValue = EmitScalarExpr(E->getArg(0)); 1154 Value *OffsetValue = 1155 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr; 1156 1157 Value *AlignmentValue = EmitScalarExpr(E->getArg(1)); 1158 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue); 1159 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue(); 1160 1161 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue); 1162 return RValue::get(PtrValue); 1163 } 1164 case Builtin::BI__assume: 1165 case Builtin::BI__builtin_assume: { 1166 if (E->getArg(0)->HasSideEffects(getContext())) 1167 return RValue::get(nullptr); 1168 1169 Value *ArgValue = EmitScalarExpr(E->getArg(0)); 1170 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume); 1171 return RValue::get(Builder.CreateCall(FnAssume, ArgValue)); 1172 } 1173 case Builtin::BI__builtin_bswap16: 1174 case Builtin::BI__builtin_bswap32: 1175 case Builtin::BI__builtin_bswap64: { 1176 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap)); 1177 } 1178 case Builtin::BI__builtin_bitreverse8: 1179 case Builtin::BI__builtin_bitreverse16: 1180 case Builtin::BI__builtin_bitreverse32: 1181 case Builtin::BI__builtin_bitreverse64: { 1182 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse)); 1183 } 1184 case Builtin::BI__builtin_object_size: { 1185 unsigned Type = 1186 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); 1187 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType())); 1188 1189 // We pass this builtin onto the optimizer so that it can figure out the 1190 // object size in more complex cases. 1191 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType, 1192 /*EmittedE=*/nullptr)); 1193 } 1194 case Builtin::BI__builtin_prefetch: { 1195 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0)); 1196 // FIXME: Technically these constants should of type 'int', yes? 1197 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) : 1198 llvm::ConstantInt::get(Int32Ty, 0); 1199 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : 1200 llvm::ConstantInt::get(Int32Ty, 3); 1201 Value *Data = llvm::ConstantInt::get(Int32Ty, 1); 1202 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 1203 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data})); 1204 } 1205 case Builtin::BI__builtin_readcyclecounter: { 1206 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter); 1207 return RValue::get(Builder.CreateCall(F)); 1208 } 1209 case Builtin::BI__builtin___clear_cache: { 1210 Value *Begin = EmitScalarExpr(E->getArg(0)); 1211 Value *End = EmitScalarExpr(E->getArg(1)); 1212 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache); 1213 return RValue::get(Builder.CreateCall(F, {Begin, End})); 1214 } 1215 case Builtin::BI__builtin_trap: 1216 return RValue::get(EmitTrapCall(Intrinsic::trap)); 1217 case Builtin::BI__debugbreak: 1218 return RValue::get(EmitTrapCall(Intrinsic::debugtrap)); 1219 case Builtin::BI__builtin_unreachable: { 1220 if (SanOpts.has(SanitizerKind::Unreachable)) { 1221 SanitizerScope SanScope(this); 1222 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()), 1223 SanitizerKind::Unreachable), 1224 SanitizerHandler::BuiltinUnreachable, 1225 EmitCheckSourceLocation(E->getExprLoc()), None); 1226 } else 1227 Builder.CreateUnreachable(); 1228 1229 // We do need to preserve an insertion point. 1230 EmitBlock(createBasicBlock("unreachable.cont")); 1231 1232 return RValue::get(nullptr); 1233 } 1234 1235 case Builtin::BI__builtin_powi: 1236 case Builtin::BI__builtin_powif: 1237 case Builtin::BI__builtin_powil: { 1238 Value *Base = EmitScalarExpr(E->getArg(0)); 1239 Value *Exponent = EmitScalarExpr(E->getArg(1)); 1240 llvm::Type *ArgType = Base->getType(); 1241 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType); 1242 return RValue::get(Builder.CreateCall(F, {Base, Exponent})); 1243 } 1244 1245 case Builtin::BI__builtin_isgreater: 1246 case Builtin::BI__builtin_isgreaterequal: 1247 case Builtin::BI__builtin_isless: 1248 case Builtin::BI__builtin_islessequal: 1249 case Builtin::BI__builtin_islessgreater: 1250 case Builtin::BI__builtin_isunordered: { 1251 // Ordered comparisons: we know the arguments to these are matching scalar 1252 // floating point values. 1253 Value *LHS = EmitScalarExpr(E->getArg(0)); 1254 Value *RHS = EmitScalarExpr(E->getArg(1)); 1255 1256 switch (BuiltinID) { 1257 default: llvm_unreachable("Unknown ordered comparison"); 1258 case Builtin::BI__builtin_isgreater: 1259 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp"); 1260 break; 1261 case Builtin::BI__builtin_isgreaterequal: 1262 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp"); 1263 break; 1264 case Builtin::BI__builtin_isless: 1265 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp"); 1266 break; 1267 case Builtin::BI__builtin_islessequal: 1268 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp"); 1269 break; 1270 case Builtin::BI__builtin_islessgreater: 1271 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp"); 1272 break; 1273 case Builtin::BI__builtin_isunordered: 1274 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp"); 1275 break; 1276 } 1277 // ZExt bool to int type. 1278 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType()))); 1279 } 1280 case Builtin::BI__builtin_isnan: { 1281 Value *V = EmitScalarExpr(E->getArg(0)); 1282 V = Builder.CreateFCmpUNO(V, V, "cmp"); 1283 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1284 } 1285 1286 case Builtin::BIfinite: 1287 case Builtin::BI__finite: 1288 case Builtin::BIfinitef: 1289 case Builtin::BI__finitef: 1290 case Builtin::BIfinitel: 1291 case Builtin::BI__finitel: 1292 case Builtin::BI__builtin_isinf: 1293 case Builtin::BI__builtin_isfinite: { 1294 // isinf(x) --> fabs(x) == infinity 1295 // isfinite(x) --> fabs(x) != infinity 1296 // x != NaN via the ordered compare in either case. 1297 Value *V = EmitScalarExpr(E->getArg(0)); 1298 Value *Fabs = EmitFAbs(*this, V); 1299 Constant *Infinity = ConstantFP::getInfinity(V->getType()); 1300 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf) 1301 ? CmpInst::FCMP_OEQ 1302 : CmpInst::FCMP_ONE; 1303 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf"); 1304 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType()))); 1305 } 1306 1307 case Builtin::BI__builtin_isinf_sign: { 1308 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0 1309 Value *Arg = EmitScalarExpr(E->getArg(0)); 1310 Value *AbsArg = EmitFAbs(*this, Arg); 1311 Value *IsInf = Builder.CreateFCmpOEQ( 1312 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf"); 1313 Value *IsNeg = EmitSignBit(*this, Arg); 1314 1315 llvm::Type *IntTy = ConvertType(E->getType()); 1316 Value *Zero = Constant::getNullValue(IntTy); 1317 Value *One = ConstantInt::get(IntTy, 1); 1318 Value *NegativeOne = ConstantInt::get(IntTy, -1); 1319 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One); 1320 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero); 1321 return RValue::get(Result); 1322 } 1323 1324 case Builtin::BI__builtin_isnormal: { 1325 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min 1326 Value *V = EmitScalarExpr(E->getArg(0)); 1327 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq"); 1328 1329 Value *Abs = EmitFAbs(*this, V); 1330 Value *IsLessThanInf = 1331 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf"); 1332 APFloat Smallest = APFloat::getSmallestNormalized( 1333 getContext().getFloatTypeSemantics(E->getArg(0)->getType())); 1334 Value *IsNormal = 1335 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest), 1336 "isnormal"); 1337 V = Builder.CreateAnd(Eq, IsLessThanInf, "and"); 1338 V = Builder.CreateAnd(V, IsNormal, "and"); 1339 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType()))); 1340 } 1341 1342 case Builtin::BI__builtin_fpclassify: { 1343 Value *V = EmitScalarExpr(E->getArg(5)); 1344 llvm::Type *Ty = ConvertType(E->getArg(5)->getType()); 1345 1346 // Create Result 1347 BasicBlock *Begin = Builder.GetInsertBlock(); 1348 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn); 1349 Builder.SetInsertPoint(End); 1350 PHINode *Result = 1351 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4, 1352 "fpclassify_result"); 1353 1354 // if (V==0) return FP_ZERO 1355 Builder.SetInsertPoint(Begin); 1356 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty), 1357 "iszero"); 1358 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4)); 1359 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn); 1360 Builder.CreateCondBr(IsZero, End, NotZero); 1361 Result->addIncoming(ZeroLiteral, Begin); 1362 1363 // if (V != V) return FP_NAN 1364 Builder.SetInsertPoint(NotZero); 1365 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp"); 1366 Value *NanLiteral = EmitScalarExpr(E->getArg(0)); 1367 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn); 1368 Builder.CreateCondBr(IsNan, End, NotNan); 1369 Result->addIncoming(NanLiteral, NotZero); 1370 1371 // if (fabs(V) == infinity) return FP_INFINITY 1372 Builder.SetInsertPoint(NotNan); 1373 Value *VAbs = EmitFAbs(*this, V); 1374 Value *IsInf = 1375 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()), 1376 "isinf"); 1377 Value *InfLiteral = EmitScalarExpr(E->getArg(1)); 1378 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn); 1379 Builder.CreateCondBr(IsInf, End, NotInf); 1380 Result->addIncoming(InfLiteral, NotNan); 1381 1382 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL 1383 Builder.SetInsertPoint(NotInf); 1384 APFloat Smallest = APFloat::getSmallestNormalized( 1385 getContext().getFloatTypeSemantics(E->getArg(5)->getType())); 1386 Value *IsNormal = 1387 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest), 1388 "isnormal"); 1389 Value *NormalResult = 1390 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)), 1391 EmitScalarExpr(E->getArg(3))); 1392 Builder.CreateBr(End); 1393 Result->addIncoming(NormalResult, NotInf); 1394 1395 // return Result 1396 Builder.SetInsertPoint(End); 1397 return RValue::get(Result); 1398 } 1399 1400 case Builtin::BIalloca: 1401 case Builtin::BI_alloca: 1402 case Builtin::BI__builtin_alloca: { 1403 Value *Size = EmitScalarExpr(E->getArg(0)); 1404 const TargetInfo &TI = getContext().getTargetInfo(); 1405 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__. 1406 unsigned SuitableAlignmentInBytes = 1407 CGM.getContext() 1408 .toCharUnitsFromBits(TI.getSuitableAlign()) 1409 .getQuantity(); 1410 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1411 AI->setAlignment(SuitableAlignmentInBytes); 1412 return RValue::get(AI); 1413 } 1414 1415 case Builtin::BI__builtin_alloca_with_align: { 1416 Value *Size = EmitScalarExpr(E->getArg(0)); 1417 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1)); 1418 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue); 1419 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue(); 1420 unsigned AlignmentInBytes = 1421 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity(); 1422 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size); 1423 AI->setAlignment(AlignmentInBytes); 1424 return RValue::get(AI); 1425 } 1426 1427 case Builtin::BIbzero: 1428 case Builtin::BI__builtin_bzero: { 1429 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1430 Value *SizeVal = EmitScalarExpr(E->getArg(1)); 1431 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1432 E->getArg(0)->getExprLoc(), FD, 0); 1433 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false); 1434 return RValue::get(Dest.getPointer()); 1435 } 1436 case Builtin::BImemcpy: 1437 case Builtin::BI__builtin_memcpy: { 1438 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1439 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1440 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1441 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1442 E->getArg(0)->getExprLoc(), FD, 0); 1443 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1444 E->getArg(1)->getExprLoc(), FD, 1); 1445 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1446 return RValue::get(Dest.getPointer()); 1447 } 1448 1449 case Builtin::BI__builtin_char_memchr: 1450 BuiltinID = Builtin::BI__builtin_memchr; 1451 break; 1452 1453 case Builtin::BI__builtin___memcpy_chk: { 1454 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2. 1455 llvm::APSInt Size, DstSize; 1456 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1457 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1458 break; 1459 if (Size.ugt(DstSize)) 1460 break; 1461 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1462 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1463 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1464 Builder.CreateMemCpy(Dest, Src, SizeVal, false); 1465 return RValue::get(Dest.getPointer()); 1466 } 1467 1468 case Builtin::BI__builtin_objc_memmove_collectable: { 1469 Address DestAddr = EmitPointerWithAlignment(E->getArg(0)); 1470 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1)); 1471 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1472 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, 1473 DestAddr, SrcAddr, SizeVal); 1474 return RValue::get(DestAddr.getPointer()); 1475 } 1476 1477 case Builtin::BI__builtin___memmove_chk: { 1478 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2. 1479 llvm::APSInt Size, DstSize; 1480 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1481 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1482 break; 1483 if (Size.ugt(DstSize)) 1484 break; 1485 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1486 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1487 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1488 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1489 return RValue::get(Dest.getPointer()); 1490 } 1491 1492 case Builtin::BImemmove: 1493 case Builtin::BI__builtin_memmove: { 1494 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1495 Address Src = EmitPointerWithAlignment(E->getArg(1)); 1496 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1497 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1498 E->getArg(0)->getExprLoc(), FD, 0); 1499 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(), 1500 E->getArg(1)->getExprLoc(), FD, 1); 1501 Builder.CreateMemMove(Dest, Src, SizeVal, false); 1502 return RValue::get(Dest.getPointer()); 1503 } 1504 case Builtin::BImemset: 1505 case Builtin::BI__builtin_memset: { 1506 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1507 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1508 Builder.getInt8Ty()); 1509 Value *SizeVal = EmitScalarExpr(E->getArg(2)); 1510 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(), 1511 E->getArg(0)->getExprLoc(), FD, 0); 1512 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1513 return RValue::get(Dest.getPointer()); 1514 } 1515 case Builtin::BI__builtin___memset_chk: { 1516 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2. 1517 llvm::APSInt Size, DstSize; 1518 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) || 1519 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext())) 1520 break; 1521 if (Size.ugt(DstSize)) 1522 break; 1523 Address Dest = EmitPointerWithAlignment(E->getArg(0)); 1524 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)), 1525 Builder.getInt8Ty()); 1526 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size); 1527 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false); 1528 return RValue::get(Dest.getPointer()); 1529 } 1530 case Builtin::BI__builtin_dwarf_cfa: { 1531 // The offset in bytes from the first argument to the CFA. 1532 // 1533 // Why on earth is this in the frontend? Is there any reason at 1534 // all that the backend can't reasonably determine this while 1535 // lowering llvm.eh.dwarf.cfa()? 1536 // 1537 // TODO: If there's a satisfactory reason, add a target hook for 1538 // this instead of hard-coding 0, which is correct for most targets. 1539 int32_t Offset = 0; 1540 1541 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa); 1542 return RValue::get(Builder.CreateCall(F, 1543 llvm::ConstantInt::get(Int32Ty, Offset))); 1544 } 1545 case Builtin::BI__builtin_return_address: { 1546 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), 1547 getContext().UnsignedIntTy); 1548 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1549 return RValue::get(Builder.CreateCall(F, Depth)); 1550 } 1551 case Builtin::BI_ReturnAddress: { 1552 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress); 1553 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0))); 1554 } 1555 case Builtin::BI__builtin_frame_address: { 1556 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0), 1557 getContext().UnsignedIntTy); 1558 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress); 1559 return RValue::get(Builder.CreateCall(F, Depth)); 1560 } 1561 case Builtin::BI__builtin_extract_return_addr: { 1562 Value *Address = EmitScalarExpr(E->getArg(0)); 1563 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address); 1564 return RValue::get(Result); 1565 } 1566 case Builtin::BI__builtin_frob_return_addr: { 1567 Value *Address = EmitScalarExpr(E->getArg(0)); 1568 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address); 1569 return RValue::get(Result); 1570 } 1571 case Builtin::BI__builtin_dwarf_sp_column: { 1572 llvm::IntegerType *Ty 1573 = cast<llvm::IntegerType>(ConvertType(E->getType())); 1574 int Column = getTargetHooks().getDwarfEHStackPointer(CGM); 1575 if (Column == -1) { 1576 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column"); 1577 return RValue::get(llvm::UndefValue::get(Ty)); 1578 } 1579 return RValue::get(llvm::ConstantInt::get(Ty, Column, true)); 1580 } 1581 case Builtin::BI__builtin_init_dwarf_reg_size_table: { 1582 Value *Address = EmitScalarExpr(E->getArg(0)); 1583 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address)) 1584 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table"); 1585 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType()))); 1586 } 1587 case Builtin::BI__builtin_eh_return: { 1588 Value *Int = EmitScalarExpr(E->getArg(0)); 1589 Value *Ptr = EmitScalarExpr(E->getArg(1)); 1590 1591 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType()); 1592 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) && 1593 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants"); 1594 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32 1595 ? Intrinsic::eh_return_i32 1596 : Intrinsic::eh_return_i64); 1597 Builder.CreateCall(F, {Int, Ptr}); 1598 Builder.CreateUnreachable(); 1599 1600 // We do need to preserve an insertion point. 1601 EmitBlock(createBasicBlock("builtin_eh_return.cont")); 1602 1603 return RValue::get(nullptr); 1604 } 1605 case Builtin::BI__builtin_unwind_init: { 1606 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init); 1607 return RValue::get(Builder.CreateCall(F)); 1608 } 1609 case Builtin::BI__builtin_extend_pointer: { 1610 // Extends a pointer to the size of an _Unwind_Word, which is 1611 // uint64_t on all platforms. Generally this gets poked into a 1612 // register and eventually used as an address, so if the 1613 // addressing registers are wider than pointers and the platform 1614 // doesn't implicitly ignore high-order bits when doing 1615 // addressing, we need to make sure we zext / sext based on 1616 // the platform's expectations. 1617 // 1618 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html 1619 1620 // Cast the pointer to intptr_t. 1621 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1622 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast"); 1623 1624 // If that's 64 bits, we're done. 1625 if (IntPtrTy->getBitWidth() == 64) 1626 return RValue::get(Result); 1627 1628 // Otherwise, ask the codegen data what to do. 1629 if (getTargetHooks().extendPointerWithSExt()) 1630 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext")); 1631 else 1632 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext")); 1633 } 1634 case Builtin::BI__builtin_setjmp: { 1635 // Buffer is a void**. 1636 Address Buf = EmitPointerWithAlignment(E->getArg(0)); 1637 1638 // Store the frame pointer to the setjmp buffer. 1639 Value *FrameAddr = 1640 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 1641 ConstantInt::get(Int32Ty, 0)); 1642 Builder.CreateStore(FrameAddr, Buf); 1643 1644 // Store the stack pointer to the setjmp buffer. 1645 Value *StackAddr = 1646 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave)); 1647 Address StackSaveSlot = 1648 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize()); 1649 Builder.CreateStore(StackAddr, StackSaveSlot); 1650 1651 // Call LLVM's EH setjmp, which is lightweight. 1652 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); 1653 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1654 return RValue::get(Builder.CreateCall(F, Buf.getPointer())); 1655 } 1656 case Builtin::BI__builtin_longjmp: { 1657 Value *Buf = EmitScalarExpr(E->getArg(0)); 1658 Buf = Builder.CreateBitCast(Buf, Int8PtrTy); 1659 1660 // Call LLVM's EH longjmp, which is lightweight. 1661 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf); 1662 1663 // longjmp doesn't return; mark this as unreachable. 1664 Builder.CreateUnreachable(); 1665 1666 // We do need to preserve an insertion point. 1667 EmitBlock(createBasicBlock("longjmp.cont")); 1668 1669 return RValue::get(nullptr); 1670 } 1671 case Builtin::BI__sync_fetch_and_add: 1672 case Builtin::BI__sync_fetch_and_sub: 1673 case Builtin::BI__sync_fetch_and_or: 1674 case Builtin::BI__sync_fetch_and_and: 1675 case Builtin::BI__sync_fetch_and_xor: 1676 case Builtin::BI__sync_fetch_and_nand: 1677 case Builtin::BI__sync_add_and_fetch: 1678 case Builtin::BI__sync_sub_and_fetch: 1679 case Builtin::BI__sync_and_and_fetch: 1680 case Builtin::BI__sync_or_and_fetch: 1681 case Builtin::BI__sync_xor_and_fetch: 1682 case Builtin::BI__sync_nand_and_fetch: 1683 case Builtin::BI__sync_val_compare_and_swap: 1684 case Builtin::BI__sync_bool_compare_and_swap: 1685 case Builtin::BI__sync_lock_test_and_set: 1686 case Builtin::BI__sync_lock_release: 1687 case Builtin::BI__sync_swap: 1688 llvm_unreachable("Shouldn't make it through sema"); 1689 case Builtin::BI__sync_fetch_and_add_1: 1690 case Builtin::BI__sync_fetch_and_add_2: 1691 case Builtin::BI__sync_fetch_and_add_4: 1692 case Builtin::BI__sync_fetch_and_add_8: 1693 case Builtin::BI__sync_fetch_and_add_16: 1694 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E); 1695 case Builtin::BI__sync_fetch_and_sub_1: 1696 case Builtin::BI__sync_fetch_and_sub_2: 1697 case Builtin::BI__sync_fetch_and_sub_4: 1698 case Builtin::BI__sync_fetch_and_sub_8: 1699 case Builtin::BI__sync_fetch_and_sub_16: 1700 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E); 1701 case Builtin::BI__sync_fetch_and_or_1: 1702 case Builtin::BI__sync_fetch_and_or_2: 1703 case Builtin::BI__sync_fetch_and_or_4: 1704 case Builtin::BI__sync_fetch_and_or_8: 1705 case Builtin::BI__sync_fetch_and_or_16: 1706 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E); 1707 case Builtin::BI__sync_fetch_and_and_1: 1708 case Builtin::BI__sync_fetch_and_and_2: 1709 case Builtin::BI__sync_fetch_and_and_4: 1710 case Builtin::BI__sync_fetch_and_and_8: 1711 case Builtin::BI__sync_fetch_and_and_16: 1712 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E); 1713 case Builtin::BI__sync_fetch_and_xor_1: 1714 case Builtin::BI__sync_fetch_and_xor_2: 1715 case Builtin::BI__sync_fetch_and_xor_4: 1716 case Builtin::BI__sync_fetch_and_xor_8: 1717 case Builtin::BI__sync_fetch_and_xor_16: 1718 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E); 1719 case Builtin::BI__sync_fetch_and_nand_1: 1720 case Builtin::BI__sync_fetch_and_nand_2: 1721 case Builtin::BI__sync_fetch_and_nand_4: 1722 case Builtin::BI__sync_fetch_and_nand_8: 1723 case Builtin::BI__sync_fetch_and_nand_16: 1724 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E); 1725 1726 // Clang extensions: not overloaded yet. 1727 case Builtin::BI__sync_fetch_and_min: 1728 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E); 1729 case Builtin::BI__sync_fetch_and_max: 1730 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E); 1731 case Builtin::BI__sync_fetch_and_umin: 1732 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E); 1733 case Builtin::BI__sync_fetch_and_umax: 1734 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E); 1735 1736 case Builtin::BI__sync_add_and_fetch_1: 1737 case Builtin::BI__sync_add_and_fetch_2: 1738 case Builtin::BI__sync_add_and_fetch_4: 1739 case Builtin::BI__sync_add_and_fetch_8: 1740 case Builtin::BI__sync_add_and_fetch_16: 1741 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E, 1742 llvm::Instruction::Add); 1743 case Builtin::BI__sync_sub_and_fetch_1: 1744 case Builtin::BI__sync_sub_and_fetch_2: 1745 case Builtin::BI__sync_sub_and_fetch_4: 1746 case Builtin::BI__sync_sub_and_fetch_8: 1747 case Builtin::BI__sync_sub_and_fetch_16: 1748 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E, 1749 llvm::Instruction::Sub); 1750 case Builtin::BI__sync_and_and_fetch_1: 1751 case Builtin::BI__sync_and_and_fetch_2: 1752 case Builtin::BI__sync_and_and_fetch_4: 1753 case Builtin::BI__sync_and_and_fetch_8: 1754 case Builtin::BI__sync_and_and_fetch_16: 1755 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E, 1756 llvm::Instruction::And); 1757 case Builtin::BI__sync_or_and_fetch_1: 1758 case Builtin::BI__sync_or_and_fetch_2: 1759 case Builtin::BI__sync_or_and_fetch_4: 1760 case Builtin::BI__sync_or_and_fetch_8: 1761 case Builtin::BI__sync_or_and_fetch_16: 1762 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E, 1763 llvm::Instruction::Or); 1764 case Builtin::BI__sync_xor_and_fetch_1: 1765 case Builtin::BI__sync_xor_and_fetch_2: 1766 case Builtin::BI__sync_xor_and_fetch_4: 1767 case Builtin::BI__sync_xor_and_fetch_8: 1768 case Builtin::BI__sync_xor_and_fetch_16: 1769 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E, 1770 llvm::Instruction::Xor); 1771 case Builtin::BI__sync_nand_and_fetch_1: 1772 case Builtin::BI__sync_nand_and_fetch_2: 1773 case Builtin::BI__sync_nand_and_fetch_4: 1774 case Builtin::BI__sync_nand_and_fetch_8: 1775 case Builtin::BI__sync_nand_and_fetch_16: 1776 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E, 1777 llvm::Instruction::And, true); 1778 1779 case Builtin::BI__sync_val_compare_and_swap_1: 1780 case Builtin::BI__sync_val_compare_and_swap_2: 1781 case Builtin::BI__sync_val_compare_and_swap_4: 1782 case Builtin::BI__sync_val_compare_and_swap_8: 1783 case Builtin::BI__sync_val_compare_and_swap_16: 1784 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false)); 1785 1786 case Builtin::BI__sync_bool_compare_and_swap_1: 1787 case Builtin::BI__sync_bool_compare_and_swap_2: 1788 case Builtin::BI__sync_bool_compare_and_swap_4: 1789 case Builtin::BI__sync_bool_compare_and_swap_8: 1790 case Builtin::BI__sync_bool_compare_and_swap_16: 1791 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true)); 1792 1793 case Builtin::BI__sync_swap_1: 1794 case Builtin::BI__sync_swap_2: 1795 case Builtin::BI__sync_swap_4: 1796 case Builtin::BI__sync_swap_8: 1797 case Builtin::BI__sync_swap_16: 1798 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1799 1800 case Builtin::BI__sync_lock_test_and_set_1: 1801 case Builtin::BI__sync_lock_test_and_set_2: 1802 case Builtin::BI__sync_lock_test_and_set_4: 1803 case Builtin::BI__sync_lock_test_and_set_8: 1804 case Builtin::BI__sync_lock_test_and_set_16: 1805 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E); 1806 1807 case Builtin::BI__sync_lock_release_1: 1808 case Builtin::BI__sync_lock_release_2: 1809 case Builtin::BI__sync_lock_release_4: 1810 case Builtin::BI__sync_lock_release_8: 1811 case Builtin::BI__sync_lock_release_16: { 1812 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1813 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 1814 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 1815 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 1816 StoreSize.getQuantity() * 8); 1817 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 1818 llvm::StoreInst *Store = 1819 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr, 1820 StoreSize); 1821 Store->setAtomic(llvm::AtomicOrdering::Release); 1822 return RValue::get(nullptr); 1823 } 1824 1825 case Builtin::BI__sync_synchronize: { 1826 // We assume this is supposed to correspond to a C++0x-style 1827 // sequentially-consistent fence (i.e. this is only usable for 1828 // synchonization, not device I/O or anything like that). This intrinsic 1829 // is really badly designed in the sense that in theory, there isn't 1830 // any way to safely use it... but in practice, it mostly works 1831 // to use it with non-atomic loads and stores to get acquire/release 1832 // semantics. 1833 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent); 1834 return RValue::get(nullptr); 1835 } 1836 1837 case Builtin::BI__builtin_nontemporal_load: 1838 return RValue::get(EmitNontemporalLoad(*this, E)); 1839 case Builtin::BI__builtin_nontemporal_store: 1840 return RValue::get(EmitNontemporalStore(*this, E)); 1841 case Builtin::BI__c11_atomic_is_lock_free: 1842 case Builtin::BI__atomic_is_lock_free: { 1843 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the 1844 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since 1845 // _Atomic(T) is always properly-aligned. 1846 const char *LibCallName = "__atomic_is_lock_free"; 1847 CallArgList Args; 1848 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))), 1849 getContext().getSizeType()); 1850 if (BuiltinID == Builtin::BI__atomic_is_lock_free) 1851 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))), 1852 getContext().VoidPtrTy); 1853 else 1854 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)), 1855 getContext().VoidPtrTy); 1856 const CGFunctionInfo &FuncInfo = 1857 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args); 1858 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo); 1859 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName); 1860 return EmitCall(FuncInfo, CGCallee::forDirect(Func), 1861 ReturnValueSlot(), Args); 1862 } 1863 1864 case Builtin::BI__atomic_test_and_set: { 1865 // Look at the argument type to determine whether this is a volatile 1866 // operation. The parameter type is always volatile. 1867 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1868 bool Volatile = 1869 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1870 1871 Value *Ptr = EmitScalarExpr(E->getArg(0)); 1872 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace(); 1873 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1874 Value *NewVal = Builder.getInt8(1); 1875 Value *Order = EmitScalarExpr(E->getArg(1)); 1876 if (isa<llvm::ConstantInt>(Order)) { 1877 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1878 AtomicRMWInst *Result = nullptr; 1879 switch (ord) { 1880 case 0: // memory_order_relaxed 1881 default: // invalid order 1882 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1883 llvm::AtomicOrdering::Monotonic); 1884 break; 1885 case 1: // memory_order_consume 1886 case 2: // memory_order_acquire 1887 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1888 llvm::AtomicOrdering::Acquire); 1889 break; 1890 case 3: // memory_order_release 1891 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1892 llvm::AtomicOrdering::Release); 1893 break; 1894 case 4: // memory_order_acq_rel 1895 1896 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1897 llvm::AtomicOrdering::AcquireRelease); 1898 break; 1899 case 5: // memory_order_seq_cst 1900 Result = Builder.CreateAtomicRMW( 1901 llvm::AtomicRMWInst::Xchg, Ptr, NewVal, 1902 llvm::AtomicOrdering::SequentiallyConsistent); 1903 break; 1904 } 1905 Result->setVolatile(Volatile); 1906 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1907 } 1908 1909 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1910 1911 llvm::BasicBlock *BBs[5] = { 1912 createBasicBlock("monotonic", CurFn), 1913 createBasicBlock("acquire", CurFn), 1914 createBasicBlock("release", CurFn), 1915 createBasicBlock("acqrel", CurFn), 1916 createBasicBlock("seqcst", CurFn) 1917 }; 1918 llvm::AtomicOrdering Orders[5] = { 1919 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire, 1920 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease, 1921 llvm::AtomicOrdering::SequentiallyConsistent}; 1922 1923 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1924 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1925 1926 Builder.SetInsertPoint(ContBB); 1927 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set"); 1928 1929 for (unsigned i = 0; i < 5; ++i) { 1930 Builder.SetInsertPoint(BBs[i]); 1931 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, 1932 Ptr, NewVal, Orders[i]); 1933 RMW->setVolatile(Volatile); 1934 Result->addIncoming(RMW, BBs[i]); 1935 Builder.CreateBr(ContBB); 1936 } 1937 1938 SI->addCase(Builder.getInt32(0), BBs[0]); 1939 SI->addCase(Builder.getInt32(1), BBs[1]); 1940 SI->addCase(Builder.getInt32(2), BBs[1]); 1941 SI->addCase(Builder.getInt32(3), BBs[2]); 1942 SI->addCase(Builder.getInt32(4), BBs[3]); 1943 SI->addCase(Builder.getInt32(5), BBs[4]); 1944 1945 Builder.SetInsertPoint(ContBB); 1946 return RValue::get(Builder.CreateIsNotNull(Result, "tobool")); 1947 } 1948 1949 case Builtin::BI__atomic_clear: { 1950 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType(); 1951 bool Volatile = 1952 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified(); 1953 1954 Address Ptr = EmitPointerWithAlignment(E->getArg(0)); 1955 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace(); 1956 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace)); 1957 Value *NewVal = Builder.getInt8(0); 1958 Value *Order = EmitScalarExpr(E->getArg(1)); 1959 if (isa<llvm::ConstantInt>(Order)) { 1960 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1961 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1962 switch (ord) { 1963 case 0: // memory_order_relaxed 1964 default: // invalid order 1965 Store->setOrdering(llvm::AtomicOrdering::Monotonic); 1966 break; 1967 case 3: // memory_order_release 1968 Store->setOrdering(llvm::AtomicOrdering::Release); 1969 break; 1970 case 5: // memory_order_seq_cst 1971 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent); 1972 break; 1973 } 1974 return RValue::get(nullptr); 1975 } 1976 1977 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1978 1979 llvm::BasicBlock *BBs[3] = { 1980 createBasicBlock("monotonic", CurFn), 1981 createBasicBlock("release", CurFn), 1982 createBasicBlock("seqcst", CurFn) 1983 }; 1984 llvm::AtomicOrdering Orders[3] = { 1985 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release, 1986 llvm::AtomicOrdering::SequentiallyConsistent}; 1987 1988 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1989 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]); 1990 1991 for (unsigned i = 0; i < 3; ++i) { 1992 Builder.SetInsertPoint(BBs[i]); 1993 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile); 1994 Store->setOrdering(Orders[i]); 1995 Builder.CreateBr(ContBB); 1996 } 1997 1998 SI->addCase(Builder.getInt32(0), BBs[0]); 1999 SI->addCase(Builder.getInt32(3), BBs[1]); 2000 SI->addCase(Builder.getInt32(5), BBs[2]); 2001 2002 Builder.SetInsertPoint(ContBB); 2003 return RValue::get(nullptr); 2004 } 2005 2006 case Builtin::BI__atomic_thread_fence: 2007 case Builtin::BI__atomic_signal_fence: 2008 case Builtin::BI__c11_atomic_thread_fence: 2009 case Builtin::BI__c11_atomic_signal_fence: { 2010 llvm::SyncScope::ID SSID; 2011 if (BuiltinID == Builtin::BI__atomic_signal_fence || 2012 BuiltinID == Builtin::BI__c11_atomic_signal_fence) 2013 SSID = llvm::SyncScope::SingleThread; 2014 else 2015 SSID = llvm::SyncScope::System; 2016 Value *Order = EmitScalarExpr(E->getArg(0)); 2017 if (isa<llvm::ConstantInt>(Order)) { 2018 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 2019 switch (ord) { 2020 case 0: // memory_order_relaxed 2021 default: // invalid order 2022 break; 2023 case 1: // memory_order_consume 2024 case 2: // memory_order_acquire 2025 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID); 2026 break; 2027 case 3: // memory_order_release 2028 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID); 2029 break; 2030 case 4: // memory_order_acq_rel 2031 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID); 2032 break; 2033 case 5: // memory_order_seq_cst 2034 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID); 2035 break; 2036 } 2037 return RValue::get(nullptr); 2038 } 2039 2040 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB; 2041 AcquireBB = createBasicBlock("acquire", CurFn); 2042 ReleaseBB = createBasicBlock("release", CurFn); 2043 AcqRelBB = createBasicBlock("acqrel", CurFn); 2044 SeqCstBB = createBasicBlock("seqcst", CurFn); 2045 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 2046 2047 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 2048 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB); 2049 2050 Builder.SetInsertPoint(AcquireBB); 2051 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID); 2052 Builder.CreateBr(ContBB); 2053 SI->addCase(Builder.getInt32(1), AcquireBB); 2054 SI->addCase(Builder.getInt32(2), AcquireBB); 2055 2056 Builder.SetInsertPoint(ReleaseBB); 2057 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID); 2058 Builder.CreateBr(ContBB); 2059 SI->addCase(Builder.getInt32(3), ReleaseBB); 2060 2061 Builder.SetInsertPoint(AcqRelBB); 2062 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID); 2063 Builder.CreateBr(ContBB); 2064 SI->addCase(Builder.getInt32(4), AcqRelBB); 2065 2066 Builder.SetInsertPoint(SeqCstBB); 2067 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID); 2068 Builder.CreateBr(ContBB); 2069 SI->addCase(Builder.getInt32(5), SeqCstBB); 2070 2071 Builder.SetInsertPoint(ContBB); 2072 return RValue::get(nullptr); 2073 } 2074 2075 // Library functions with special handling. 2076 case Builtin::BIsqrt: 2077 case Builtin::BIsqrtf: 2078 case Builtin::BIsqrtl: { 2079 // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only 2080 // in finite- or unsafe-math mode (the intrinsic has different semantics 2081 // for handling negative numbers compared to the library function, so 2082 // -fmath-errno=0 is not enough). 2083 if (!FD->hasAttr<ConstAttr>()) 2084 break; 2085 if (!(CGM.getCodeGenOpts().UnsafeFPMath || 2086 CGM.getCodeGenOpts().NoNaNsFPMath)) 2087 break; 2088 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 2089 llvm::Type *ArgType = Arg0->getType(); 2090 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType); 2091 return RValue::get(Builder.CreateCall(F, Arg0)); 2092 } 2093 2094 case Builtin::BI__builtin_pow: 2095 case Builtin::BI__builtin_powf: 2096 case Builtin::BI__builtin_powl: 2097 case Builtin::BIpow: 2098 case Builtin::BIpowf: 2099 case Builtin::BIpowl: { 2100 // Transform a call to pow* into a @llvm.pow.* intrinsic call. 2101 if (!FD->hasAttr<ConstAttr>()) 2102 break; 2103 Value *Base = EmitScalarExpr(E->getArg(0)); 2104 Value *Exponent = EmitScalarExpr(E->getArg(1)); 2105 llvm::Type *ArgType = Base->getType(); 2106 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType); 2107 return RValue::get(Builder.CreateCall(F, {Base, Exponent})); 2108 } 2109 2110 case Builtin::BIfma: 2111 case Builtin::BIfmaf: 2112 case Builtin::BIfmal: 2113 case Builtin::BI__builtin_fma: 2114 case Builtin::BI__builtin_fmaf: 2115 case Builtin::BI__builtin_fmal: { 2116 // Rewrite fma to intrinsic. 2117 Value *FirstArg = EmitScalarExpr(E->getArg(0)); 2118 llvm::Type *ArgType = FirstArg->getType(); 2119 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType); 2120 return RValue::get( 2121 Builder.CreateCall(F, {FirstArg, EmitScalarExpr(E->getArg(1)), 2122 EmitScalarExpr(E->getArg(2))})); 2123 } 2124 2125 case Builtin::BI__builtin_signbit: 2126 case Builtin::BI__builtin_signbitf: 2127 case Builtin::BI__builtin_signbitl: { 2128 return RValue::get( 2129 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))), 2130 ConvertType(E->getType()))); 2131 } 2132 case Builtin::BI__annotation: { 2133 // Re-encode each wide string to UTF8 and make an MDString. 2134 SmallVector<Metadata *, 1> Strings; 2135 for (const Expr *Arg : E->arguments()) { 2136 const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts()); 2137 assert(Str->getCharByteWidth() == 2); 2138 StringRef WideBytes = Str->getBytes(); 2139 std::string StrUtf8; 2140 if (!convertUTF16ToUTF8String( 2141 makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) { 2142 CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument"); 2143 continue; 2144 } 2145 Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8)); 2146 } 2147 2148 // Build and MDTuple of MDStrings and emit the intrinsic call. 2149 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {}); 2150 MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings); 2151 Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple)); 2152 return RValue::getIgnored(); 2153 } 2154 case Builtin::BI__builtin_annotation: { 2155 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0)); 2156 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation, 2157 AnnVal->getType()); 2158 2159 // Get the annotation string, go through casts. Sema requires this to be a 2160 // non-wide string literal, potentially casted, so the cast<> is safe. 2161 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts(); 2162 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString(); 2163 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); 2164 } 2165 case Builtin::BI__builtin_addcb: 2166 case Builtin::BI__builtin_addcs: 2167 case Builtin::BI__builtin_addc: 2168 case Builtin::BI__builtin_addcl: 2169 case Builtin::BI__builtin_addcll: 2170 case Builtin::BI__builtin_subcb: 2171 case Builtin::BI__builtin_subcs: 2172 case Builtin::BI__builtin_subc: 2173 case Builtin::BI__builtin_subcl: 2174 case Builtin::BI__builtin_subcll: { 2175 2176 // We translate all of these builtins from expressions of the form: 2177 // int x = ..., y = ..., carryin = ..., carryout, result; 2178 // result = __builtin_addc(x, y, carryin, &carryout); 2179 // 2180 // to LLVM IR of the form: 2181 // 2182 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y) 2183 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0 2184 // %carry1 = extractvalue {i32, i1} %tmp1, 1 2185 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1, 2186 // i32 %carryin) 2187 // %result = extractvalue {i32, i1} %tmp2, 0 2188 // %carry2 = extractvalue {i32, i1} %tmp2, 1 2189 // %tmp3 = or i1 %carry1, %carry2 2190 // %tmp4 = zext i1 %tmp3 to i32 2191 // store i32 %tmp4, i32* %carryout 2192 2193 // Scalarize our inputs. 2194 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2195 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2196 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2)); 2197 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3)); 2198 2199 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow. 2200 llvm::Intrinsic::ID IntrinsicId; 2201 switch (BuiltinID) { 2202 default: llvm_unreachable("Unknown multiprecision builtin id."); 2203 case Builtin::BI__builtin_addcb: 2204 case Builtin::BI__builtin_addcs: 2205 case Builtin::BI__builtin_addc: 2206 case Builtin::BI__builtin_addcl: 2207 case Builtin::BI__builtin_addcll: 2208 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2209 break; 2210 case Builtin::BI__builtin_subcb: 2211 case Builtin::BI__builtin_subcs: 2212 case Builtin::BI__builtin_subc: 2213 case Builtin::BI__builtin_subcl: 2214 case Builtin::BI__builtin_subcll: 2215 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2216 break; 2217 } 2218 2219 // Construct our resulting LLVM IR expression. 2220 llvm::Value *Carry1; 2221 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId, 2222 X, Y, Carry1); 2223 llvm::Value *Carry2; 2224 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId, 2225 Sum1, Carryin, Carry2); 2226 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2), 2227 X->getType()); 2228 Builder.CreateStore(CarryOut, CarryOutPtr); 2229 return RValue::get(Sum2); 2230 } 2231 2232 case Builtin::BI__builtin_add_overflow: 2233 case Builtin::BI__builtin_sub_overflow: 2234 case Builtin::BI__builtin_mul_overflow: { 2235 const clang::Expr *LeftArg = E->getArg(0); 2236 const clang::Expr *RightArg = E->getArg(1); 2237 const clang::Expr *ResultArg = E->getArg(2); 2238 2239 clang::QualType ResultQTy = 2240 ResultArg->getType()->castAs<PointerType>()->getPointeeType(); 2241 2242 WidthAndSignedness LeftInfo = 2243 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType()); 2244 WidthAndSignedness RightInfo = 2245 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType()); 2246 WidthAndSignedness ResultInfo = 2247 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy); 2248 WidthAndSignedness EncompassingInfo = 2249 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo}); 2250 2251 llvm::Type *EncompassingLLVMTy = 2252 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width); 2253 2254 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy); 2255 2256 llvm::Intrinsic::ID IntrinsicId; 2257 switch (BuiltinID) { 2258 default: 2259 llvm_unreachable("Unknown overflow builtin id."); 2260 case Builtin::BI__builtin_add_overflow: 2261 IntrinsicId = EncompassingInfo.Signed 2262 ? llvm::Intrinsic::sadd_with_overflow 2263 : llvm::Intrinsic::uadd_with_overflow; 2264 break; 2265 case Builtin::BI__builtin_sub_overflow: 2266 IntrinsicId = EncompassingInfo.Signed 2267 ? llvm::Intrinsic::ssub_with_overflow 2268 : llvm::Intrinsic::usub_with_overflow; 2269 break; 2270 case Builtin::BI__builtin_mul_overflow: 2271 IntrinsicId = EncompassingInfo.Signed 2272 ? llvm::Intrinsic::smul_with_overflow 2273 : llvm::Intrinsic::umul_with_overflow; 2274 break; 2275 } 2276 2277 llvm::Value *Left = EmitScalarExpr(LeftArg); 2278 llvm::Value *Right = EmitScalarExpr(RightArg); 2279 Address ResultPtr = EmitPointerWithAlignment(ResultArg); 2280 2281 // Extend each operand to the encompassing type. 2282 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed); 2283 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed); 2284 2285 // Perform the operation on the extended values. 2286 llvm::Value *Overflow, *Result; 2287 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow); 2288 2289 if (EncompassingInfo.Width > ResultInfo.Width) { 2290 // The encompassing type is wider than the result type, so we need to 2291 // truncate it. 2292 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy); 2293 2294 // To see if the truncation caused an overflow, we will extend 2295 // the result and then compare it to the original result. 2296 llvm::Value *ResultTruncExt = Builder.CreateIntCast( 2297 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed); 2298 llvm::Value *TruncationOverflow = 2299 Builder.CreateICmpNE(Result, ResultTruncExt); 2300 2301 Overflow = Builder.CreateOr(Overflow, TruncationOverflow); 2302 Result = ResultTrunc; 2303 } 2304 2305 // Finally, store the result using the pointer. 2306 bool isVolatile = 2307 ResultArg->getType()->getPointeeType().isVolatileQualified(); 2308 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile); 2309 2310 return RValue::get(Overflow); 2311 } 2312 2313 case Builtin::BI__builtin_uadd_overflow: 2314 case Builtin::BI__builtin_uaddl_overflow: 2315 case Builtin::BI__builtin_uaddll_overflow: 2316 case Builtin::BI__builtin_usub_overflow: 2317 case Builtin::BI__builtin_usubl_overflow: 2318 case Builtin::BI__builtin_usubll_overflow: 2319 case Builtin::BI__builtin_umul_overflow: 2320 case Builtin::BI__builtin_umull_overflow: 2321 case Builtin::BI__builtin_umulll_overflow: 2322 case Builtin::BI__builtin_sadd_overflow: 2323 case Builtin::BI__builtin_saddl_overflow: 2324 case Builtin::BI__builtin_saddll_overflow: 2325 case Builtin::BI__builtin_ssub_overflow: 2326 case Builtin::BI__builtin_ssubl_overflow: 2327 case Builtin::BI__builtin_ssubll_overflow: 2328 case Builtin::BI__builtin_smul_overflow: 2329 case Builtin::BI__builtin_smull_overflow: 2330 case Builtin::BI__builtin_smulll_overflow: { 2331 2332 // We translate all of these builtins directly to the relevant llvm IR node. 2333 2334 // Scalarize our inputs. 2335 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 2336 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 2337 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2)); 2338 2339 // Decide which of the overflow intrinsics we are lowering to: 2340 llvm::Intrinsic::ID IntrinsicId; 2341 switch (BuiltinID) { 2342 default: llvm_unreachable("Unknown overflow builtin id."); 2343 case Builtin::BI__builtin_uadd_overflow: 2344 case Builtin::BI__builtin_uaddl_overflow: 2345 case Builtin::BI__builtin_uaddll_overflow: 2346 IntrinsicId = llvm::Intrinsic::uadd_with_overflow; 2347 break; 2348 case Builtin::BI__builtin_usub_overflow: 2349 case Builtin::BI__builtin_usubl_overflow: 2350 case Builtin::BI__builtin_usubll_overflow: 2351 IntrinsicId = llvm::Intrinsic::usub_with_overflow; 2352 break; 2353 case Builtin::BI__builtin_umul_overflow: 2354 case Builtin::BI__builtin_umull_overflow: 2355 case Builtin::BI__builtin_umulll_overflow: 2356 IntrinsicId = llvm::Intrinsic::umul_with_overflow; 2357 break; 2358 case Builtin::BI__builtin_sadd_overflow: 2359 case Builtin::BI__builtin_saddl_overflow: 2360 case Builtin::BI__builtin_saddll_overflow: 2361 IntrinsicId = llvm::Intrinsic::sadd_with_overflow; 2362 break; 2363 case Builtin::BI__builtin_ssub_overflow: 2364 case Builtin::BI__builtin_ssubl_overflow: 2365 case Builtin::BI__builtin_ssubll_overflow: 2366 IntrinsicId = llvm::Intrinsic::ssub_with_overflow; 2367 break; 2368 case Builtin::BI__builtin_smul_overflow: 2369 case Builtin::BI__builtin_smull_overflow: 2370 case Builtin::BI__builtin_smulll_overflow: 2371 IntrinsicId = llvm::Intrinsic::smul_with_overflow; 2372 break; 2373 } 2374 2375 2376 llvm::Value *Carry; 2377 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry); 2378 Builder.CreateStore(Sum, SumOutPtr); 2379 2380 return RValue::get(Carry); 2381 } 2382 case Builtin::BI__builtin_addressof: 2383 return RValue::get(EmitLValue(E->getArg(0)).getPointer()); 2384 case Builtin::BI__builtin_operator_new: 2385 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2386 E->getArg(0), false); 2387 case Builtin::BI__builtin_operator_delete: 2388 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(), 2389 E->getArg(0), true); 2390 case Builtin::BI__noop: 2391 // __noop always evaluates to an integer literal zero. 2392 return RValue::get(ConstantInt::get(IntTy, 0)); 2393 case Builtin::BI__builtin_call_with_static_chain: { 2394 const CallExpr *Call = cast<CallExpr>(E->getArg(0)); 2395 const Expr *Chain = E->getArg(1); 2396 return EmitCall(Call->getCallee()->getType(), 2397 EmitCallee(Call->getCallee()), Call, ReturnValue, 2398 EmitScalarExpr(Chain)); 2399 } 2400 case Builtin::BI_InterlockedExchange8: 2401 case Builtin::BI_InterlockedExchange16: 2402 case Builtin::BI_InterlockedExchange: 2403 case Builtin::BI_InterlockedExchangePointer: 2404 return RValue::get( 2405 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E)); 2406 case Builtin::BI_InterlockedCompareExchangePointer: { 2407 llvm::Type *RTy; 2408 llvm::IntegerType *IntType = 2409 IntegerType::get(getLLVMContext(), 2410 getContext().getTypeSize(E->getType())); 2411 llvm::Type *IntPtrType = IntType->getPointerTo(); 2412 2413 llvm::Value *Destination = 2414 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType); 2415 2416 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1)); 2417 RTy = Exchange->getType(); 2418 Exchange = Builder.CreatePtrToInt(Exchange, IntType); 2419 2420 llvm::Value *Comparand = 2421 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType); 2422 2423 auto Result = 2424 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange, 2425 AtomicOrdering::SequentiallyConsistent, 2426 AtomicOrdering::SequentiallyConsistent); 2427 Result->setVolatile(true); 2428 2429 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result, 2430 0), 2431 RTy)); 2432 } 2433 case Builtin::BI_InterlockedCompareExchange8: 2434 case Builtin::BI_InterlockedCompareExchange16: 2435 case Builtin::BI_InterlockedCompareExchange: 2436 case Builtin::BI_InterlockedCompareExchange64: { 2437 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg( 2438 EmitScalarExpr(E->getArg(0)), 2439 EmitScalarExpr(E->getArg(2)), 2440 EmitScalarExpr(E->getArg(1)), 2441 AtomicOrdering::SequentiallyConsistent, 2442 AtomicOrdering::SequentiallyConsistent); 2443 CXI->setVolatile(true); 2444 return RValue::get(Builder.CreateExtractValue(CXI, 0)); 2445 } 2446 case Builtin::BI_InterlockedIncrement16: 2447 case Builtin::BI_InterlockedIncrement: 2448 return RValue::get( 2449 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E)); 2450 case Builtin::BI_InterlockedDecrement16: 2451 case Builtin::BI_InterlockedDecrement: 2452 return RValue::get( 2453 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E)); 2454 case Builtin::BI_InterlockedAnd8: 2455 case Builtin::BI_InterlockedAnd16: 2456 case Builtin::BI_InterlockedAnd: 2457 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E)); 2458 case Builtin::BI_InterlockedExchangeAdd8: 2459 case Builtin::BI_InterlockedExchangeAdd16: 2460 case Builtin::BI_InterlockedExchangeAdd: 2461 return RValue::get( 2462 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E)); 2463 case Builtin::BI_InterlockedExchangeSub8: 2464 case Builtin::BI_InterlockedExchangeSub16: 2465 case Builtin::BI_InterlockedExchangeSub: 2466 return RValue::get( 2467 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E)); 2468 case Builtin::BI_InterlockedOr8: 2469 case Builtin::BI_InterlockedOr16: 2470 case Builtin::BI_InterlockedOr: 2471 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E)); 2472 case Builtin::BI_InterlockedXor8: 2473 case Builtin::BI_InterlockedXor16: 2474 case Builtin::BI_InterlockedXor: 2475 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E)); 2476 case Builtin::BI_interlockedbittestandset: 2477 return RValue::get( 2478 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E)); 2479 2480 case Builtin::BI__exception_code: 2481 case Builtin::BI_exception_code: 2482 return RValue::get(EmitSEHExceptionCode()); 2483 case Builtin::BI__exception_info: 2484 case Builtin::BI_exception_info: 2485 return RValue::get(EmitSEHExceptionInfo()); 2486 case Builtin::BI__abnormal_termination: 2487 case Builtin::BI_abnormal_termination: 2488 return RValue::get(EmitSEHAbnormalTermination()); 2489 case Builtin::BI_setjmpex: { 2490 if (getTarget().getTriple().isOSMSVCRT()) { 2491 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2492 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2493 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2494 llvm::Attribute::ReturnsTwice); 2495 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction( 2496 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2497 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true); 2498 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2499 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2500 llvm::Value *FrameAddr = 2501 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2502 ConstantInt::get(Int32Ty, 0)); 2503 llvm::Value *Args[] = {Buf, FrameAddr}; 2504 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args); 2505 CS.setAttributes(ReturnsTwiceAttr); 2506 return RValue::get(CS.getInstruction()); 2507 } 2508 break; 2509 } 2510 case Builtin::BI_setjmp: { 2511 if (getTarget().getTriple().isOSMSVCRT()) { 2512 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get( 2513 getLLVMContext(), llvm::AttributeList::FunctionIndex, 2514 llvm::Attribute::ReturnsTwice); 2515 llvm::Value *Buf = Builder.CreateBitOrPointerCast( 2516 EmitScalarExpr(E->getArg(0)), Int8PtrTy); 2517 llvm::CallSite CS; 2518 if (getTarget().getTriple().getArch() == llvm::Triple::x86) { 2519 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy}; 2520 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction( 2521 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true), 2522 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true); 2523 llvm::Value *Count = ConstantInt::get(IntTy, 0); 2524 llvm::Value *Args[] = {Buf, Count}; 2525 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args); 2526 } else { 2527 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy}; 2528 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction( 2529 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false), 2530 "_setjmp", ReturnsTwiceAttr, /*Local=*/true); 2531 llvm::Value *FrameAddr = 2532 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress), 2533 ConstantInt::get(Int32Ty, 0)); 2534 llvm::Value *Args[] = {Buf, FrameAddr}; 2535 CS = EmitRuntimeCallOrInvoke(SetJmp, Args); 2536 } 2537 CS.setAttributes(ReturnsTwiceAttr); 2538 return RValue::get(CS.getInstruction()); 2539 } 2540 break; 2541 } 2542 2543 case Builtin::BI__GetExceptionInfo: { 2544 if (llvm::GlobalVariable *GV = 2545 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType())) 2546 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy)); 2547 break; 2548 } 2549 2550 case Builtin::BI__fastfail: 2551 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E)); 2552 2553 case Builtin::BI__builtin_coro_size: { 2554 auto & Context = getContext(); 2555 auto SizeTy = Context.getSizeType(); 2556 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy)); 2557 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T); 2558 return RValue::get(Builder.CreateCall(F)); 2559 } 2560 2561 case Builtin::BI__builtin_coro_id: 2562 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id); 2563 case Builtin::BI__builtin_coro_promise: 2564 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise); 2565 case Builtin::BI__builtin_coro_resume: 2566 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume); 2567 case Builtin::BI__builtin_coro_frame: 2568 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame); 2569 case Builtin::BI__builtin_coro_free: 2570 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free); 2571 case Builtin::BI__builtin_coro_destroy: 2572 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy); 2573 case Builtin::BI__builtin_coro_done: 2574 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done); 2575 case Builtin::BI__builtin_coro_alloc: 2576 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc); 2577 case Builtin::BI__builtin_coro_begin: 2578 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin); 2579 case Builtin::BI__builtin_coro_end: 2580 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end); 2581 case Builtin::BI__builtin_coro_suspend: 2582 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend); 2583 case Builtin::BI__builtin_coro_param: 2584 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param); 2585 2586 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions 2587 case Builtin::BIread_pipe: 2588 case Builtin::BIwrite_pipe: { 2589 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2590 *Arg1 = EmitScalarExpr(E->getArg(1)); 2591 CGOpenCLRuntime OpenCLRT(CGM); 2592 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2593 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2594 2595 // Type of the generic packet parameter. 2596 unsigned GenericAS = 2597 getContext().getTargetAddressSpace(LangAS::opencl_generic); 2598 llvm::Type *I8PTy = llvm::PointerType::get( 2599 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS); 2600 2601 // Testing which overloaded version we should generate the call for. 2602 if (2U == E->getNumArgs()) { 2603 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2" 2604 : "__write_pipe_2"; 2605 // Creating a generic function type to be able to call with any builtin or 2606 // user defined type. 2607 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty}; 2608 llvm::FunctionType *FTy = llvm::FunctionType::get( 2609 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2610 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy); 2611 return RValue::get( 2612 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2613 {Arg0, BCast, PacketSize, PacketAlign})); 2614 } else { 2615 assert(4 == E->getNumArgs() && 2616 "Illegal number of parameters to pipe function"); 2617 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4" 2618 : "__write_pipe_4"; 2619 2620 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy, 2621 Int32Ty, Int32Ty}; 2622 Value *Arg2 = EmitScalarExpr(E->getArg(2)), 2623 *Arg3 = EmitScalarExpr(E->getArg(3)); 2624 llvm::FunctionType *FTy = llvm::FunctionType::get( 2625 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2626 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy); 2627 // We know the third argument is an integer type, but we may need to cast 2628 // it to i32. 2629 if (Arg2->getType() != Int32Ty) 2630 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty); 2631 return RValue::get(Builder.CreateCall( 2632 CGM.CreateRuntimeFunction(FTy, Name), 2633 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign})); 2634 } 2635 } 2636 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write 2637 // functions 2638 case Builtin::BIreserve_read_pipe: 2639 case Builtin::BIreserve_write_pipe: 2640 case Builtin::BIwork_group_reserve_read_pipe: 2641 case Builtin::BIwork_group_reserve_write_pipe: 2642 case Builtin::BIsub_group_reserve_read_pipe: 2643 case Builtin::BIsub_group_reserve_write_pipe: { 2644 // Composing the mangled name for the function. 2645 const char *Name; 2646 if (BuiltinID == Builtin::BIreserve_read_pipe) 2647 Name = "__reserve_read_pipe"; 2648 else if (BuiltinID == Builtin::BIreserve_write_pipe) 2649 Name = "__reserve_write_pipe"; 2650 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe) 2651 Name = "__work_group_reserve_read_pipe"; 2652 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe) 2653 Name = "__work_group_reserve_write_pipe"; 2654 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe) 2655 Name = "__sub_group_reserve_read_pipe"; 2656 else 2657 Name = "__sub_group_reserve_write_pipe"; 2658 2659 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2660 *Arg1 = EmitScalarExpr(E->getArg(1)); 2661 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy); 2662 CGOpenCLRuntime OpenCLRT(CGM); 2663 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2664 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2665 2666 // Building the generic function prototype. 2667 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty}; 2668 llvm::FunctionType *FTy = llvm::FunctionType::get( 2669 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2670 // We know the second argument is an integer type, but we may need to cast 2671 // it to i32. 2672 if (Arg1->getType() != Int32Ty) 2673 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty); 2674 return RValue::get( 2675 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2676 {Arg0, Arg1, PacketSize, PacketAlign})); 2677 } 2678 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write 2679 // functions 2680 case Builtin::BIcommit_read_pipe: 2681 case Builtin::BIcommit_write_pipe: 2682 case Builtin::BIwork_group_commit_read_pipe: 2683 case Builtin::BIwork_group_commit_write_pipe: 2684 case Builtin::BIsub_group_commit_read_pipe: 2685 case Builtin::BIsub_group_commit_write_pipe: { 2686 const char *Name; 2687 if (BuiltinID == Builtin::BIcommit_read_pipe) 2688 Name = "__commit_read_pipe"; 2689 else if (BuiltinID == Builtin::BIcommit_write_pipe) 2690 Name = "__commit_write_pipe"; 2691 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe) 2692 Name = "__work_group_commit_read_pipe"; 2693 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe) 2694 Name = "__work_group_commit_write_pipe"; 2695 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe) 2696 Name = "__sub_group_commit_read_pipe"; 2697 else 2698 Name = "__sub_group_commit_write_pipe"; 2699 2700 Value *Arg0 = EmitScalarExpr(E->getArg(0)), 2701 *Arg1 = EmitScalarExpr(E->getArg(1)); 2702 CGOpenCLRuntime OpenCLRT(CGM); 2703 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2704 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2705 2706 // Building the generic function prototype. 2707 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty}; 2708 llvm::FunctionType *FTy = 2709 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), 2710 llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2711 2712 return RValue::get( 2713 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2714 {Arg0, Arg1, PacketSize, PacketAlign})); 2715 } 2716 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions 2717 case Builtin::BIget_pipe_num_packets: 2718 case Builtin::BIget_pipe_max_packets: { 2719 const char *Name; 2720 if (BuiltinID == Builtin::BIget_pipe_num_packets) 2721 Name = "__get_pipe_num_packets"; 2722 else 2723 Name = "__get_pipe_max_packets"; 2724 2725 // Building the generic function prototype. 2726 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 2727 CGOpenCLRuntime OpenCLRT(CGM); 2728 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0)); 2729 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0)); 2730 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty}; 2731 llvm::FunctionType *FTy = llvm::FunctionType::get( 2732 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2733 2734 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2735 {Arg0, PacketSize, PacketAlign})); 2736 } 2737 2738 // OpenCL v2.0 s6.13.9 - Address space qualifier functions. 2739 case Builtin::BIto_global: 2740 case Builtin::BIto_local: 2741 case Builtin::BIto_private: { 2742 auto Arg0 = EmitScalarExpr(E->getArg(0)); 2743 auto NewArgT = llvm::PointerType::get(Int8Ty, 2744 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2745 auto NewRetT = llvm::PointerType::get(Int8Ty, 2746 CGM.getContext().getTargetAddressSpace( 2747 E->getType()->getPointeeType().getAddressSpace())); 2748 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false); 2749 llvm::Value *NewArg; 2750 if (Arg0->getType()->getPointerAddressSpace() != 2751 NewArgT->getPointerAddressSpace()) 2752 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT); 2753 else 2754 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT); 2755 auto NewName = std::string("__") + E->getDirectCallee()->getName().str(); 2756 auto NewCall = 2757 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg}); 2758 return RValue::get(Builder.CreateBitOrPointerCast(NewCall, 2759 ConvertType(E->getType()))); 2760 } 2761 2762 // OpenCL v2.0, s6.13.17 - Enqueue kernel function. 2763 // It contains four different overload formats specified in Table 6.13.17.1. 2764 case Builtin::BIenqueue_kernel: { 2765 StringRef Name; // Generated function call name 2766 unsigned NumArgs = E->getNumArgs(); 2767 2768 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy); 2769 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2770 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2771 2772 llvm::Value *Queue = EmitScalarExpr(E->getArg(0)); 2773 llvm::Value *Flags = EmitScalarExpr(E->getArg(1)); 2774 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2)); 2775 llvm::Value *Range = NDRangeL.getAddress().getPointer(); 2776 llvm::Type *RangeTy = NDRangeL.getAddress().getType(); 2777 2778 if (NumArgs == 4) { 2779 // The most basic form of the call with parameters: 2780 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void) 2781 Name = "__enqueue_kernel_basic"; 2782 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy, 2783 GenericVoidPtrTy}; 2784 llvm::FunctionType *FTy = llvm::FunctionType::get( 2785 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2786 2787 auto Info = 2788 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2789 llvm::Value *Kernel = 2790 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2791 llvm::Value *Block = 2792 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2793 2794 AttrBuilder B; 2795 B.addAttribute(Attribute::ByVal); 2796 llvm::AttributeList ByValAttrSet = 2797 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B); 2798 2799 auto RTCall = 2800 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet), 2801 {Queue, Flags, Range, Kernel, Block}); 2802 RTCall->setAttributes(ByValAttrSet); 2803 return RValue::get(RTCall); 2804 } 2805 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature"); 2806 2807 // Create a temporary array to hold the sizes of local pointer arguments 2808 // for the block. \p First is the position of the first size argument. 2809 auto CreateArrayForSizeVar = [=](unsigned First) { 2810 auto *AT = llvm::ArrayType::get(SizeTy, NumArgs - First); 2811 auto *Arr = Builder.CreateAlloca(AT); 2812 llvm::Value *Ptr; 2813 // Each of the following arguments specifies the size of the corresponding 2814 // argument passed to the enqueued block. 2815 auto *Zero = llvm::ConstantInt::get(IntTy, 0); 2816 for (unsigned I = First; I < NumArgs; ++I) { 2817 auto *Index = llvm::ConstantInt::get(IntTy, I - First); 2818 auto *GEP = Builder.CreateGEP(Arr, {Zero, Index}); 2819 if (I == First) 2820 Ptr = GEP; 2821 auto *V = 2822 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy); 2823 Builder.CreateAlignedStore( 2824 V, GEP, CGM.getDataLayout().getPrefTypeAlignment(SizeTy)); 2825 } 2826 return Ptr; 2827 }; 2828 2829 // Could have events and/or vaargs. 2830 if (E->getArg(3)->getType()->isBlockPointerType()) { 2831 // No events passed, but has variadic arguments. 2832 Name = "__enqueue_kernel_vaargs"; 2833 auto Info = 2834 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3)); 2835 llvm::Value *Kernel = 2836 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2837 auto *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2838 auto *PtrToSizeArray = CreateArrayForSizeVar(4); 2839 2840 // Create a vector of the arguments, as well as a constant value to 2841 // express to the runtime the number of variadic arguments. 2842 std::vector<llvm::Value *> Args = { 2843 Queue, Flags, Range, 2844 Kernel, Block, ConstantInt::get(IntTy, NumArgs - 4), 2845 PtrToSizeArray}; 2846 std::vector<llvm::Type *> ArgTys = { 2847 QueueTy, IntTy, RangeTy, 2848 GenericVoidPtrTy, GenericVoidPtrTy, IntTy, 2849 PtrToSizeArray->getType()}; 2850 2851 llvm::FunctionType *FTy = llvm::FunctionType::get( 2852 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2853 return RValue::get( 2854 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2855 llvm::ArrayRef<llvm::Value *>(Args))); 2856 } 2857 // Any calls now have event arguments passed. 2858 if (NumArgs >= 7) { 2859 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy); 2860 llvm::Type *EventPtrTy = EventTy->getPointerTo( 2861 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2862 2863 llvm::Value *NumEvents = 2864 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty); 2865 llvm::Value *EventList = 2866 E->getArg(4)->getType()->isArrayType() 2867 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer() 2868 : EmitScalarExpr(E->getArg(4)); 2869 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5)); 2870 // Convert to generic address space. 2871 EventList = Builder.CreatePointerCast(EventList, EventPtrTy); 2872 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy); 2873 auto Info = 2874 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(6)); 2875 llvm::Value *Kernel = 2876 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2877 llvm::Value *Block = 2878 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2879 2880 std::vector<llvm::Type *> ArgTys = { 2881 QueueTy, Int32Ty, RangeTy, Int32Ty, 2882 EventPtrTy, EventPtrTy, GenericVoidPtrTy, GenericVoidPtrTy}; 2883 2884 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents, 2885 EventList, ClkEvent, Kernel, Block}; 2886 2887 if (NumArgs == 7) { 2888 // Has events but no variadics. 2889 Name = "__enqueue_kernel_basic_events"; 2890 llvm::FunctionType *FTy = llvm::FunctionType::get( 2891 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2892 return RValue::get( 2893 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2894 llvm::ArrayRef<llvm::Value *>(Args))); 2895 } 2896 // Has event info and variadics 2897 // Pass the number of variadics to the runtime function too. 2898 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7)); 2899 ArgTys.push_back(Int32Ty); 2900 Name = "__enqueue_kernel_events_vaargs"; 2901 2902 auto *PtrToSizeArray = CreateArrayForSizeVar(7); 2903 Args.push_back(PtrToSizeArray); 2904 ArgTys.push_back(PtrToSizeArray->getType()); 2905 2906 llvm::FunctionType *FTy = llvm::FunctionType::get( 2907 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false); 2908 return RValue::get( 2909 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name), 2910 llvm::ArrayRef<llvm::Value *>(Args))); 2911 } 2912 LLVM_FALLTHROUGH; 2913 } 2914 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block 2915 // parameter. 2916 case Builtin::BIget_kernel_work_group_size: { 2917 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2918 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2919 auto Info = 2920 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 2921 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2922 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2923 return RValue::get(Builder.CreateCall( 2924 CGM.CreateRuntimeFunction( 2925 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 2926 false), 2927 "__get_kernel_work_group_size_impl"), 2928 {Kernel, Arg})); 2929 } 2930 case Builtin::BIget_kernel_preferred_work_group_size_multiple: { 2931 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2932 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2933 auto Info = 2934 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0)); 2935 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2936 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2937 return RValue::get(Builder.CreateCall( 2938 CGM.CreateRuntimeFunction( 2939 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy}, 2940 false), 2941 "__get_kernel_preferred_work_group_multiple_impl"), 2942 {Kernel, Arg})); 2943 } 2944 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange: 2945 case Builtin::BIget_kernel_sub_group_count_for_ndrange: { 2946 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy( 2947 getContext().getTargetAddressSpace(LangAS::opencl_generic)); 2948 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0)); 2949 llvm::Value *NDRange = NDRangeL.getAddress().getPointer(); 2950 auto Info = 2951 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(1)); 2952 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy); 2953 Value *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy); 2954 const char *Name = 2955 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange 2956 ? "__get_kernel_max_sub_group_size_for_ndrange_impl" 2957 : "__get_kernel_sub_group_count_for_ndrange_impl"; 2958 return RValue::get(Builder.CreateCall( 2959 CGM.CreateRuntimeFunction( 2960 llvm::FunctionType::get( 2961 IntTy, {NDRange->getType(), GenericVoidPtrTy, GenericVoidPtrTy}, 2962 false), 2963 Name), 2964 {NDRange, Kernel, Block})); 2965 } 2966 2967 case Builtin::BI__builtin_store_half: 2968 case Builtin::BI__builtin_store_halff: { 2969 Value *Val = EmitScalarExpr(E->getArg(0)); 2970 Address Address = EmitPointerWithAlignment(E->getArg(1)); 2971 Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy()); 2972 return RValue::get(Builder.CreateStore(HalfVal, Address)); 2973 } 2974 case Builtin::BI__builtin_load_half: { 2975 Address Address = EmitPointerWithAlignment(E->getArg(0)); 2976 Value *HalfVal = Builder.CreateLoad(Address); 2977 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy())); 2978 } 2979 case Builtin::BI__builtin_load_halff: { 2980 Address Address = EmitPointerWithAlignment(E->getArg(0)); 2981 Value *HalfVal = Builder.CreateLoad(Address); 2982 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy())); 2983 } 2984 case Builtin::BIprintf: 2985 if (getTarget().getTriple().isNVPTX()) 2986 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue); 2987 break; 2988 case Builtin::BI__builtin_canonicalize: 2989 case Builtin::BI__builtin_canonicalizef: 2990 case Builtin::BI__builtin_canonicalizel: 2991 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize)); 2992 2993 case Builtin::BI__builtin_thread_pointer: { 2994 if (!getContext().getTargetInfo().isTLSSupported()) 2995 CGM.ErrorUnsupported(E, "__builtin_thread_pointer"); 2996 // Fall through - it's already mapped to the intrinsic by GCCBuiltin. 2997 break; 2998 } 2999 case Builtin::BI__builtin_os_log_format: 3000 return emitBuiltinOSLogFormat(*E); 3001 3002 case Builtin::BI__builtin_os_log_format_buffer_size: { 3003 analyze_os_log::OSLogBufferLayout Layout; 3004 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout); 3005 return RValue::get(ConstantInt::get(ConvertType(E->getType()), 3006 Layout.size().getQuantity())); 3007 } 3008 3009 case Builtin::BI__xray_customevent: { 3010 if (!ShouldXRayInstrumentFunction()) 3011 return RValue::getIgnored(); 3012 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) { 3013 if (XRayAttr->neverXRayInstrument()) 3014 return RValue::getIgnored(); 3015 } 3016 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent); 3017 auto FTy = F->getFunctionType(); 3018 auto Arg0 = E->getArg(0); 3019 auto Arg0Val = EmitScalarExpr(Arg0); 3020 auto Arg0Ty = Arg0->getType(); 3021 auto PTy0 = FTy->getParamType(0); 3022 if (PTy0 != Arg0Val->getType()) { 3023 if (Arg0Ty->isArrayType()) 3024 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer(); 3025 else 3026 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0); 3027 } 3028 auto Arg1 = EmitScalarExpr(E->getArg(1)); 3029 auto PTy1 = FTy->getParamType(1); 3030 if (PTy1 != Arg1->getType()) 3031 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1); 3032 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1})); 3033 } 3034 3035 case Builtin::BI__builtin_ms_va_start: 3036 case Builtin::BI__builtin_ms_va_end: 3037 return RValue::get( 3038 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(), 3039 BuiltinID == Builtin::BI__builtin_ms_va_start)); 3040 3041 case Builtin::BI__builtin_ms_va_copy: { 3042 // Lower this manually. We can't reliably determine whether or not any 3043 // given va_copy() is for a Win64 va_list from the calling convention 3044 // alone, because it's legal to do this from a System V ABI function. 3045 // With opaque pointer types, we won't have enough information in LLVM 3046 // IR to determine this from the argument types, either. Best to do it 3047 // now, while we have enough information. 3048 Address DestAddr = EmitMSVAListRef(E->getArg(0)); 3049 Address SrcAddr = EmitMSVAListRef(E->getArg(1)); 3050 3051 llvm::Type *BPP = Int8PtrPtrTy; 3052 3053 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"), 3054 DestAddr.getAlignment()); 3055 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"), 3056 SrcAddr.getAlignment()); 3057 3058 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val"); 3059 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr)); 3060 } 3061 } 3062 3063 // If this is an alias for a lib function (e.g. __builtin_sin), emit 3064 // the call using the normal call path, but using the unmangled 3065 // version of the function name. 3066 if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) 3067 return emitLibraryCall(*this, FD, E, 3068 CGM.getBuiltinLibFunction(FD, BuiltinID)); 3069 3070 // If this is a predefined lib function (e.g. malloc), emit the call 3071 // using exactly the normal call path. 3072 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) 3073 return emitLibraryCall(*this, FD, E, 3074 cast<llvm::Constant>(EmitScalarExpr(E->getCallee()))); 3075 3076 // Check that a call to a target specific builtin has the correct target 3077 // features. 3078 // This is down here to avoid non-target specific builtins, however, if 3079 // generic builtins start to require generic target features then we 3080 // can move this up to the beginning of the function. 3081 checkTargetFeatures(E, FD); 3082 3083 // See if we have a target specific intrinsic. 3084 const char *Name = getContext().BuiltinInfo.getName(BuiltinID); 3085 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic; 3086 StringRef Prefix = 3087 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch()); 3088 if (!Prefix.empty()) { 3089 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name); 3090 // NOTE we dont need to perform a compatibility flag check here since the 3091 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the 3092 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier. 3093 if (IntrinsicID == Intrinsic::not_intrinsic) 3094 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name); 3095 } 3096 3097 if (IntrinsicID != Intrinsic::not_intrinsic) { 3098 SmallVector<Value*, 16> Args; 3099 3100 // Find out if any arguments are required to be integer constant 3101 // expressions. 3102 unsigned ICEArguments = 0; 3103 ASTContext::GetBuiltinTypeError Error; 3104 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 3105 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 3106 3107 Function *F = CGM.getIntrinsic(IntrinsicID); 3108 llvm::FunctionType *FTy = F->getFunctionType(); 3109 3110 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) { 3111 Value *ArgValue; 3112 // If this is a normal argument, just emit it as a scalar. 3113 if ((ICEArguments & (1 << i)) == 0) { 3114 ArgValue = EmitScalarExpr(E->getArg(i)); 3115 } else { 3116 // If this is required to be a constant, constant fold it so that we 3117 // know that the generated intrinsic gets a ConstantInt. 3118 llvm::APSInt Result; 3119 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext()); 3120 assert(IsConst && "Constant arg isn't actually constant?"); 3121 (void)IsConst; 3122 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result); 3123 } 3124 3125 // If the intrinsic arg type is different from the builtin arg type 3126 // we need to do a bit cast. 3127 llvm::Type *PTy = FTy->getParamType(i); 3128 if (PTy != ArgValue->getType()) { 3129 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) && 3130 "Must be able to losslessly bit cast to param"); 3131 ArgValue = Builder.CreateBitCast(ArgValue, PTy); 3132 } 3133 3134 Args.push_back(ArgValue); 3135 } 3136 3137 Value *V = Builder.CreateCall(F, Args); 3138 QualType BuiltinRetType = E->getType(); 3139 3140 llvm::Type *RetTy = VoidTy; 3141 if (!BuiltinRetType->isVoidType()) 3142 RetTy = ConvertType(BuiltinRetType); 3143 3144 if (RetTy != V->getType()) { 3145 assert(V->getType()->canLosslesslyBitCastTo(RetTy) && 3146 "Must be able to losslessly bit cast result type"); 3147 V = Builder.CreateBitCast(V, RetTy); 3148 } 3149 3150 return RValue::get(V); 3151 } 3152 3153 // See if we have a target specific builtin that needs to be lowered. 3154 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E)) 3155 return RValue::get(V); 3156 3157 ErrorUnsupported(E, "builtin function"); 3158 3159 // Unknown builtin, for now just dump it out and return undef. 3160 return GetUndefRValue(E->getType()); 3161 } 3162 3163 static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF, 3164 unsigned BuiltinID, const CallExpr *E, 3165 llvm::Triple::ArchType Arch) { 3166 switch (Arch) { 3167 case llvm::Triple::arm: 3168 case llvm::Triple::armeb: 3169 case llvm::Triple::thumb: 3170 case llvm::Triple::thumbeb: 3171 return CGF->EmitARMBuiltinExpr(BuiltinID, E); 3172 case llvm::Triple::aarch64: 3173 case llvm::Triple::aarch64_be: 3174 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E); 3175 case llvm::Triple::x86: 3176 case llvm::Triple::x86_64: 3177 return CGF->EmitX86BuiltinExpr(BuiltinID, E); 3178 case llvm::Triple::ppc: 3179 case llvm::Triple::ppc64: 3180 case llvm::Triple::ppc64le: 3181 return CGF->EmitPPCBuiltinExpr(BuiltinID, E); 3182 case llvm::Triple::r600: 3183 case llvm::Triple::amdgcn: 3184 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E); 3185 case llvm::Triple::systemz: 3186 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E); 3187 case llvm::Triple::nvptx: 3188 case llvm::Triple::nvptx64: 3189 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E); 3190 case llvm::Triple::wasm32: 3191 case llvm::Triple::wasm64: 3192 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E); 3193 default: 3194 return nullptr; 3195 } 3196 } 3197 3198 Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID, 3199 const CallExpr *E) { 3200 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) { 3201 assert(getContext().getAuxTargetInfo() && "Missing aux target info"); 3202 return EmitTargetArchBuiltinExpr( 3203 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E, 3204 getContext().getAuxTargetInfo()->getTriple().getArch()); 3205 } 3206 3207 return EmitTargetArchBuiltinExpr(this, BuiltinID, E, 3208 getTarget().getTriple().getArch()); 3209 } 3210 3211 static llvm::VectorType *GetNeonType(CodeGenFunction *CGF, 3212 NeonTypeFlags TypeFlags, 3213 bool V1Ty=false) { 3214 int IsQuad = TypeFlags.isQuad(); 3215 switch (TypeFlags.getEltType()) { 3216 case NeonTypeFlags::Int8: 3217 case NeonTypeFlags::Poly8: 3218 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad)); 3219 case NeonTypeFlags::Int16: 3220 case NeonTypeFlags::Poly16: 3221 case NeonTypeFlags::Float16: 3222 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad)); 3223 case NeonTypeFlags::Int32: 3224 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad)); 3225 case NeonTypeFlags::Int64: 3226 case NeonTypeFlags::Poly64: 3227 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad)); 3228 case NeonTypeFlags::Poly128: 3229 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm. 3230 // There is a lot of i128 and f128 API missing. 3231 // so we use v16i8 to represent poly128 and get pattern matched. 3232 return llvm::VectorType::get(CGF->Int8Ty, 16); 3233 case NeonTypeFlags::Float32: 3234 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad)); 3235 case NeonTypeFlags::Float64: 3236 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad)); 3237 } 3238 llvm_unreachable("Unknown vector element type!"); 3239 } 3240 3241 static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF, 3242 NeonTypeFlags IntTypeFlags) { 3243 int IsQuad = IntTypeFlags.isQuad(); 3244 switch (IntTypeFlags.getEltType()) { 3245 case NeonTypeFlags::Int32: 3246 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad)); 3247 case NeonTypeFlags::Int64: 3248 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad)); 3249 default: 3250 llvm_unreachable("Type can't be converted to floating-point!"); 3251 } 3252 } 3253 3254 Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) { 3255 unsigned nElts = V->getType()->getVectorNumElements(); 3256 Value* SV = llvm::ConstantVector::getSplat(nElts, C); 3257 return Builder.CreateShuffleVector(V, V, SV, "lane"); 3258 } 3259 3260 Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops, 3261 const char *name, 3262 unsigned shift, bool rightshift) { 3263 unsigned j = 0; 3264 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3265 ai != ae; ++ai, ++j) 3266 if (shift > 0 && shift == j) 3267 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift); 3268 else 3269 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name); 3270 3271 return Builder.CreateCall(F, Ops, name); 3272 } 3273 3274 Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty, 3275 bool neg) { 3276 int SV = cast<ConstantInt>(V)->getSExtValue(); 3277 return ConstantInt::get(Ty, neg ? -SV : SV); 3278 } 3279 3280 // \brief Right-shift a vector by a constant. 3281 Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift, 3282 llvm::Type *Ty, bool usgn, 3283 const char *name) { 3284 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 3285 3286 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue(); 3287 int EltSize = VTy->getScalarSizeInBits(); 3288 3289 Vec = Builder.CreateBitCast(Vec, Ty); 3290 3291 // lshr/ashr are undefined when the shift amount is equal to the vector 3292 // element size. 3293 if (ShiftAmt == EltSize) { 3294 if (usgn) { 3295 // Right-shifting an unsigned value by its size yields 0. 3296 return llvm::ConstantAggregateZero::get(VTy); 3297 } else { 3298 // Right-shifting a signed value by its size is equivalent 3299 // to a shift of size-1. 3300 --ShiftAmt; 3301 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt); 3302 } 3303 } 3304 3305 Shift = EmitNeonShiftVector(Shift, Ty, false); 3306 if (usgn) 3307 return Builder.CreateLShr(Vec, Shift, name); 3308 else 3309 return Builder.CreateAShr(Vec, Shift, name); 3310 } 3311 3312 enum { 3313 AddRetType = (1 << 0), 3314 Add1ArgType = (1 << 1), 3315 Add2ArgTypes = (1 << 2), 3316 3317 VectorizeRetType = (1 << 3), 3318 VectorizeArgTypes = (1 << 4), 3319 3320 InventFloatType = (1 << 5), 3321 UnsignedAlts = (1 << 6), 3322 3323 Use64BitVectors = (1 << 7), 3324 Use128BitVectors = (1 << 8), 3325 3326 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes, 3327 VectorRet = AddRetType | VectorizeRetType, 3328 VectorRetGetArgs01 = 3329 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes, 3330 FpCmpzModifiers = 3331 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType 3332 }; 3333 3334 namespace { 3335 struct NeonIntrinsicInfo { 3336 const char *NameHint; 3337 unsigned BuiltinID; 3338 unsigned LLVMIntrinsic; 3339 unsigned AltLLVMIntrinsic; 3340 unsigned TypeModifier; 3341 3342 bool operator<(unsigned RHSBuiltinID) const { 3343 return BuiltinID < RHSBuiltinID; 3344 } 3345 bool operator<(const NeonIntrinsicInfo &TE) const { 3346 return BuiltinID < TE.BuiltinID; 3347 } 3348 }; 3349 } // end anonymous namespace 3350 3351 #define NEONMAP0(NameBase) \ 3352 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 } 3353 3354 #define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \ 3355 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3356 Intrinsic::LLVMIntrinsic, 0, TypeModifier } 3357 3358 #define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \ 3359 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \ 3360 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \ 3361 TypeModifier } 3362 3363 static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = { 3364 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3365 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts), 3366 NEONMAP1(vabs_v, arm_neon_vabs, 0), 3367 NEONMAP1(vabsq_v, arm_neon_vabs, 0), 3368 NEONMAP0(vaddhn_v), 3369 NEONMAP1(vaesdq_v, arm_neon_aesd, 0), 3370 NEONMAP1(vaeseq_v, arm_neon_aese, 0), 3371 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0), 3372 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0), 3373 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType), 3374 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType), 3375 NEONMAP1(vcage_v, arm_neon_vacge, 0), 3376 NEONMAP1(vcageq_v, arm_neon_vacge, 0), 3377 NEONMAP1(vcagt_v, arm_neon_vacgt, 0), 3378 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0), 3379 NEONMAP1(vcale_v, arm_neon_vacge, 0), 3380 NEONMAP1(vcaleq_v, arm_neon_vacge, 0), 3381 NEONMAP1(vcalt_v, arm_neon_vacgt, 0), 3382 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0), 3383 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType), 3384 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType), 3385 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3386 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3387 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3388 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3389 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0), 3390 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0), 3391 NEONMAP0(vcvt_f32_v), 3392 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3393 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3394 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3395 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3396 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3397 NEONMAP0(vcvt_s32_v), 3398 NEONMAP0(vcvt_s64_v), 3399 NEONMAP0(vcvt_u32_v), 3400 NEONMAP0(vcvt_u64_v), 3401 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0), 3402 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0), 3403 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0), 3404 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0), 3405 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0), 3406 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0), 3407 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0), 3408 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0), 3409 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0), 3410 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0), 3411 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0), 3412 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0), 3413 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0), 3414 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0), 3415 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0), 3416 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0), 3417 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0), 3418 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0), 3419 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0), 3420 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0), 3421 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0), 3422 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0), 3423 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0), 3424 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0), 3425 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0), 3426 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0), 3427 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0), 3428 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0), 3429 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0), 3430 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0), 3431 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0), 3432 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0), 3433 NEONMAP0(vcvtq_f32_v), 3434 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0), 3435 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0), 3436 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0), 3437 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0), 3438 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0), 3439 NEONMAP0(vcvtq_s32_v), 3440 NEONMAP0(vcvtq_s64_v), 3441 NEONMAP0(vcvtq_u32_v), 3442 NEONMAP0(vcvtq_u64_v), 3443 NEONMAP0(vext_v), 3444 NEONMAP0(vextq_v), 3445 NEONMAP0(vfma_v), 3446 NEONMAP0(vfmaq_v), 3447 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3448 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts), 3449 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3450 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts), 3451 NEONMAP0(vld1_dup_v), 3452 NEONMAP1(vld1_v, arm_neon_vld1, 0), 3453 NEONMAP0(vld1q_dup_v), 3454 NEONMAP1(vld1q_v, arm_neon_vld1, 0), 3455 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0), 3456 NEONMAP1(vld2_v, arm_neon_vld2, 0), 3457 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0), 3458 NEONMAP1(vld2q_v, arm_neon_vld2, 0), 3459 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0), 3460 NEONMAP1(vld3_v, arm_neon_vld3, 0), 3461 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0), 3462 NEONMAP1(vld3q_v, arm_neon_vld3, 0), 3463 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0), 3464 NEONMAP1(vld4_v, arm_neon_vld4, 0), 3465 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0), 3466 NEONMAP1(vld4q_v, arm_neon_vld4, 0), 3467 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3468 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType), 3469 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType), 3470 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts), 3471 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3472 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType), 3473 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType), 3474 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts), 3475 NEONMAP0(vmovl_v), 3476 NEONMAP0(vmovn_v), 3477 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType), 3478 NEONMAP0(vmull_v), 3479 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType), 3480 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3481 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts), 3482 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType), 3483 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3484 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts), 3485 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType), 3486 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts), 3487 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts), 3488 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType), 3489 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType), 3490 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3491 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts), 3492 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0), 3493 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0), 3494 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType), 3495 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType), 3496 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType), 3497 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts), 3498 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType), 3499 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType), 3500 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType), 3501 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType), 3502 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType), 3503 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3504 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts), 3505 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3506 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3507 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts), 3508 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts), 3509 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0), 3510 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0), 3511 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3512 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts), 3513 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType), 3514 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3515 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0), 3516 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType), 3517 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType), 3518 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3519 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts), 3520 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType), 3521 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType), 3522 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType), 3523 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType), 3524 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType), 3525 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType), 3526 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType), 3527 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType), 3528 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType), 3529 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType), 3530 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType), 3531 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType), 3532 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3533 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts), 3534 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3535 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts), 3536 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3537 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0), 3538 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType), 3539 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType), 3540 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType), 3541 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0), 3542 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0), 3543 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0), 3544 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0), 3545 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0), 3546 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0), 3547 NEONMAP0(vshl_n_v), 3548 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3549 NEONMAP0(vshll_n_v), 3550 NEONMAP0(vshlq_n_v), 3551 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts), 3552 NEONMAP0(vshr_n_v), 3553 NEONMAP0(vshrn_n_v), 3554 NEONMAP0(vshrq_n_v), 3555 NEONMAP1(vst1_v, arm_neon_vst1, 0), 3556 NEONMAP1(vst1q_v, arm_neon_vst1, 0), 3557 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0), 3558 NEONMAP1(vst2_v, arm_neon_vst2, 0), 3559 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0), 3560 NEONMAP1(vst2q_v, arm_neon_vst2, 0), 3561 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0), 3562 NEONMAP1(vst3_v, arm_neon_vst3, 0), 3563 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0), 3564 NEONMAP1(vst3q_v, arm_neon_vst3, 0), 3565 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0), 3566 NEONMAP1(vst4_v, arm_neon_vst4, 0), 3567 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0), 3568 NEONMAP1(vst4q_v, arm_neon_vst4, 0), 3569 NEONMAP0(vsubhn_v), 3570 NEONMAP0(vtrn_v), 3571 NEONMAP0(vtrnq_v), 3572 NEONMAP0(vtst_v), 3573 NEONMAP0(vtstq_v), 3574 NEONMAP0(vuzp_v), 3575 NEONMAP0(vuzpq_v), 3576 NEONMAP0(vzip_v), 3577 NEONMAP0(vzipq_v) 3578 }; 3579 3580 static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = { 3581 NEONMAP1(vabs_v, aarch64_neon_abs, 0), 3582 NEONMAP1(vabsq_v, aarch64_neon_abs, 0), 3583 NEONMAP0(vaddhn_v), 3584 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0), 3585 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0), 3586 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0), 3587 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0), 3588 NEONMAP1(vcage_v, aarch64_neon_facge, 0), 3589 NEONMAP1(vcageq_v, aarch64_neon_facge, 0), 3590 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0), 3591 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0), 3592 NEONMAP1(vcale_v, aarch64_neon_facge, 0), 3593 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0), 3594 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0), 3595 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0), 3596 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType), 3597 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType), 3598 NEONMAP1(vclz_v, ctlz, Add1ArgType), 3599 NEONMAP1(vclzq_v, ctlz, Add1ArgType), 3600 NEONMAP1(vcnt_v, ctpop, Add1ArgType), 3601 NEONMAP1(vcntq_v, ctpop, Add1ArgType), 3602 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0), 3603 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0), 3604 NEONMAP0(vcvt_f32_v), 3605 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3606 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3607 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3608 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3609 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3610 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3611 NEONMAP0(vcvtq_f32_v), 3612 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3613 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0), 3614 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0), 3615 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0), 3616 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0), 3617 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0), 3618 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType), 3619 NEONMAP0(vext_v), 3620 NEONMAP0(vextq_v), 3621 NEONMAP0(vfma_v), 3622 NEONMAP0(vfmaq_v), 3623 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3624 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts), 3625 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3626 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts), 3627 NEONMAP0(vmovl_v), 3628 NEONMAP0(vmovn_v), 3629 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType), 3630 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType), 3631 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType), 3632 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3633 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts), 3634 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType), 3635 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType), 3636 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType), 3637 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3638 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts), 3639 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0), 3640 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0), 3641 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType), 3642 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType), 3643 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType), 3644 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts), 3645 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType), 3646 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType), 3647 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType), 3648 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType), 3649 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType), 3650 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3651 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts), 3652 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts), 3653 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3654 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts), 3655 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts), 3656 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0), 3657 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0), 3658 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3659 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts), 3660 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType), 3661 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3662 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0), 3663 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType), 3664 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType), 3665 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3666 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts), 3667 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3668 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts), 3669 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3670 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts), 3671 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3672 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0), 3673 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType), 3674 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType), 3675 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType), 3676 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0), 3677 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0), 3678 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0), 3679 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0), 3680 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0), 3681 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0), 3682 NEONMAP0(vshl_n_v), 3683 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3684 NEONMAP0(vshll_n_v), 3685 NEONMAP0(vshlq_n_v), 3686 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts), 3687 NEONMAP0(vshr_n_v), 3688 NEONMAP0(vshrn_n_v), 3689 NEONMAP0(vshrq_n_v), 3690 NEONMAP0(vsubhn_v), 3691 NEONMAP0(vtst_v), 3692 NEONMAP0(vtstq_v), 3693 }; 3694 3695 static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = { 3696 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType), 3697 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType), 3698 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType), 3699 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3700 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3701 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType), 3702 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType), 3703 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3704 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3705 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3706 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType), 3707 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType), 3708 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType), 3709 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType), 3710 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3711 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3712 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3713 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3714 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3715 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3716 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType), 3717 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType), 3718 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType), 3719 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType), 3720 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3721 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3722 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType), 3723 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType), 3724 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3725 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3726 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3727 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3728 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3729 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3730 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType), 3731 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType), 3732 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3733 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3734 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType), 3735 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType), 3736 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3737 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3738 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType), 3739 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType), 3740 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType), 3741 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType), 3742 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType), 3743 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType), 3744 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0), 3745 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3746 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3747 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3748 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3749 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3750 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3751 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3752 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3753 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType), 3754 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType), 3755 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3756 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3757 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3758 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3759 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3760 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3761 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3762 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3763 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType), 3764 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType), 3765 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0), 3766 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType), 3767 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType), 3768 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3769 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType), 3770 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3771 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType), 3772 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3773 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType), 3774 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3775 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType), 3776 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType), 3777 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType), 3778 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3779 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType), 3780 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors), 3781 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType), 3782 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3783 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3784 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType), 3785 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType), 3786 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors), 3787 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors), 3788 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType), 3789 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType), 3790 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors), 3791 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType), 3792 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors), 3793 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0), 3794 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType), 3795 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType), 3796 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3797 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3798 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors), 3799 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors), 3800 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType), 3801 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3802 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors), 3803 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3804 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType), 3805 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors), 3806 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType), 3807 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors), 3808 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType), 3809 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3810 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3811 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType), 3812 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType), 3813 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors), 3814 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors), 3815 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType), 3816 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType), 3817 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType), 3818 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType), 3819 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3820 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3821 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors), 3822 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors), 3823 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType), 3824 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3825 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors), 3826 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3827 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3828 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3829 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3830 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType), 3831 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType), 3832 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3833 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3834 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors), 3835 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors), 3836 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType), 3837 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType), 3838 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType), 3839 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType), 3840 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3841 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors), 3842 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType), 3843 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType), 3844 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType), 3845 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3846 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3847 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors), 3848 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors), 3849 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType), 3850 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3851 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors), 3852 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3853 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3854 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType), 3855 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType), 3856 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors), 3857 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors), 3858 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType), 3859 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType), 3860 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType), 3861 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType), 3862 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType), 3863 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType), 3864 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType), 3865 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType), 3866 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType), 3867 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType), 3868 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType), 3869 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType), 3870 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0), 3871 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0), 3872 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0), 3873 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0), 3874 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType), 3875 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType), 3876 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType), 3877 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType), 3878 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3879 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType), 3880 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors), 3881 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType), 3882 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType), 3883 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType), 3884 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3885 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType), 3886 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors), 3887 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType), 3888 }; 3889 3890 #undef NEONMAP0 3891 #undef NEONMAP1 3892 #undef NEONMAP2 3893 3894 static bool NEONSIMDIntrinsicsProvenSorted = false; 3895 3896 static bool AArch64SIMDIntrinsicsProvenSorted = false; 3897 static bool AArch64SISDIntrinsicsProvenSorted = false; 3898 3899 3900 static const NeonIntrinsicInfo * 3901 findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap, 3902 unsigned BuiltinID, bool &MapProvenSorted) { 3903 3904 #ifndef NDEBUG 3905 if (!MapProvenSorted) { 3906 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap))); 3907 MapProvenSorted = true; 3908 } 3909 #endif 3910 3911 const NeonIntrinsicInfo *Builtin = 3912 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID); 3913 3914 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID) 3915 return Builtin; 3916 3917 return nullptr; 3918 } 3919 3920 Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID, 3921 unsigned Modifier, 3922 llvm::Type *ArgType, 3923 const CallExpr *E) { 3924 int VectorSize = 0; 3925 if (Modifier & Use64BitVectors) 3926 VectorSize = 64; 3927 else if (Modifier & Use128BitVectors) 3928 VectorSize = 128; 3929 3930 // Return type. 3931 SmallVector<llvm::Type *, 3> Tys; 3932 if (Modifier & AddRetType) { 3933 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 3934 if (Modifier & VectorizeRetType) 3935 Ty = llvm::VectorType::get( 3936 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1); 3937 3938 Tys.push_back(Ty); 3939 } 3940 3941 // Arguments. 3942 if (Modifier & VectorizeArgTypes) { 3943 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1; 3944 ArgType = llvm::VectorType::get(ArgType, Elts); 3945 } 3946 3947 if (Modifier & (Add1ArgType | Add2ArgTypes)) 3948 Tys.push_back(ArgType); 3949 3950 if (Modifier & Add2ArgTypes) 3951 Tys.push_back(ArgType); 3952 3953 if (Modifier & InventFloatType) 3954 Tys.push_back(FloatTy); 3955 3956 return CGM.getIntrinsic(IntrinsicID, Tys); 3957 } 3958 3959 static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF, 3960 const NeonIntrinsicInfo &SISDInfo, 3961 SmallVectorImpl<Value *> &Ops, 3962 const CallExpr *E) { 3963 unsigned BuiltinID = SISDInfo.BuiltinID; 3964 unsigned int Int = SISDInfo.LLVMIntrinsic; 3965 unsigned Modifier = SISDInfo.TypeModifier; 3966 const char *s = SISDInfo.NameHint; 3967 3968 switch (BuiltinID) { 3969 case NEON::BI__builtin_neon_vcled_s64: 3970 case NEON::BI__builtin_neon_vcled_u64: 3971 case NEON::BI__builtin_neon_vcles_f32: 3972 case NEON::BI__builtin_neon_vcled_f64: 3973 case NEON::BI__builtin_neon_vcltd_s64: 3974 case NEON::BI__builtin_neon_vcltd_u64: 3975 case NEON::BI__builtin_neon_vclts_f32: 3976 case NEON::BI__builtin_neon_vcltd_f64: 3977 case NEON::BI__builtin_neon_vcales_f32: 3978 case NEON::BI__builtin_neon_vcaled_f64: 3979 case NEON::BI__builtin_neon_vcalts_f32: 3980 case NEON::BI__builtin_neon_vcaltd_f64: 3981 // Only one direction of comparisons actually exist, cmle is actually a cmge 3982 // with swapped operands. The table gives us the right intrinsic but we 3983 // still need to do the swap. 3984 std::swap(Ops[0], Ops[1]); 3985 break; 3986 } 3987 3988 assert(Int && "Generic code assumes a valid intrinsic"); 3989 3990 // Determine the type(s) of this overloaded AArch64 intrinsic. 3991 const Expr *Arg = E->getArg(0); 3992 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType()); 3993 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E); 3994 3995 int j = 0; 3996 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0); 3997 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end(); 3998 ai != ae; ++ai, ++j) { 3999 llvm::Type *ArgTy = ai->getType(); 4000 if (Ops[j]->getType()->getPrimitiveSizeInBits() == 4001 ArgTy->getPrimitiveSizeInBits()) 4002 continue; 4003 4004 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy()); 4005 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate 4006 // it before inserting. 4007 Ops[j] = 4008 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType()); 4009 Ops[j] = 4010 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0); 4011 } 4012 4013 Value *Result = CGF.EmitNeonCall(F, Ops, s); 4014 llvm::Type *ResultType = CGF.ConvertType(E->getType()); 4015 if (ResultType->getPrimitiveSizeInBits() < 4016 Result->getType()->getPrimitiveSizeInBits()) 4017 return CGF.Builder.CreateExtractElement(Result, C0); 4018 4019 return CGF.Builder.CreateBitCast(Result, ResultType, s); 4020 } 4021 4022 Value *CodeGenFunction::EmitCommonNeonBuiltinExpr( 4023 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic, 4024 const char *NameHint, unsigned Modifier, const CallExpr *E, 4025 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) { 4026 // Get the last argument, which specifies the vector type. 4027 llvm::APSInt NeonTypeConst; 4028 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 4029 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext())) 4030 return nullptr; 4031 4032 // Determine the type of this overloaded NEON intrinsic. 4033 NeonTypeFlags Type(NeonTypeConst.getZExtValue()); 4034 bool Usgn = Type.isUnsigned(); 4035 bool Quad = Type.isQuad(); 4036 4037 llvm::VectorType *VTy = GetNeonType(this, Type); 4038 llvm::Type *Ty = VTy; 4039 if (!Ty) 4040 return nullptr; 4041 4042 auto getAlignmentValue32 = [&](Address addr) -> Value* { 4043 return Builder.getInt32(addr.getAlignment().getQuantity()); 4044 }; 4045 4046 unsigned Int = LLVMIntrinsic; 4047 if ((Modifier & UnsignedAlts) && !Usgn) 4048 Int = AltLLVMIntrinsic; 4049 4050 switch (BuiltinID) { 4051 default: break; 4052 case NEON::BI__builtin_neon_vabs_v: 4053 case NEON::BI__builtin_neon_vabsq_v: 4054 if (VTy->getElementType()->isFloatingPointTy()) 4055 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs"); 4056 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs"); 4057 case NEON::BI__builtin_neon_vaddhn_v: { 4058 llvm::VectorType *SrcTy = 4059 llvm::VectorType::getExtendedElementVectorType(VTy); 4060 4061 // %sum = add <4 x i32> %lhs, %rhs 4062 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4063 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4064 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn"); 4065 4066 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4067 Constant *ShiftAmt = 4068 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4069 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn"); 4070 4071 // %res = trunc <4 x i32> %high to <4 x i16> 4072 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn"); 4073 } 4074 case NEON::BI__builtin_neon_vcale_v: 4075 case NEON::BI__builtin_neon_vcaleq_v: 4076 case NEON::BI__builtin_neon_vcalt_v: 4077 case NEON::BI__builtin_neon_vcaltq_v: 4078 std::swap(Ops[0], Ops[1]); 4079 LLVM_FALLTHROUGH; 4080 case NEON::BI__builtin_neon_vcage_v: 4081 case NEON::BI__builtin_neon_vcageq_v: 4082 case NEON::BI__builtin_neon_vcagt_v: 4083 case NEON::BI__builtin_neon_vcagtq_v: { 4084 llvm::Type *VecFlt = llvm::VectorType::get( 4085 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy, 4086 VTy->getNumElements()); 4087 llvm::Type *Tys[] = { VTy, VecFlt }; 4088 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4089 return EmitNeonCall(F, Ops, NameHint); 4090 } 4091 case NEON::BI__builtin_neon_vclz_v: 4092 case NEON::BI__builtin_neon_vclzq_v: 4093 // We generate target-independent intrinsic, which needs a second argument 4094 // for whether or not clz of zero is undefined; on ARM it isn't. 4095 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef())); 4096 break; 4097 case NEON::BI__builtin_neon_vcvt_f32_v: 4098 case NEON::BI__builtin_neon_vcvtq_f32_v: 4099 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4100 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad)); 4101 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 4102 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 4103 case NEON::BI__builtin_neon_vcvt_n_f32_v: 4104 case NEON::BI__builtin_neon_vcvt_n_f64_v: 4105 case NEON::BI__builtin_neon_vcvtq_n_f32_v: 4106 case NEON::BI__builtin_neon_vcvtq_n_f64_v: { 4107 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty }; 4108 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic; 4109 Function *F = CGM.getIntrinsic(Int, Tys); 4110 return EmitNeonCall(F, Ops, "vcvt_n"); 4111 } 4112 case NEON::BI__builtin_neon_vcvt_n_s32_v: 4113 case NEON::BI__builtin_neon_vcvt_n_u32_v: 4114 case NEON::BI__builtin_neon_vcvt_n_s64_v: 4115 case NEON::BI__builtin_neon_vcvt_n_u64_v: 4116 case NEON::BI__builtin_neon_vcvtq_n_s32_v: 4117 case NEON::BI__builtin_neon_vcvtq_n_u32_v: 4118 case NEON::BI__builtin_neon_vcvtq_n_s64_v: 4119 case NEON::BI__builtin_neon_vcvtq_n_u64_v: { 4120 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4121 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4122 return EmitNeonCall(F, Ops, "vcvt_n"); 4123 } 4124 case NEON::BI__builtin_neon_vcvt_s32_v: 4125 case NEON::BI__builtin_neon_vcvt_u32_v: 4126 case NEON::BI__builtin_neon_vcvt_s64_v: 4127 case NEON::BI__builtin_neon_vcvt_u64_v: 4128 case NEON::BI__builtin_neon_vcvtq_s32_v: 4129 case NEON::BI__builtin_neon_vcvtq_u32_v: 4130 case NEON::BI__builtin_neon_vcvtq_s64_v: 4131 case NEON::BI__builtin_neon_vcvtq_u64_v: { 4132 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 4133 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt") 4134 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt"); 4135 } 4136 case NEON::BI__builtin_neon_vcvta_s32_v: 4137 case NEON::BI__builtin_neon_vcvta_s64_v: 4138 case NEON::BI__builtin_neon_vcvta_u32_v: 4139 case NEON::BI__builtin_neon_vcvta_u64_v: 4140 case NEON::BI__builtin_neon_vcvtaq_s32_v: 4141 case NEON::BI__builtin_neon_vcvtaq_s64_v: 4142 case NEON::BI__builtin_neon_vcvtaq_u32_v: 4143 case NEON::BI__builtin_neon_vcvtaq_u64_v: 4144 case NEON::BI__builtin_neon_vcvtn_s32_v: 4145 case NEON::BI__builtin_neon_vcvtn_s64_v: 4146 case NEON::BI__builtin_neon_vcvtn_u32_v: 4147 case NEON::BI__builtin_neon_vcvtn_u64_v: 4148 case NEON::BI__builtin_neon_vcvtnq_s32_v: 4149 case NEON::BI__builtin_neon_vcvtnq_s64_v: 4150 case NEON::BI__builtin_neon_vcvtnq_u32_v: 4151 case NEON::BI__builtin_neon_vcvtnq_u64_v: 4152 case NEON::BI__builtin_neon_vcvtp_s32_v: 4153 case NEON::BI__builtin_neon_vcvtp_s64_v: 4154 case NEON::BI__builtin_neon_vcvtp_u32_v: 4155 case NEON::BI__builtin_neon_vcvtp_u64_v: 4156 case NEON::BI__builtin_neon_vcvtpq_s32_v: 4157 case NEON::BI__builtin_neon_vcvtpq_s64_v: 4158 case NEON::BI__builtin_neon_vcvtpq_u32_v: 4159 case NEON::BI__builtin_neon_vcvtpq_u64_v: 4160 case NEON::BI__builtin_neon_vcvtm_s32_v: 4161 case NEON::BI__builtin_neon_vcvtm_s64_v: 4162 case NEON::BI__builtin_neon_vcvtm_u32_v: 4163 case NEON::BI__builtin_neon_vcvtm_u64_v: 4164 case NEON::BI__builtin_neon_vcvtmq_s32_v: 4165 case NEON::BI__builtin_neon_vcvtmq_s64_v: 4166 case NEON::BI__builtin_neon_vcvtmq_u32_v: 4167 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 4168 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 4169 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint); 4170 } 4171 case NEON::BI__builtin_neon_vext_v: 4172 case NEON::BI__builtin_neon_vextq_v: { 4173 int CV = cast<ConstantInt>(Ops[2])->getSExtValue(); 4174 SmallVector<uint32_t, 16> Indices; 4175 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4176 Indices.push_back(i+CV); 4177 4178 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4179 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4180 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext"); 4181 } 4182 case NEON::BI__builtin_neon_vfma_v: 4183 case NEON::BI__builtin_neon_vfmaq_v: { 4184 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 4185 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4186 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4187 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4188 4189 // NEON intrinsic puts accumulator first, unlike the LLVM fma. 4190 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 4191 } 4192 case NEON::BI__builtin_neon_vld1_v: 4193 case NEON::BI__builtin_neon_vld1q_v: { 4194 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4195 Ops.push_back(getAlignmentValue32(PtrOp0)); 4196 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1"); 4197 } 4198 case NEON::BI__builtin_neon_vld2_v: 4199 case NEON::BI__builtin_neon_vld2q_v: 4200 case NEON::BI__builtin_neon_vld3_v: 4201 case NEON::BI__builtin_neon_vld3q_v: 4202 case NEON::BI__builtin_neon_vld4_v: 4203 case NEON::BI__builtin_neon_vld4q_v: { 4204 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4205 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4206 Value *Align = getAlignmentValue32(PtrOp1); 4207 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint); 4208 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4209 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4210 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4211 } 4212 case NEON::BI__builtin_neon_vld1_dup_v: 4213 case NEON::BI__builtin_neon_vld1q_dup_v: { 4214 Value *V = UndefValue::get(Ty); 4215 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 4216 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty); 4217 LoadInst *Ld = Builder.CreateLoad(PtrOp0); 4218 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 4219 Ops[0] = Builder.CreateInsertElement(V, Ld, CI); 4220 return EmitNeonSplat(Ops[0], CI); 4221 } 4222 case NEON::BI__builtin_neon_vld2_lane_v: 4223 case NEON::BI__builtin_neon_vld2q_lane_v: 4224 case NEON::BI__builtin_neon_vld3_lane_v: 4225 case NEON::BI__builtin_neon_vld3q_lane_v: 4226 case NEON::BI__builtin_neon_vld4_lane_v: 4227 case NEON::BI__builtin_neon_vld4q_lane_v: { 4228 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 4229 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys); 4230 for (unsigned I = 2; I < Ops.size() - 1; ++I) 4231 Ops[I] = Builder.CreateBitCast(Ops[I], Ty); 4232 Ops.push_back(getAlignmentValue32(PtrOp1)); 4233 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint); 4234 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 4235 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4236 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 4237 } 4238 case NEON::BI__builtin_neon_vmovl_v: { 4239 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy); 4240 Ops[0] = Builder.CreateBitCast(Ops[0], DTy); 4241 if (Usgn) 4242 return Builder.CreateZExt(Ops[0], Ty, "vmovl"); 4243 return Builder.CreateSExt(Ops[0], Ty, "vmovl"); 4244 } 4245 case NEON::BI__builtin_neon_vmovn_v: { 4246 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4247 Ops[0] = Builder.CreateBitCast(Ops[0], QTy); 4248 return Builder.CreateTrunc(Ops[0], Ty, "vmovn"); 4249 } 4250 case NEON::BI__builtin_neon_vmull_v: 4251 // FIXME: the integer vmull operations could be emitted in terms of pure 4252 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of 4253 // hoisting the exts outside loops. Until global ISel comes along that can 4254 // see through such movement this leads to bad CodeGen. So we need an 4255 // intrinsic for now. 4256 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls; 4257 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int; 4258 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 4259 case NEON::BI__builtin_neon_vpadal_v: 4260 case NEON::BI__builtin_neon_vpadalq_v: { 4261 // The source operand type has twice as many elements of half the size. 4262 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4263 llvm::Type *EltTy = 4264 llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4265 llvm::Type *NarrowTy = 4266 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4267 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4268 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint); 4269 } 4270 case NEON::BI__builtin_neon_vpaddl_v: 4271 case NEON::BI__builtin_neon_vpaddlq_v: { 4272 // The source operand type has twice as many elements of half the size. 4273 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits(); 4274 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2); 4275 llvm::Type *NarrowTy = 4276 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2); 4277 llvm::Type *Tys[2] = { Ty, NarrowTy }; 4278 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl"); 4279 } 4280 case NEON::BI__builtin_neon_vqdmlal_v: 4281 case NEON::BI__builtin_neon_vqdmlsl_v: { 4282 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end()); 4283 Ops[1] = 4284 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal"); 4285 Ops.resize(2); 4286 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint); 4287 } 4288 case NEON::BI__builtin_neon_vqshl_n_v: 4289 case NEON::BI__builtin_neon_vqshlq_n_v: 4290 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n", 4291 1, false); 4292 case NEON::BI__builtin_neon_vqshlu_n_v: 4293 case NEON::BI__builtin_neon_vqshluq_n_v: 4294 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n", 4295 1, false); 4296 case NEON::BI__builtin_neon_vrecpe_v: 4297 case NEON::BI__builtin_neon_vrecpeq_v: 4298 case NEON::BI__builtin_neon_vrsqrte_v: 4299 case NEON::BI__builtin_neon_vrsqrteq_v: 4300 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic; 4301 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint); 4302 4303 case NEON::BI__builtin_neon_vrshr_n_v: 4304 case NEON::BI__builtin_neon_vrshrq_n_v: 4305 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n", 4306 1, true); 4307 case NEON::BI__builtin_neon_vshl_n_v: 4308 case NEON::BI__builtin_neon_vshlq_n_v: 4309 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false); 4310 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1], 4311 "vshl_n"); 4312 case NEON::BI__builtin_neon_vshll_n_v: { 4313 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy); 4314 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4315 if (Usgn) 4316 Ops[0] = Builder.CreateZExt(Ops[0], VTy); 4317 else 4318 Ops[0] = Builder.CreateSExt(Ops[0], VTy); 4319 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false); 4320 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n"); 4321 } 4322 case NEON::BI__builtin_neon_vshrn_n_v: { 4323 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy); 4324 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4325 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false); 4326 if (Usgn) 4327 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]); 4328 else 4329 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]); 4330 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n"); 4331 } 4332 case NEON::BI__builtin_neon_vshr_n_v: 4333 case NEON::BI__builtin_neon_vshrq_n_v: 4334 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n"); 4335 case NEON::BI__builtin_neon_vst1_v: 4336 case NEON::BI__builtin_neon_vst1q_v: 4337 case NEON::BI__builtin_neon_vst2_v: 4338 case NEON::BI__builtin_neon_vst2q_v: 4339 case NEON::BI__builtin_neon_vst3_v: 4340 case NEON::BI__builtin_neon_vst3q_v: 4341 case NEON::BI__builtin_neon_vst4_v: 4342 case NEON::BI__builtin_neon_vst4q_v: 4343 case NEON::BI__builtin_neon_vst2_lane_v: 4344 case NEON::BI__builtin_neon_vst2q_lane_v: 4345 case NEON::BI__builtin_neon_vst3_lane_v: 4346 case NEON::BI__builtin_neon_vst3q_lane_v: 4347 case NEON::BI__builtin_neon_vst4_lane_v: 4348 case NEON::BI__builtin_neon_vst4q_lane_v: { 4349 llvm::Type *Tys[] = {Int8PtrTy, Ty}; 4350 Ops.push_back(getAlignmentValue32(PtrOp0)); 4351 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 4352 } 4353 case NEON::BI__builtin_neon_vsubhn_v: { 4354 llvm::VectorType *SrcTy = 4355 llvm::VectorType::getExtendedElementVectorType(VTy); 4356 4357 // %sum = add <4 x i32> %lhs, %rhs 4358 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy); 4359 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy); 4360 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn"); 4361 4362 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16> 4363 Constant *ShiftAmt = 4364 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2); 4365 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn"); 4366 4367 // %res = trunc <4 x i32> %high to <4 x i16> 4368 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn"); 4369 } 4370 case NEON::BI__builtin_neon_vtrn_v: 4371 case NEON::BI__builtin_neon_vtrnq_v: { 4372 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4373 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4374 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4375 Value *SV = nullptr; 4376 4377 for (unsigned vi = 0; vi != 2; ++vi) { 4378 SmallVector<uint32_t, 16> Indices; 4379 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4380 Indices.push_back(i+vi); 4381 Indices.push_back(i+e+vi); 4382 } 4383 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4384 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 4385 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4386 } 4387 return SV; 4388 } 4389 case NEON::BI__builtin_neon_vtst_v: 4390 case NEON::BI__builtin_neon_vtstq_v: { 4391 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 4392 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4393 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 4394 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 4395 ConstantAggregateZero::get(Ty)); 4396 return Builder.CreateSExt(Ops[0], Ty, "vtst"); 4397 } 4398 case NEON::BI__builtin_neon_vuzp_v: 4399 case NEON::BI__builtin_neon_vuzpq_v: { 4400 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4401 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4402 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4403 Value *SV = nullptr; 4404 4405 for (unsigned vi = 0; vi != 2; ++vi) { 4406 SmallVector<uint32_t, 16> Indices; 4407 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 4408 Indices.push_back(2*i+vi); 4409 4410 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4411 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 4412 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4413 } 4414 return SV; 4415 } 4416 case NEON::BI__builtin_neon_vzip_v: 4417 case NEON::BI__builtin_neon_vzipq_v: { 4418 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 4419 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 4420 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 4421 Value *SV = nullptr; 4422 4423 for (unsigned vi = 0; vi != 2; ++vi) { 4424 SmallVector<uint32_t, 16> Indices; 4425 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 4426 Indices.push_back((i + vi*e) >> 1); 4427 Indices.push_back(((i + vi*e) >> 1)+e); 4428 } 4429 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 4430 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 4431 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 4432 } 4433 return SV; 4434 } 4435 } 4436 4437 assert(Int && "Expected valid intrinsic number"); 4438 4439 // Determine the type(s) of this overloaded AArch64 intrinsic. 4440 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E); 4441 4442 Value *Result = EmitNeonCall(F, Ops, NameHint); 4443 llvm::Type *ResultType = ConvertType(E->getType()); 4444 // AArch64 intrinsic one-element vector type cast to 4445 // scalar type expected by the builtin 4446 return Builder.CreateBitCast(Result, ResultType, NameHint); 4447 } 4448 4449 Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr( 4450 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp, 4451 const CmpInst::Predicate Ip, const Twine &Name) { 4452 llvm::Type *OTy = Op->getType(); 4453 4454 // FIXME: this is utterly horrific. We should not be looking at previous 4455 // codegen context to find out what needs doing. Unfortunately TableGen 4456 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32 4457 // (etc). 4458 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op)) 4459 OTy = BI->getOperand(0)->getType(); 4460 4461 Op = Builder.CreateBitCast(Op, OTy); 4462 if (OTy->getScalarType()->isFloatingPointTy()) { 4463 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy)); 4464 } else { 4465 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy)); 4466 } 4467 return Builder.CreateSExt(Op, Ty, Name); 4468 } 4469 4470 static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops, 4471 Value *ExtOp, Value *IndexOp, 4472 llvm::Type *ResTy, unsigned IntID, 4473 const char *Name) { 4474 SmallVector<Value *, 2> TblOps; 4475 if (ExtOp) 4476 TblOps.push_back(ExtOp); 4477 4478 // Build a vector containing sequential number like (0, 1, 2, ..., 15) 4479 SmallVector<uint32_t, 16> Indices; 4480 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType()); 4481 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) { 4482 Indices.push_back(2*i); 4483 Indices.push_back(2*i+1); 4484 } 4485 4486 int PairPos = 0, End = Ops.size() - 1; 4487 while (PairPos < End) { 4488 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4489 Ops[PairPos+1], Indices, 4490 Name)); 4491 PairPos += 2; 4492 } 4493 4494 // If there's an odd number of 64-bit lookup table, fill the high 64-bit 4495 // of the 128-bit lookup table with zero. 4496 if (PairPos == End) { 4497 Value *ZeroTbl = ConstantAggregateZero::get(TblTy); 4498 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos], 4499 ZeroTbl, Indices, Name)); 4500 } 4501 4502 Function *TblF; 4503 TblOps.push_back(IndexOp); 4504 TblF = CGF.CGM.getIntrinsic(IntID, ResTy); 4505 4506 return CGF.EmitNeonCall(TblF, TblOps, Name); 4507 } 4508 4509 Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) { 4510 unsigned Value; 4511 switch (BuiltinID) { 4512 default: 4513 return nullptr; 4514 case ARM::BI__builtin_arm_nop: 4515 Value = 0; 4516 break; 4517 case ARM::BI__builtin_arm_yield: 4518 case ARM::BI__yield: 4519 Value = 1; 4520 break; 4521 case ARM::BI__builtin_arm_wfe: 4522 case ARM::BI__wfe: 4523 Value = 2; 4524 break; 4525 case ARM::BI__builtin_arm_wfi: 4526 case ARM::BI__wfi: 4527 Value = 3; 4528 break; 4529 case ARM::BI__builtin_arm_sev: 4530 case ARM::BI__sev: 4531 Value = 4; 4532 break; 4533 case ARM::BI__builtin_arm_sevl: 4534 case ARM::BI__sevl: 4535 Value = 5; 4536 break; 4537 } 4538 4539 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint), 4540 llvm::ConstantInt::get(Int32Ty, Value)); 4541 } 4542 4543 // Generates the IR for the read/write special register builtin, 4544 // ValueType is the type of the value that is to be written or read, 4545 // RegisterType is the type of the register being written to or read from. 4546 static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF, 4547 const CallExpr *E, 4548 llvm::Type *RegisterType, 4549 llvm::Type *ValueType, 4550 bool IsRead, 4551 StringRef SysReg = "") { 4552 // write and register intrinsics only support 32 and 64 bit operations. 4553 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64)) 4554 && "Unsupported size for register."); 4555 4556 CodeGen::CGBuilderTy &Builder = CGF.Builder; 4557 CodeGen::CodeGenModule &CGM = CGF.CGM; 4558 LLVMContext &Context = CGM.getLLVMContext(); 4559 4560 if (SysReg.empty()) { 4561 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts(); 4562 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString(); 4563 } 4564 4565 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) }; 4566 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops); 4567 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName); 4568 4569 llvm::Type *Types[] = { RegisterType }; 4570 4571 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32); 4572 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64)) 4573 && "Can't fit 64-bit value in 32-bit register"); 4574 4575 if (IsRead) { 4576 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types); 4577 llvm::Value *Call = Builder.CreateCall(F, Metadata); 4578 4579 if (MixedTypes) 4580 // Read into 64 bit register and then truncate result to 32 bit. 4581 return Builder.CreateTrunc(Call, ValueType); 4582 4583 if (ValueType->isPointerTy()) 4584 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*). 4585 return Builder.CreateIntToPtr(Call, ValueType); 4586 4587 return Call; 4588 } 4589 4590 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types); 4591 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1)); 4592 if (MixedTypes) { 4593 // Extend 32 bit write value to 64 bit to pass to write. 4594 ArgValue = Builder.CreateZExt(ArgValue, RegisterType); 4595 return Builder.CreateCall(F, { Metadata, ArgValue }); 4596 } 4597 4598 if (ValueType->isPointerTy()) { 4599 // Have VoidPtrTy ArgValue but want to return an i32/i64. 4600 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType); 4601 return Builder.CreateCall(F, { Metadata, ArgValue }); 4602 } 4603 4604 return Builder.CreateCall(F, { Metadata, ArgValue }); 4605 } 4606 4607 /// Return true if BuiltinID is an overloaded Neon intrinsic with an extra 4608 /// argument that specifies the vector type. 4609 static bool HasExtraNeonArgument(unsigned BuiltinID) { 4610 switch (BuiltinID) { 4611 default: break; 4612 case NEON::BI__builtin_neon_vget_lane_i8: 4613 case NEON::BI__builtin_neon_vget_lane_i16: 4614 case NEON::BI__builtin_neon_vget_lane_i32: 4615 case NEON::BI__builtin_neon_vget_lane_i64: 4616 case NEON::BI__builtin_neon_vget_lane_f32: 4617 case NEON::BI__builtin_neon_vgetq_lane_i8: 4618 case NEON::BI__builtin_neon_vgetq_lane_i16: 4619 case NEON::BI__builtin_neon_vgetq_lane_i32: 4620 case NEON::BI__builtin_neon_vgetq_lane_i64: 4621 case NEON::BI__builtin_neon_vgetq_lane_f32: 4622 case NEON::BI__builtin_neon_vset_lane_i8: 4623 case NEON::BI__builtin_neon_vset_lane_i16: 4624 case NEON::BI__builtin_neon_vset_lane_i32: 4625 case NEON::BI__builtin_neon_vset_lane_i64: 4626 case NEON::BI__builtin_neon_vset_lane_f32: 4627 case NEON::BI__builtin_neon_vsetq_lane_i8: 4628 case NEON::BI__builtin_neon_vsetq_lane_i16: 4629 case NEON::BI__builtin_neon_vsetq_lane_i32: 4630 case NEON::BI__builtin_neon_vsetq_lane_i64: 4631 case NEON::BI__builtin_neon_vsetq_lane_f32: 4632 case NEON::BI__builtin_neon_vsha1h_u32: 4633 case NEON::BI__builtin_neon_vsha1cq_u32: 4634 case NEON::BI__builtin_neon_vsha1pq_u32: 4635 case NEON::BI__builtin_neon_vsha1mq_u32: 4636 case ARM::BI_MoveToCoprocessor: 4637 case ARM::BI_MoveToCoprocessor2: 4638 return false; 4639 } 4640 return true; 4641 } 4642 4643 Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, 4644 const CallExpr *E) { 4645 if (auto Hint = GetValueForARMHint(BuiltinID)) 4646 return Hint; 4647 4648 if (BuiltinID == ARM::BI__emit) { 4649 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb; 4650 llvm::FunctionType *FTy = 4651 llvm::FunctionType::get(VoidTy, /*Variadic=*/false); 4652 4653 APSInt Value; 4654 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext())) 4655 llvm_unreachable("Sema will ensure that the parameter is constant"); 4656 4657 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue(); 4658 4659 llvm::InlineAsm *Emit = 4660 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "", 4661 /*SideEffects=*/true) 4662 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "", 4663 /*SideEffects=*/true); 4664 4665 return Builder.CreateCall(Emit); 4666 } 4667 4668 if (BuiltinID == ARM::BI__builtin_arm_dbg) { 4669 Value *Option = EmitScalarExpr(E->getArg(0)); 4670 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option); 4671 } 4672 4673 if (BuiltinID == ARM::BI__builtin_arm_prefetch) { 4674 Value *Address = EmitScalarExpr(E->getArg(0)); 4675 Value *RW = EmitScalarExpr(E->getArg(1)); 4676 Value *IsData = EmitScalarExpr(E->getArg(2)); 4677 4678 // Locality is not supported on ARM target 4679 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3); 4680 4681 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 4682 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 4683 } 4684 4685 if (BuiltinID == ARM::BI__builtin_arm_rbit) { 4686 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 4687 return Builder.CreateCall( 4688 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 4689 } 4690 4691 if (BuiltinID == ARM::BI__clear_cache) { 4692 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 4693 const FunctionDecl *FD = E->getDirectCallee(); 4694 Value *Ops[2]; 4695 for (unsigned i = 0; i < 2; i++) 4696 Ops[i] = EmitScalarExpr(E->getArg(i)); 4697 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 4698 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 4699 StringRef Name = FD->getName(); 4700 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 4701 } 4702 4703 if (BuiltinID == ARM::BI__builtin_arm_mcrr || 4704 BuiltinID == ARM::BI__builtin_arm_mcrr2) { 4705 Function *F; 4706 4707 switch (BuiltinID) { 4708 default: llvm_unreachable("unexpected builtin"); 4709 case ARM::BI__builtin_arm_mcrr: 4710 F = CGM.getIntrinsic(Intrinsic::arm_mcrr); 4711 break; 4712 case ARM::BI__builtin_arm_mcrr2: 4713 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2); 4714 break; 4715 } 4716 4717 // MCRR{2} instruction has 5 operands but 4718 // the intrinsic has 4 because Rt and Rt2 4719 // are represented as a single unsigned 64 4720 // bit integer in the intrinsic definition 4721 // but internally it's represented as 2 32 4722 // bit integers. 4723 4724 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4725 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4726 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2)); 4727 Value *CRm = EmitScalarExpr(E->getArg(3)); 4728 4729 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4730 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty); 4731 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1); 4732 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty); 4733 4734 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm}); 4735 } 4736 4737 if (BuiltinID == ARM::BI__builtin_arm_mrrc || 4738 BuiltinID == ARM::BI__builtin_arm_mrrc2) { 4739 Function *F; 4740 4741 switch (BuiltinID) { 4742 default: llvm_unreachable("unexpected builtin"); 4743 case ARM::BI__builtin_arm_mrrc: 4744 F = CGM.getIntrinsic(Intrinsic::arm_mrrc); 4745 break; 4746 case ARM::BI__builtin_arm_mrrc2: 4747 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2); 4748 break; 4749 } 4750 4751 Value *Coproc = EmitScalarExpr(E->getArg(0)); 4752 Value *Opc1 = EmitScalarExpr(E->getArg(1)); 4753 Value *CRm = EmitScalarExpr(E->getArg(2)); 4754 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm}); 4755 4756 // Returns an unsigned 64 bit integer, represented 4757 // as two 32 bit integers. 4758 4759 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1); 4760 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0); 4761 Rt = Builder.CreateZExt(Rt, Int64Ty); 4762 Rt1 = Builder.CreateZExt(Rt1, Int64Ty); 4763 4764 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32); 4765 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true); 4766 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1); 4767 4768 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType())); 4769 } 4770 4771 if (BuiltinID == ARM::BI__builtin_arm_ldrexd || 4772 ((BuiltinID == ARM::BI__builtin_arm_ldrex || 4773 BuiltinID == ARM::BI__builtin_arm_ldaex) && 4774 getContext().getTypeSize(E->getType()) == 64) || 4775 BuiltinID == ARM::BI__ldrexd) { 4776 Function *F; 4777 4778 switch (BuiltinID) { 4779 default: llvm_unreachable("unexpected builtin"); 4780 case ARM::BI__builtin_arm_ldaex: 4781 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd); 4782 break; 4783 case ARM::BI__builtin_arm_ldrexd: 4784 case ARM::BI__builtin_arm_ldrex: 4785 case ARM::BI__ldrexd: 4786 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd); 4787 break; 4788 } 4789 4790 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 4791 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 4792 "ldrexd"); 4793 4794 Value *Val0 = Builder.CreateExtractValue(Val, 1); 4795 Value *Val1 = Builder.CreateExtractValue(Val, 0); 4796 Val0 = Builder.CreateZExt(Val0, Int64Ty); 4797 Val1 = Builder.CreateZExt(Val1, Int64Ty); 4798 4799 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32); 4800 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 4801 Val = Builder.CreateOr(Val, Val1); 4802 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 4803 } 4804 4805 if (BuiltinID == ARM::BI__builtin_arm_ldrex || 4806 BuiltinID == ARM::BI__builtin_arm_ldaex) { 4807 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 4808 4809 QualType Ty = E->getType(); 4810 llvm::Type *RealResTy = ConvertType(Ty); 4811 llvm::Type *PtrTy = llvm::IntegerType::get( 4812 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 4813 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 4814 4815 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex 4816 ? Intrinsic::arm_ldaex 4817 : Intrinsic::arm_ldrex, 4818 PtrTy); 4819 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex"); 4820 4821 if (RealResTy->isPointerTy()) 4822 return Builder.CreateIntToPtr(Val, RealResTy); 4823 else { 4824 llvm::Type *IntResTy = llvm::IntegerType::get( 4825 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 4826 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 4827 return Builder.CreateBitCast(Val, RealResTy); 4828 } 4829 } 4830 4831 if (BuiltinID == ARM::BI__builtin_arm_strexd || 4832 ((BuiltinID == ARM::BI__builtin_arm_stlex || 4833 BuiltinID == ARM::BI__builtin_arm_strex) && 4834 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) { 4835 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4836 ? Intrinsic::arm_stlexd 4837 : Intrinsic::arm_strexd); 4838 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty); 4839 4840 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 4841 Value *Val = EmitScalarExpr(E->getArg(0)); 4842 Builder.CreateStore(Val, Tmp); 4843 4844 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy)); 4845 Val = Builder.CreateLoad(LdPtr); 4846 4847 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 4848 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 4849 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy); 4850 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd"); 4851 } 4852 4853 if (BuiltinID == ARM::BI__builtin_arm_strex || 4854 BuiltinID == ARM::BI__builtin_arm_stlex) { 4855 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 4856 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 4857 4858 QualType Ty = E->getArg(0)->getType(); 4859 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 4860 getContext().getTypeSize(Ty)); 4861 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 4862 4863 if (StoreVal->getType()->isPointerTy()) 4864 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty); 4865 else { 4866 llvm::Type *IntTy = llvm::IntegerType::get( 4867 getLLVMContext(), 4868 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 4869 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 4870 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty); 4871 } 4872 4873 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex 4874 ? Intrinsic::arm_stlex 4875 : Intrinsic::arm_strex, 4876 StoreAddr->getType()); 4877 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex"); 4878 } 4879 4880 switch (BuiltinID) { 4881 case ARM::BI__iso_volatile_load8: 4882 case ARM::BI__iso_volatile_load16: 4883 case ARM::BI__iso_volatile_load32: 4884 case ARM::BI__iso_volatile_load64: { 4885 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4886 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4887 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy); 4888 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4889 LoadSize.getQuantity() * 8); 4890 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4891 llvm::LoadInst *Load = 4892 Builder.CreateAlignedLoad(Ptr, LoadSize); 4893 Load->setVolatile(true); 4894 return Load; 4895 } 4896 case ARM::BI__iso_volatile_store8: 4897 case ARM::BI__iso_volatile_store16: 4898 case ARM::BI__iso_volatile_store32: 4899 case ARM::BI__iso_volatile_store64: { 4900 Value *Ptr = EmitScalarExpr(E->getArg(0)); 4901 Value *Value = EmitScalarExpr(E->getArg(1)); 4902 QualType ElTy = E->getArg(0)->getType()->getPointeeType(); 4903 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy); 4904 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(), 4905 StoreSize.getQuantity() * 8); 4906 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo()); 4907 llvm::StoreInst *Store = 4908 Builder.CreateAlignedStore(Value, Ptr, 4909 StoreSize); 4910 Store->setVolatile(true); 4911 return Store; 4912 } 4913 } 4914 4915 if (BuiltinID == ARM::BI__builtin_arm_clrex) { 4916 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex); 4917 return Builder.CreateCall(F); 4918 } 4919 4920 // CRC32 4921 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 4922 switch (BuiltinID) { 4923 case ARM::BI__builtin_arm_crc32b: 4924 CRCIntrinsicID = Intrinsic::arm_crc32b; break; 4925 case ARM::BI__builtin_arm_crc32cb: 4926 CRCIntrinsicID = Intrinsic::arm_crc32cb; break; 4927 case ARM::BI__builtin_arm_crc32h: 4928 CRCIntrinsicID = Intrinsic::arm_crc32h; break; 4929 case ARM::BI__builtin_arm_crc32ch: 4930 CRCIntrinsicID = Intrinsic::arm_crc32ch; break; 4931 case ARM::BI__builtin_arm_crc32w: 4932 case ARM::BI__builtin_arm_crc32d: 4933 CRCIntrinsicID = Intrinsic::arm_crc32w; break; 4934 case ARM::BI__builtin_arm_crc32cw: 4935 case ARM::BI__builtin_arm_crc32cd: 4936 CRCIntrinsicID = Intrinsic::arm_crc32cw; break; 4937 } 4938 4939 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 4940 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 4941 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 4942 4943 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w 4944 // intrinsics, hence we need different codegen for these cases. 4945 if (BuiltinID == ARM::BI__builtin_arm_crc32d || 4946 BuiltinID == ARM::BI__builtin_arm_crc32cd) { 4947 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32); 4948 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty); 4949 Value *Arg1b = Builder.CreateLShr(Arg1, C1); 4950 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty); 4951 4952 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4953 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a}); 4954 return Builder.CreateCall(F, {Res, Arg1b}); 4955 } else { 4956 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty); 4957 4958 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 4959 return Builder.CreateCall(F, {Arg0, Arg1}); 4960 } 4961 } 4962 4963 if (BuiltinID == ARM::BI__builtin_arm_rsr || 4964 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4965 BuiltinID == ARM::BI__builtin_arm_rsrp || 4966 BuiltinID == ARM::BI__builtin_arm_wsr || 4967 BuiltinID == ARM::BI__builtin_arm_wsr64 || 4968 BuiltinID == ARM::BI__builtin_arm_wsrp) { 4969 4970 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr || 4971 BuiltinID == ARM::BI__builtin_arm_rsr64 || 4972 BuiltinID == ARM::BI__builtin_arm_rsrp; 4973 4974 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp || 4975 BuiltinID == ARM::BI__builtin_arm_wsrp; 4976 4977 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 || 4978 BuiltinID == ARM::BI__builtin_arm_wsr64; 4979 4980 llvm::Type *ValueType; 4981 llvm::Type *RegisterType; 4982 if (IsPointerBuiltin) { 4983 ValueType = VoidPtrTy; 4984 RegisterType = Int32Ty; 4985 } else if (Is64Bit) { 4986 ValueType = RegisterType = Int64Ty; 4987 } else { 4988 ValueType = RegisterType = Int32Ty; 4989 } 4990 4991 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 4992 } 4993 4994 // Find out if any arguments are required to be integer constant 4995 // expressions. 4996 unsigned ICEArguments = 0; 4997 ASTContext::GetBuiltinTypeError Error; 4998 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 4999 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 5000 5001 auto getAlignmentValue32 = [&](Address addr) -> Value* { 5002 return Builder.getInt32(addr.getAlignment().getQuantity()); 5003 }; 5004 5005 Address PtrOp0 = Address::invalid(); 5006 Address PtrOp1 = Address::invalid(); 5007 SmallVector<Value*, 4> Ops; 5008 bool HasExtraArg = HasExtraNeonArgument(BuiltinID); 5009 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0); 5010 for (unsigned i = 0, e = NumArgs; i != e; i++) { 5011 if (i == 0) { 5012 switch (BuiltinID) { 5013 case NEON::BI__builtin_neon_vld1_v: 5014 case NEON::BI__builtin_neon_vld1q_v: 5015 case NEON::BI__builtin_neon_vld1q_lane_v: 5016 case NEON::BI__builtin_neon_vld1_lane_v: 5017 case NEON::BI__builtin_neon_vld1_dup_v: 5018 case NEON::BI__builtin_neon_vld1q_dup_v: 5019 case NEON::BI__builtin_neon_vst1_v: 5020 case NEON::BI__builtin_neon_vst1q_v: 5021 case NEON::BI__builtin_neon_vst1q_lane_v: 5022 case NEON::BI__builtin_neon_vst1_lane_v: 5023 case NEON::BI__builtin_neon_vst2_v: 5024 case NEON::BI__builtin_neon_vst2q_v: 5025 case NEON::BI__builtin_neon_vst2_lane_v: 5026 case NEON::BI__builtin_neon_vst2q_lane_v: 5027 case NEON::BI__builtin_neon_vst3_v: 5028 case NEON::BI__builtin_neon_vst3q_v: 5029 case NEON::BI__builtin_neon_vst3_lane_v: 5030 case NEON::BI__builtin_neon_vst3q_lane_v: 5031 case NEON::BI__builtin_neon_vst4_v: 5032 case NEON::BI__builtin_neon_vst4q_v: 5033 case NEON::BI__builtin_neon_vst4_lane_v: 5034 case NEON::BI__builtin_neon_vst4q_lane_v: 5035 // Get the alignment for the argument in addition to the value; 5036 // we'll use it later. 5037 PtrOp0 = EmitPointerWithAlignment(E->getArg(0)); 5038 Ops.push_back(PtrOp0.getPointer()); 5039 continue; 5040 } 5041 } 5042 if (i == 1) { 5043 switch (BuiltinID) { 5044 case NEON::BI__builtin_neon_vld2_v: 5045 case NEON::BI__builtin_neon_vld2q_v: 5046 case NEON::BI__builtin_neon_vld3_v: 5047 case NEON::BI__builtin_neon_vld3q_v: 5048 case NEON::BI__builtin_neon_vld4_v: 5049 case NEON::BI__builtin_neon_vld4q_v: 5050 case NEON::BI__builtin_neon_vld2_lane_v: 5051 case NEON::BI__builtin_neon_vld2q_lane_v: 5052 case NEON::BI__builtin_neon_vld3_lane_v: 5053 case NEON::BI__builtin_neon_vld3q_lane_v: 5054 case NEON::BI__builtin_neon_vld4_lane_v: 5055 case NEON::BI__builtin_neon_vld4q_lane_v: 5056 case NEON::BI__builtin_neon_vld2_dup_v: 5057 case NEON::BI__builtin_neon_vld3_dup_v: 5058 case NEON::BI__builtin_neon_vld4_dup_v: 5059 // Get the alignment for the argument in addition to the value; 5060 // we'll use it later. 5061 PtrOp1 = EmitPointerWithAlignment(E->getArg(1)); 5062 Ops.push_back(PtrOp1.getPointer()); 5063 continue; 5064 } 5065 } 5066 5067 if ((ICEArguments & (1 << i)) == 0) { 5068 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5069 } else { 5070 // If this is required to be a constant, constant fold it so that we know 5071 // that the generated intrinsic gets a ConstantInt. 5072 llvm::APSInt Result; 5073 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5074 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 5075 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5076 } 5077 } 5078 5079 switch (BuiltinID) { 5080 default: break; 5081 5082 case NEON::BI__builtin_neon_vget_lane_i8: 5083 case NEON::BI__builtin_neon_vget_lane_i16: 5084 case NEON::BI__builtin_neon_vget_lane_i32: 5085 case NEON::BI__builtin_neon_vget_lane_i64: 5086 case NEON::BI__builtin_neon_vget_lane_f32: 5087 case NEON::BI__builtin_neon_vgetq_lane_i8: 5088 case NEON::BI__builtin_neon_vgetq_lane_i16: 5089 case NEON::BI__builtin_neon_vgetq_lane_i32: 5090 case NEON::BI__builtin_neon_vgetq_lane_i64: 5091 case NEON::BI__builtin_neon_vgetq_lane_f32: 5092 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane"); 5093 5094 case NEON::BI__builtin_neon_vset_lane_i8: 5095 case NEON::BI__builtin_neon_vset_lane_i16: 5096 case NEON::BI__builtin_neon_vset_lane_i32: 5097 case NEON::BI__builtin_neon_vset_lane_i64: 5098 case NEON::BI__builtin_neon_vset_lane_f32: 5099 case NEON::BI__builtin_neon_vsetq_lane_i8: 5100 case NEON::BI__builtin_neon_vsetq_lane_i16: 5101 case NEON::BI__builtin_neon_vsetq_lane_i32: 5102 case NEON::BI__builtin_neon_vsetq_lane_i64: 5103 case NEON::BI__builtin_neon_vsetq_lane_f32: 5104 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 5105 5106 case NEON::BI__builtin_neon_vsha1h_u32: 5107 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops, 5108 "vsha1h"); 5109 case NEON::BI__builtin_neon_vsha1cq_u32: 5110 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops, 5111 "vsha1h"); 5112 case NEON::BI__builtin_neon_vsha1pq_u32: 5113 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops, 5114 "vsha1h"); 5115 case NEON::BI__builtin_neon_vsha1mq_u32: 5116 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops, 5117 "vsha1h"); 5118 5119 // The ARM _MoveToCoprocessor builtins put the input register value as 5120 // the first argument, but the LLVM intrinsic expects it as the third one. 5121 case ARM::BI_MoveToCoprocessor: 5122 case ARM::BI_MoveToCoprocessor2: { 5123 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ? 5124 Intrinsic::arm_mcr : Intrinsic::arm_mcr2); 5125 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0], 5126 Ops[3], Ops[4], Ops[5]}); 5127 } 5128 case ARM::BI_BitScanForward: 5129 case ARM::BI_BitScanForward64: 5130 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 5131 case ARM::BI_BitScanReverse: 5132 case ARM::BI_BitScanReverse64: 5133 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 5134 5135 case ARM::BI_InterlockedAnd64: 5136 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 5137 case ARM::BI_InterlockedExchange64: 5138 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 5139 case ARM::BI_InterlockedExchangeAdd64: 5140 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 5141 case ARM::BI_InterlockedExchangeSub64: 5142 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 5143 case ARM::BI_InterlockedOr64: 5144 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 5145 case ARM::BI_InterlockedXor64: 5146 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 5147 case ARM::BI_InterlockedDecrement64: 5148 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 5149 case ARM::BI_InterlockedIncrement64: 5150 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 5151 } 5152 5153 // Get the last argument, which specifies the vector type. 5154 assert(HasExtraArg); 5155 llvm::APSInt Result; 5156 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5157 if (!Arg->isIntegerConstantExpr(Result, getContext())) 5158 return nullptr; 5159 5160 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f || 5161 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) { 5162 // Determine the overloaded type of this builtin. 5163 llvm::Type *Ty; 5164 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f) 5165 Ty = FloatTy; 5166 else 5167 Ty = DoubleTy; 5168 5169 // Determine whether this is an unsigned conversion or not. 5170 bool usgn = Result.getZExtValue() == 1; 5171 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr; 5172 5173 // Call the appropriate intrinsic. 5174 Function *F = CGM.getIntrinsic(Int, Ty); 5175 return Builder.CreateCall(F, Ops, "vcvtr"); 5176 } 5177 5178 // Determine the type of this overloaded NEON intrinsic. 5179 NeonTypeFlags Type(Result.getZExtValue()); 5180 bool usgn = Type.isUnsigned(); 5181 bool rightShift = false; 5182 5183 llvm::VectorType *VTy = GetNeonType(this, Type); 5184 llvm::Type *Ty = VTy; 5185 if (!Ty) 5186 return nullptr; 5187 5188 // Many NEON builtins have identical semantics and uses in ARM and 5189 // AArch64. Emit these in a single function. 5190 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap); 5191 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5192 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted); 5193 if (Builtin) 5194 return EmitCommonNeonBuiltinExpr( 5195 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 5196 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1); 5197 5198 unsigned Int; 5199 switch (BuiltinID) { 5200 default: return nullptr; 5201 case NEON::BI__builtin_neon_vld1q_lane_v: 5202 // Handle 64-bit integer elements as a special case. Use shuffles of 5203 // one-element vectors to avoid poor code for i64 in the backend. 5204 if (VTy->getElementType()->isIntegerTy(64)) { 5205 // Extract the other lane. 5206 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5207 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); 5208 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); 5209 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5210 // Load the value as a one-element vector. 5211 Ty = llvm::VectorType::get(VTy->getElementType(), 1); 5212 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5213 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys); 5214 Value *Align = getAlignmentValue32(PtrOp0); 5215 Value *Ld = Builder.CreateCall(F, {Ops[0], Align}); 5216 // Combine them. 5217 uint32_t Indices[] = {1 - Lane, Lane}; 5218 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices); 5219 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); 5220 } 5221 // fall through 5222 case NEON::BI__builtin_neon_vld1_lane_v: { 5223 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5224 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType()); 5225 Value *Ld = Builder.CreateLoad(PtrOp0); 5226 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane"); 5227 } 5228 case NEON::BI__builtin_neon_vld2_dup_v: 5229 case NEON::BI__builtin_neon_vld3_dup_v: 5230 case NEON::BI__builtin_neon_vld4_dup_v: { 5231 // Handle 64-bit elements as a special-case. There is no "dup" needed. 5232 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) { 5233 switch (BuiltinID) { 5234 case NEON::BI__builtin_neon_vld2_dup_v: 5235 Int = Intrinsic::arm_neon_vld2; 5236 break; 5237 case NEON::BI__builtin_neon_vld3_dup_v: 5238 Int = Intrinsic::arm_neon_vld3; 5239 break; 5240 case NEON::BI__builtin_neon_vld4_dup_v: 5241 Int = Intrinsic::arm_neon_vld4; 5242 break; 5243 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5244 } 5245 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5246 Function *F = CGM.getIntrinsic(Int, Tys); 5247 llvm::Value *Align = getAlignmentValue32(PtrOp1); 5248 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup"); 5249 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5250 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5251 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5252 } 5253 switch (BuiltinID) { 5254 case NEON::BI__builtin_neon_vld2_dup_v: 5255 Int = Intrinsic::arm_neon_vld2lane; 5256 break; 5257 case NEON::BI__builtin_neon_vld3_dup_v: 5258 Int = Intrinsic::arm_neon_vld3lane; 5259 break; 5260 case NEON::BI__builtin_neon_vld4_dup_v: 5261 Int = Intrinsic::arm_neon_vld4lane; 5262 break; 5263 default: llvm_unreachable("unknown vld_dup intrinsic?"); 5264 } 5265 llvm::Type *Tys[] = {Ty, Int8PtrTy}; 5266 Function *F = CGM.getIntrinsic(Int, Tys); 5267 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType()); 5268 5269 SmallVector<Value*, 6> Args; 5270 Args.push_back(Ops[1]); 5271 Args.append(STy->getNumElements(), UndefValue::get(Ty)); 5272 5273 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 5274 Args.push_back(CI); 5275 Args.push_back(getAlignmentValue32(PtrOp1)); 5276 5277 Ops[1] = Builder.CreateCall(F, Args, "vld_dup"); 5278 // splat lane 0 to all elts in each vector of the result. 5279 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { 5280 Value *Val = Builder.CreateExtractValue(Ops[1], i); 5281 Value *Elt = Builder.CreateBitCast(Val, Ty); 5282 Elt = EmitNeonSplat(Elt, CI); 5283 Elt = Builder.CreateBitCast(Elt, Val->getType()); 5284 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i); 5285 } 5286 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5287 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5288 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 5289 } 5290 case NEON::BI__builtin_neon_vqrshrn_n_v: 5291 Int = 5292 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns; 5293 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n", 5294 1, true); 5295 case NEON::BI__builtin_neon_vqrshrun_n_v: 5296 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty), 5297 Ops, "vqrshrun_n", 1, true); 5298 case NEON::BI__builtin_neon_vqshrn_n_v: 5299 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns; 5300 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n", 5301 1, true); 5302 case NEON::BI__builtin_neon_vqshrun_n_v: 5303 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty), 5304 Ops, "vqshrun_n", 1, true); 5305 case NEON::BI__builtin_neon_vrecpe_v: 5306 case NEON::BI__builtin_neon_vrecpeq_v: 5307 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty), 5308 Ops, "vrecpe"); 5309 case NEON::BI__builtin_neon_vrshrn_n_v: 5310 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty), 5311 Ops, "vrshrn_n", 1, true); 5312 case NEON::BI__builtin_neon_vrsra_n_v: 5313 case NEON::BI__builtin_neon_vrsraq_n_v: 5314 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5315 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5316 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true); 5317 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts; 5318 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]}); 5319 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n"); 5320 case NEON::BI__builtin_neon_vsri_n_v: 5321 case NEON::BI__builtin_neon_vsriq_n_v: 5322 rightShift = true; 5323 LLVM_FALLTHROUGH; 5324 case NEON::BI__builtin_neon_vsli_n_v: 5325 case NEON::BI__builtin_neon_vsliq_n_v: 5326 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift); 5327 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty), 5328 Ops, "vsli_n"); 5329 case NEON::BI__builtin_neon_vsra_n_v: 5330 case NEON::BI__builtin_neon_vsraq_n_v: 5331 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 5332 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 5333 return Builder.CreateAdd(Ops[0], Ops[1]); 5334 case NEON::BI__builtin_neon_vst1q_lane_v: 5335 // Handle 64-bit integer elements as a special case. Use a shuffle to get 5336 // a one-element vector and avoid poor code for i64 in the backend. 5337 if (VTy->getElementType()->isIntegerTy(64)) { 5338 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5339 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); 5340 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); 5341 Ops[2] = getAlignmentValue32(PtrOp0); 5342 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()}; 5343 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, 5344 Tys), Ops); 5345 } 5346 // fall through 5347 case NEON::BI__builtin_neon_vst1_lane_v: { 5348 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 5349 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 5350 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 5351 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty)); 5352 return St; 5353 } 5354 case NEON::BI__builtin_neon_vtbl1_v: 5355 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1), 5356 Ops, "vtbl1"); 5357 case NEON::BI__builtin_neon_vtbl2_v: 5358 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2), 5359 Ops, "vtbl2"); 5360 case NEON::BI__builtin_neon_vtbl3_v: 5361 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3), 5362 Ops, "vtbl3"); 5363 case NEON::BI__builtin_neon_vtbl4_v: 5364 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4), 5365 Ops, "vtbl4"); 5366 case NEON::BI__builtin_neon_vtbx1_v: 5367 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1), 5368 Ops, "vtbx1"); 5369 case NEON::BI__builtin_neon_vtbx2_v: 5370 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2), 5371 Ops, "vtbx2"); 5372 case NEON::BI__builtin_neon_vtbx3_v: 5373 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3), 5374 Ops, "vtbx3"); 5375 case NEON::BI__builtin_neon_vtbx4_v: 5376 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4), 5377 Ops, "vtbx4"); 5378 } 5379 } 5380 5381 static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID, 5382 const CallExpr *E, 5383 SmallVectorImpl<Value *> &Ops) { 5384 unsigned int Int = 0; 5385 const char *s = nullptr; 5386 5387 switch (BuiltinID) { 5388 default: 5389 return nullptr; 5390 case NEON::BI__builtin_neon_vtbl1_v: 5391 case NEON::BI__builtin_neon_vqtbl1_v: 5392 case NEON::BI__builtin_neon_vqtbl1q_v: 5393 case NEON::BI__builtin_neon_vtbl2_v: 5394 case NEON::BI__builtin_neon_vqtbl2_v: 5395 case NEON::BI__builtin_neon_vqtbl2q_v: 5396 case NEON::BI__builtin_neon_vtbl3_v: 5397 case NEON::BI__builtin_neon_vqtbl3_v: 5398 case NEON::BI__builtin_neon_vqtbl3q_v: 5399 case NEON::BI__builtin_neon_vtbl4_v: 5400 case NEON::BI__builtin_neon_vqtbl4_v: 5401 case NEON::BI__builtin_neon_vqtbl4q_v: 5402 break; 5403 case NEON::BI__builtin_neon_vtbx1_v: 5404 case NEON::BI__builtin_neon_vqtbx1_v: 5405 case NEON::BI__builtin_neon_vqtbx1q_v: 5406 case NEON::BI__builtin_neon_vtbx2_v: 5407 case NEON::BI__builtin_neon_vqtbx2_v: 5408 case NEON::BI__builtin_neon_vqtbx2q_v: 5409 case NEON::BI__builtin_neon_vtbx3_v: 5410 case NEON::BI__builtin_neon_vqtbx3_v: 5411 case NEON::BI__builtin_neon_vqtbx3q_v: 5412 case NEON::BI__builtin_neon_vtbx4_v: 5413 case NEON::BI__builtin_neon_vqtbx4_v: 5414 case NEON::BI__builtin_neon_vqtbx4q_v: 5415 break; 5416 } 5417 5418 assert(E->getNumArgs() >= 3); 5419 5420 // Get the last argument, which specifies the vector type. 5421 llvm::APSInt Result; 5422 const Expr *Arg = E->getArg(E->getNumArgs() - 1); 5423 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext())) 5424 return nullptr; 5425 5426 // Determine the type of this overloaded NEON intrinsic. 5427 NeonTypeFlags Type(Result.getZExtValue()); 5428 llvm::VectorType *Ty = GetNeonType(&CGF, Type); 5429 if (!Ty) 5430 return nullptr; 5431 5432 CodeGen::CGBuilderTy &Builder = CGF.Builder; 5433 5434 // AArch64 scalar builtins are not overloaded, they do not have an extra 5435 // argument that specifies the vector type, need to handle each case. 5436 switch (BuiltinID) { 5437 case NEON::BI__builtin_neon_vtbl1_v: { 5438 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr, 5439 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1, 5440 "vtbl1"); 5441 } 5442 case NEON::BI__builtin_neon_vtbl2_v: { 5443 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr, 5444 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1, 5445 "vtbl1"); 5446 } 5447 case NEON::BI__builtin_neon_vtbl3_v: { 5448 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr, 5449 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2, 5450 "vtbl2"); 5451 } 5452 case NEON::BI__builtin_neon_vtbl4_v: { 5453 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr, 5454 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2, 5455 "vtbl2"); 5456 } 5457 case NEON::BI__builtin_neon_vtbx1_v: { 5458 Value *TblRes = 5459 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2], 5460 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1"); 5461 5462 llvm::Constant *EightV = ConstantInt::get(Ty, 8); 5463 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV); 5464 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5465 5466 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5467 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5468 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5469 } 5470 case NEON::BI__builtin_neon_vtbx2_v: { 5471 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0], 5472 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1, 5473 "vtbx1"); 5474 } 5475 case NEON::BI__builtin_neon_vtbx3_v: { 5476 Value *TblRes = 5477 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4], 5478 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2"); 5479 5480 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24); 5481 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4], 5482 TwentyFourV); 5483 CmpRes = Builder.CreateSExt(CmpRes, Ty); 5484 5485 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]); 5486 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes); 5487 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx"); 5488 } 5489 case NEON::BI__builtin_neon_vtbx4_v: { 5490 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0], 5491 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2, 5492 "vtbx2"); 5493 } 5494 case NEON::BI__builtin_neon_vqtbl1_v: 5495 case NEON::BI__builtin_neon_vqtbl1q_v: 5496 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break; 5497 case NEON::BI__builtin_neon_vqtbl2_v: 5498 case NEON::BI__builtin_neon_vqtbl2q_v: { 5499 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break; 5500 case NEON::BI__builtin_neon_vqtbl3_v: 5501 case NEON::BI__builtin_neon_vqtbl3q_v: 5502 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break; 5503 case NEON::BI__builtin_neon_vqtbl4_v: 5504 case NEON::BI__builtin_neon_vqtbl4q_v: 5505 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break; 5506 case NEON::BI__builtin_neon_vqtbx1_v: 5507 case NEON::BI__builtin_neon_vqtbx1q_v: 5508 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break; 5509 case NEON::BI__builtin_neon_vqtbx2_v: 5510 case NEON::BI__builtin_neon_vqtbx2q_v: 5511 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break; 5512 case NEON::BI__builtin_neon_vqtbx3_v: 5513 case NEON::BI__builtin_neon_vqtbx3q_v: 5514 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break; 5515 case NEON::BI__builtin_neon_vqtbx4_v: 5516 case NEON::BI__builtin_neon_vqtbx4q_v: 5517 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break; 5518 } 5519 } 5520 5521 if (!Int) 5522 return nullptr; 5523 5524 Function *F = CGF.CGM.getIntrinsic(Int, Ty); 5525 return CGF.EmitNeonCall(F, Ops, s); 5526 } 5527 5528 Value *CodeGenFunction::vectorWrapScalar16(Value *Op) { 5529 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4); 5530 Op = Builder.CreateBitCast(Op, Int16Ty); 5531 Value *V = UndefValue::get(VTy); 5532 llvm::Constant *CI = ConstantInt::get(SizeTy, 0); 5533 Op = Builder.CreateInsertElement(V, Op, CI); 5534 return Op; 5535 } 5536 5537 Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, 5538 const CallExpr *E) { 5539 unsigned HintID = static_cast<unsigned>(-1); 5540 switch (BuiltinID) { 5541 default: break; 5542 case AArch64::BI__builtin_arm_nop: 5543 HintID = 0; 5544 break; 5545 case AArch64::BI__builtin_arm_yield: 5546 HintID = 1; 5547 break; 5548 case AArch64::BI__builtin_arm_wfe: 5549 HintID = 2; 5550 break; 5551 case AArch64::BI__builtin_arm_wfi: 5552 HintID = 3; 5553 break; 5554 case AArch64::BI__builtin_arm_sev: 5555 HintID = 4; 5556 break; 5557 case AArch64::BI__builtin_arm_sevl: 5558 HintID = 5; 5559 break; 5560 } 5561 5562 if (HintID != static_cast<unsigned>(-1)) { 5563 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint); 5564 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID)); 5565 } 5566 5567 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) { 5568 Value *Address = EmitScalarExpr(E->getArg(0)); 5569 Value *RW = EmitScalarExpr(E->getArg(1)); 5570 Value *CacheLevel = EmitScalarExpr(E->getArg(2)); 5571 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3)); 5572 Value *IsData = EmitScalarExpr(E->getArg(4)); 5573 5574 Value *Locality = nullptr; 5575 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) { 5576 // Temporal fetch, needs to convert cache level to locality. 5577 Locality = llvm::ConstantInt::get(Int32Ty, 5578 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3); 5579 } else { 5580 // Streaming fetch. 5581 Locality = llvm::ConstantInt::get(Int32Ty, 0); 5582 } 5583 5584 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify 5585 // PLDL3STRM or PLDL2STRM. 5586 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 5587 return Builder.CreateCall(F, {Address, RW, Locality, IsData}); 5588 } 5589 5590 if (BuiltinID == AArch64::BI__builtin_arm_rbit) { 5591 assert((getContext().getTypeSize(E->getType()) == 32) && 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 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) { 5598 assert((getContext().getTypeSize(E->getType()) == 64) && 5599 "rbit of unusual size!"); 5600 llvm::Value *Arg = EmitScalarExpr(E->getArg(0)); 5601 return Builder.CreateCall( 5602 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit"); 5603 } 5604 5605 if (BuiltinID == AArch64::BI__clear_cache) { 5606 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments"); 5607 const FunctionDecl *FD = E->getDirectCallee(); 5608 Value *Ops[2]; 5609 for (unsigned i = 0; i < 2; i++) 5610 Ops[i] = EmitScalarExpr(E->getArg(i)); 5611 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType()); 5612 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty); 5613 StringRef Name = FD->getName(); 5614 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops); 5615 } 5616 5617 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex || 5618 BuiltinID == AArch64::BI__builtin_arm_ldaex) && 5619 getContext().getTypeSize(E->getType()) == 128) { 5620 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5621 ? Intrinsic::aarch64_ldaxp 5622 : Intrinsic::aarch64_ldxp); 5623 5624 Value *LdPtr = EmitScalarExpr(E->getArg(0)); 5625 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy), 5626 "ldxp"); 5627 5628 Value *Val0 = Builder.CreateExtractValue(Val, 1); 5629 Value *Val1 = Builder.CreateExtractValue(Val, 0); 5630 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 5631 Val0 = Builder.CreateZExt(Val0, Int128Ty); 5632 Val1 = Builder.CreateZExt(Val1, Int128Ty); 5633 5634 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64); 5635 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */); 5636 Val = Builder.CreateOr(Val, Val1); 5637 return Builder.CreateBitCast(Val, ConvertType(E->getType())); 5638 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex || 5639 BuiltinID == AArch64::BI__builtin_arm_ldaex) { 5640 Value *LoadAddr = EmitScalarExpr(E->getArg(0)); 5641 5642 QualType Ty = E->getType(); 5643 llvm::Type *RealResTy = ConvertType(Ty); 5644 llvm::Type *PtrTy = llvm::IntegerType::get( 5645 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo(); 5646 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy); 5647 5648 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex 5649 ? Intrinsic::aarch64_ldaxr 5650 : Intrinsic::aarch64_ldxr, 5651 PtrTy); 5652 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr"); 5653 5654 if (RealResTy->isPointerTy()) 5655 return Builder.CreateIntToPtr(Val, RealResTy); 5656 5657 llvm::Type *IntResTy = llvm::IntegerType::get( 5658 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy)); 5659 Val = Builder.CreateTruncOrBitCast(Val, IntResTy); 5660 return Builder.CreateBitCast(Val, RealResTy); 5661 } 5662 5663 if ((BuiltinID == AArch64::BI__builtin_arm_strex || 5664 BuiltinID == AArch64::BI__builtin_arm_stlex) && 5665 getContext().getTypeSize(E->getArg(0)->getType()) == 128) { 5666 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5667 ? Intrinsic::aarch64_stlxp 5668 : Intrinsic::aarch64_stxp); 5669 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty); 5670 5671 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 5672 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true); 5673 5674 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy)); 5675 llvm::Value *Val = Builder.CreateLoad(Tmp); 5676 5677 Value *Arg0 = Builder.CreateExtractValue(Val, 0); 5678 Value *Arg1 = Builder.CreateExtractValue(Val, 1); 5679 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), 5680 Int8PtrTy); 5681 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp"); 5682 } 5683 5684 if (BuiltinID == AArch64::BI__builtin_arm_strex || 5685 BuiltinID == AArch64::BI__builtin_arm_stlex) { 5686 Value *StoreVal = EmitScalarExpr(E->getArg(0)); 5687 Value *StoreAddr = EmitScalarExpr(E->getArg(1)); 5688 5689 QualType Ty = E->getArg(0)->getType(); 5690 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(), 5691 getContext().getTypeSize(Ty)); 5692 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo()); 5693 5694 if (StoreVal->getType()->isPointerTy()) 5695 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty); 5696 else { 5697 llvm::Type *IntTy = llvm::IntegerType::get( 5698 getLLVMContext(), 5699 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType())); 5700 StoreVal = Builder.CreateBitCast(StoreVal, IntTy); 5701 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty); 5702 } 5703 5704 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex 5705 ? Intrinsic::aarch64_stlxr 5706 : Intrinsic::aarch64_stxr, 5707 StoreAddr->getType()); 5708 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr"); 5709 } 5710 5711 if (BuiltinID == AArch64::BI__builtin_arm_clrex) { 5712 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex); 5713 return Builder.CreateCall(F); 5714 } 5715 5716 // CRC32 5717 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic; 5718 switch (BuiltinID) { 5719 case AArch64::BI__builtin_arm_crc32b: 5720 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break; 5721 case AArch64::BI__builtin_arm_crc32cb: 5722 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break; 5723 case AArch64::BI__builtin_arm_crc32h: 5724 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break; 5725 case AArch64::BI__builtin_arm_crc32ch: 5726 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break; 5727 case AArch64::BI__builtin_arm_crc32w: 5728 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break; 5729 case AArch64::BI__builtin_arm_crc32cw: 5730 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break; 5731 case AArch64::BI__builtin_arm_crc32d: 5732 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break; 5733 case AArch64::BI__builtin_arm_crc32cd: 5734 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break; 5735 } 5736 5737 if (CRCIntrinsicID != Intrinsic::not_intrinsic) { 5738 Value *Arg0 = EmitScalarExpr(E->getArg(0)); 5739 Value *Arg1 = EmitScalarExpr(E->getArg(1)); 5740 Function *F = CGM.getIntrinsic(CRCIntrinsicID); 5741 5742 llvm::Type *DataTy = F->getFunctionType()->getParamType(1); 5743 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy); 5744 5745 return Builder.CreateCall(F, {Arg0, Arg1}); 5746 } 5747 5748 if (BuiltinID == AArch64::BI__builtin_arm_rsr || 5749 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5750 BuiltinID == AArch64::BI__builtin_arm_rsrp || 5751 BuiltinID == AArch64::BI__builtin_arm_wsr || 5752 BuiltinID == AArch64::BI__builtin_arm_wsr64 || 5753 BuiltinID == AArch64::BI__builtin_arm_wsrp) { 5754 5755 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr || 5756 BuiltinID == AArch64::BI__builtin_arm_rsr64 || 5757 BuiltinID == AArch64::BI__builtin_arm_rsrp; 5758 5759 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp || 5760 BuiltinID == AArch64::BI__builtin_arm_wsrp; 5761 5762 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr && 5763 BuiltinID != AArch64::BI__builtin_arm_wsr; 5764 5765 llvm::Type *ValueType; 5766 llvm::Type *RegisterType = Int64Ty; 5767 if (IsPointerBuiltin) { 5768 ValueType = VoidPtrTy; 5769 } else if (Is64Bit) { 5770 ValueType = Int64Ty; 5771 } else { 5772 ValueType = Int32Ty; 5773 } 5774 5775 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead); 5776 } 5777 5778 // Find out if any arguments are required to be integer constant 5779 // expressions. 5780 unsigned ICEArguments = 0; 5781 ASTContext::GetBuiltinTypeError Error; 5782 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 5783 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 5784 5785 llvm::SmallVector<Value*, 4> Ops; 5786 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) { 5787 if ((ICEArguments & (1 << i)) == 0) { 5788 Ops.push_back(EmitScalarExpr(E->getArg(i))); 5789 } else { 5790 // If this is required to be a constant, constant fold it so that we know 5791 // that the generated intrinsic gets a ConstantInt. 5792 llvm::APSInt Result; 5793 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 5794 assert(IsConst && "Constant arg isn't actually constant?"); 5795 (void)IsConst; 5796 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 5797 } 5798 } 5799 5800 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap); 5801 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap( 5802 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted); 5803 5804 if (Builtin) { 5805 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1))); 5806 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E); 5807 assert(Result && "SISD intrinsic should have been handled"); 5808 return Result; 5809 } 5810 5811 llvm::APSInt Result; 5812 const Expr *Arg = E->getArg(E->getNumArgs()-1); 5813 NeonTypeFlags Type(0); 5814 if (Arg->isIntegerConstantExpr(Result, getContext())) 5815 // Determine the type of this overloaded NEON intrinsic. 5816 Type = NeonTypeFlags(Result.getZExtValue()); 5817 5818 bool usgn = Type.isUnsigned(); 5819 bool quad = Type.isQuad(); 5820 5821 // Handle non-overloaded intrinsics first. 5822 switch (BuiltinID) { 5823 default: break; 5824 case NEON::BI__builtin_neon_vldrq_p128: { 5825 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128); 5826 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0); 5827 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy); 5828 return Builder.CreateAlignedLoad(Int128Ty, Ptr, 5829 CharUnits::fromQuantity(16)); 5830 } 5831 case NEON::BI__builtin_neon_vstrq_p128: { 5832 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128); 5833 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy); 5834 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr); 5835 } 5836 case NEON::BI__builtin_neon_vcvts_u32_f32: 5837 case NEON::BI__builtin_neon_vcvtd_u64_f64: 5838 usgn = true; 5839 // FALL THROUGH 5840 case NEON::BI__builtin_neon_vcvts_s32_f32: 5841 case NEON::BI__builtin_neon_vcvtd_s64_f64: { 5842 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5843 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5844 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5845 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5846 Ops[0] = Builder.CreateBitCast(Ops[0], FTy); 5847 if (usgn) 5848 return Builder.CreateFPToUI(Ops[0], InTy); 5849 return Builder.CreateFPToSI(Ops[0], InTy); 5850 } 5851 case NEON::BI__builtin_neon_vcvts_f32_u32: 5852 case NEON::BI__builtin_neon_vcvtd_f64_u64: 5853 usgn = true; 5854 // FALL THROUGH 5855 case NEON::BI__builtin_neon_vcvts_f32_s32: 5856 case NEON::BI__builtin_neon_vcvtd_f64_s64: { 5857 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5858 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64; 5859 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty; 5860 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy; 5861 Ops[0] = Builder.CreateBitCast(Ops[0], InTy); 5862 if (usgn) 5863 return Builder.CreateUIToFP(Ops[0], FTy); 5864 return Builder.CreateSIToFP(Ops[0], FTy); 5865 } 5866 case NEON::BI__builtin_neon_vpaddd_s64: { 5867 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2); 5868 Value *Vec = EmitScalarExpr(E->getArg(0)); 5869 // The vector is v2f64, so make sure it's bitcast to that. 5870 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64"); 5871 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5872 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5873 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5874 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5875 // Pairwise addition of a v2f64 into a scalar f64. 5876 return Builder.CreateAdd(Op0, Op1, "vpaddd"); 5877 } 5878 case NEON::BI__builtin_neon_vpaddd_f64: { 5879 llvm::Type *Ty = 5880 llvm::VectorType::get(DoubleTy, 2); 5881 Value *Vec = EmitScalarExpr(E->getArg(0)); 5882 // The vector is v2f64, so make sure it's bitcast to that. 5883 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64"); 5884 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5885 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5886 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5887 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5888 // Pairwise addition of a v2f64 into a scalar f64. 5889 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5890 } 5891 case NEON::BI__builtin_neon_vpadds_f32: { 5892 llvm::Type *Ty = 5893 llvm::VectorType::get(FloatTy, 2); 5894 Value *Vec = EmitScalarExpr(E->getArg(0)); 5895 // The vector is v2f32, so make sure it's bitcast to that. 5896 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32"); 5897 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0); 5898 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1); 5899 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0"); 5900 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1"); 5901 // Pairwise addition of a v2f32 into a scalar f32. 5902 return Builder.CreateFAdd(Op0, Op1, "vpaddd"); 5903 } 5904 case NEON::BI__builtin_neon_vceqzd_s64: 5905 case NEON::BI__builtin_neon_vceqzd_f64: 5906 case NEON::BI__builtin_neon_vceqzs_f32: 5907 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5908 return EmitAArch64CompareBuiltinExpr( 5909 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5910 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz"); 5911 case NEON::BI__builtin_neon_vcgezd_s64: 5912 case NEON::BI__builtin_neon_vcgezd_f64: 5913 case NEON::BI__builtin_neon_vcgezs_f32: 5914 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5915 return EmitAArch64CompareBuiltinExpr( 5916 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5917 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez"); 5918 case NEON::BI__builtin_neon_vclezd_s64: 5919 case NEON::BI__builtin_neon_vclezd_f64: 5920 case NEON::BI__builtin_neon_vclezs_f32: 5921 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5922 return EmitAArch64CompareBuiltinExpr( 5923 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5924 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez"); 5925 case NEON::BI__builtin_neon_vcgtzd_s64: 5926 case NEON::BI__builtin_neon_vcgtzd_f64: 5927 case NEON::BI__builtin_neon_vcgtzs_f32: 5928 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5929 return EmitAArch64CompareBuiltinExpr( 5930 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5931 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz"); 5932 case NEON::BI__builtin_neon_vcltzd_s64: 5933 case NEON::BI__builtin_neon_vcltzd_f64: 5934 case NEON::BI__builtin_neon_vcltzs_f32: 5935 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5936 return EmitAArch64CompareBuiltinExpr( 5937 Ops[0], ConvertType(E->getCallReturnType(getContext())), 5938 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz"); 5939 5940 case NEON::BI__builtin_neon_vceqzd_u64: { 5941 Ops.push_back(EmitScalarExpr(E->getArg(0))); 5942 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 5943 Ops[0] = 5944 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty)); 5945 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd"); 5946 } 5947 case NEON::BI__builtin_neon_vceqd_f64: 5948 case NEON::BI__builtin_neon_vcled_f64: 5949 case NEON::BI__builtin_neon_vcltd_f64: 5950 case NEON::BI__builtin_neon_vcged_f64: 5951 case NEON::BI__builtin_neon_vcgtd_f64: { 5952 llvm::CmpInst::Predicate P; 5953 switch (BuiltinID) { 5954 default: llvm_unreachable("missing builtin ID in switch!"); 5955 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break; 5956 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break; 5957 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break; 5958 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break; 5959 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break; 5960 } 5961 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5962 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 5963 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 5964 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5965 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd"); 5966 } 5967 case NEON::BI__builtin_neon_vceqs_f32: 5968 case NEON::BI__builtin_neon_vcles_f32: 5969 case NEON::BI__builtin_neon_vclts_f32: 5970 case NEON::BI__builtin_neon_vcges_f32: 5971 case NEON::BI__builtin_neon_vcgts_f32: { 5972 llvm::CmpInst::Predicate P; 5973 switch (BuiltinID) { 5974 default: llvm_unreachable("missing builtin ID in switch!"); 5975 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break; 5976 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break; 5977 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break; 5978 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break; 5979 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break; 5980 } 5981 Ops.push_back(EmitScalarExpr(E->getArg(1))); 5982 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy); 5983 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy); 5984 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]); 5985 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd"); 5986 } 5987 case NEON::BI__builtin_neon_vceqd_s64: 5988 case NEON::BI__builtin_neon_vceqd_u64: 5989 case NEON::BI__builtin_neon_vcgtd_s64: 5990 case NEON::BI__builtin_neon_vcgtd_u64: 5991 case NEON::BI__builtin_neon_vcltd_s64: 5992 case NEON::BI__builtin_neon_vcltd_u64: 5993 case NEON::BI__builtin_neon_vcged_u64: 5994 case NEON::BI__builtin_neon_vcged_s64: 5995 case NEON::BI__builtin_neon_vcled_u64: 5996 case NEON::BI__builtin_neon_vcled_s64: { 5997 llvm::CmpInst::Predicate P; 5998 switch (BuiltinID) { 5999 default: llvm_unreachable("missing builtin ID in switch!"); 6000 case NEON::BI__builtin_neon_vceqd_s64: 6001 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break; 6002 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break; 6003 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break; 6004 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break; 6005 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break; 6006 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break; 6007 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break; 6008 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break; 6009 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break; 6010 } 6011 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6012 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6013 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6014 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]); 6015 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd"); 6016 } 6017 case NEON::BI__builtin_neon_vtstd_s64: 6018 case NEON::BI__builtin_neon_vtstd_u64: { 6019 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6020 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty); 6021 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6022 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]); 6023 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0], 6024 llvm::Constant::getNullValue(Int64Ty)); 6025 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd"); 6026 } 6027 case NEON::BI__builtin_neon_vset_lane_i8: 6028 case NEON::BI__builtin_neon_vset_lane_i16: 6029 case NEON::BI__builtin_neon_vset_lane_i32: 6030 case NEON::BI__builtin_neon_vset_lane_i64: 6031 case NEON::BI__builtin_neon_vset_lane_f32: 6032 case NEON::BI__builtin_neon_vsetq_lane_i8: 6033 case NEON::BI__builtin_neon_vsetq_lane_i16: 6034 case NEON::BI__builtin_neon_vsetq_lane_i32: 6035 case NEON::BI__builtin_neon_vsetq_lane_i64: 6036 case NEON::BI__builtin_neon_vsetq_lane_f32: 6037 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6038 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6039 case NEON::BI__builtin_neon_vset_lane_f64: 6040 // The vector type needs a cast for the v1f64 variant. 6041 Ops[1] = Builder.CreateBitCast(Ops[1], 6042 llvm::VectorType::get(DoubleTy, 1)); 6043 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6044 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6045 case NEON::BI__builtin_neon_vsetq_lane_f64: 6046 // The vector type needs a cast for the v2f64 variant. 6047 Ops[1] = Builder.CreateBitCast(Ops[1], 6048 llvm::VectorType::get(DoubleTy, 2)); 6049 Ops.push_back(EmitScalarExpr(E->getArg(2))); 6050 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane"); 6051 6052 case NEON::BI__builtin_neon_vget_lane_i8: 6053 case NEON::BI__builtin_neon_vdupb_lane_i8: 6054 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8)); 6055 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6056 "vget_lane"); 6057 case NEON::BI__builtin_neon_vgetq_lane_i8: 6058 case NEON::BI__builtin_neon_vdupb_laneq_i8: 6059 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16)); 6060 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6061 "vgetq_lane"); 6062 case NEON::BI__builtin_neon_vget_lane_i16: 6063 case NEON::BI__builtin_neon_vduph_lane_i16: 6064 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4)); 6065 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6066 "vget_lane"); 6067 case NEON::BI__builtin_neon_vgetq_lane_i16: 6068 case NEON::BI__builtin_neon_vduph_laneq_i16: 6069 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8)); 6070 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6071 "vgetq_lane"); 6072 case NEON::BI__builtin_neon_vget_lane_i32: 6073 case NEON::BI__builtin_neon_vdups_lane_i32: 6074 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2)); 6075 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6076 "vget_lane"); 6077 case NEON::BI__builtin_neon_vdups_lane_f32: 6078 Ops[0] = Builder.CreateBitCast(Ops[0], 6079 llvm::VectorType::get(FloatTy, 2)); 6080 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6081 "vdups_lane"); 6082 case NEON::BI__builtin_neon_vgetq_lane_i32: 6083 case NEON::BI__builtin_neon_vdups_laneq_i32: 6084 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 6085 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6086 "vgetq_lane"); 6087 case NEON::BI__builtin_neon_vget_lane_i64: 6088 case NEON::BI__builtin_neon_vdupd_lane_i64: 6089 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1)); 6090 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6091 "vget_lane"); 6092 case NEON::BI__builtin_neon_vdupd_lane_f64: 6093 Ops[0] = Builder.CreateBitCast(Ops[0], 6094 llvm::VectorType::get(DoubleTy, 1)); 6095 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6096 "vdupd_lane"); 6097 case NEON::BI__builtin_neon_vgetq_lane_i64: 6098 case NEON::BI__builtin_neon_vdupd_laneq_i64: 6099 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 6100 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6101 "vgetq_lane"); 6102 case NEON::BI__builtin_neon_vget_lane_f32: 6103 Ops[0] = Builder.CreateBitCast(Ops[0], 6104 llvm::VectorType::get(FloatTy, 2)); 6105 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6106 "vget_lane"); 6107 case NEON::BI__builtin_neon_vget_lane_f64: 6108 Ops[0] = Builder.CreateBitCast(Ops[0], 6109 llvm::VectorType::get(DoubleTy, 1)); 6110 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6111 "vget_lane"); 6112 case NEON::BI__builtin_neon_vgetq_lane_f32: 6113 case NEON::BI__builtin_neon_vdups_laneq_f32: 6114 Ops[0] = Builder.CreateBitCast(Ops[0], 6115 llvm::VectorType::get(FloatTy, 4)); 6116 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6117 "vgetq_lane"); 6118 case NEON::BI__builtin_neon_vgetq_lane_f64: 6119 case NEON::BI__builtin_neon_vdupd_laneq_f64: 6120 Ops[0] = Builder.CreateBitCast(Ops[0], 6121 llvm::VectorType::get(DoubleTy, 2)); 6122 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)), 6123 "vgetq_lane"); 6124 case NEON::BI__builtin_neon_vaddd_s64: 6125 case NEON::BI__builtin_neon_vaddd_u64: 6126 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd"); 6127 case NEON::BI__builtin_neon_vsubd_s64: 6128 case NEON::BI__builtin_neon_vsubd_u64: 6129 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd"); 6130 case NEON::BI__builtin_neon_vqdmlalh_s16: 6131 case NEON::BI__builtin_neon_vqdmlslh_s16: { 6132 SmallVector<Value *, 2> ProductOps; 6133 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6134 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2)))); 6135 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6136 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6137 ProductOps, "vqdmlXl"); 6138 Constant *CI = ConstantInt::get(SizeTy, 0); 6139 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6140 6141 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16 6142 ? Intrinsic::aarch64_neon_sqadd 6143 : Intrinsic::aarch64_neon_sqsub; 6144 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl"); 6145 } 6146 case NEON::BI__builtin_neon_vqshlud_n_s64: { 6147 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6148 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6149 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty), 6150 Ops, "vqshlu_n"); 6151 } 6152 case NEON::BI__builtin_neon_vqshld_n_u64: 6153 case NEON::BI__builtin_neon_vqshld_n_s64: { 6154 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64 6155 ? Intrinsic::aarch64_neon_uqshl 6156 : Intrinsic::aarch64_neon_sqshl; 6157 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6158 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty); 6159 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n"); 6160 } 6161 case NEON::BI__builtin_neon_vrshrd_n_u64: 6162 case NEON::BI__builtin_neon_vrshrd_n_s64: { 6163 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64 6164 ? Intrinsic::aarch64_neon_urshl 6165 : Intrinsic::aarch64_neon_srshl; 6166 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6167 int SV = cast<ConstantInt>(Ops[1])->getSExtValue(); 6168 Ops[1] = ConstantInt::get(Int64Ty, -SV); 6169 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n"); 6170 } 6171 case NEON::BI__builtin_neon_vrsrad_n_u64: 6172 case NEON::BI__builtin_neon_vrsrad_n_s64: { 6173 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64 6174 ? Intrinsic::aarch64_neon_urshl 6175 : Intrinsic::aarch64_neon_srshl; 6176 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty); 6177 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2)))); 6178 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty), 6179 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)}); 6180 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty)); 6181 } 6182 case NEON::BI__builtin_neon_vshld_n_s64: 6183 case NEON::BI__builtin_neon_vshld_n_u64: { 6184 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6185 return Builder.CreateShl( 6186 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n"); 6187 } 6188 case NEON::BI__builtin_neon_vshrd_n_s64: { 6189 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6190 return Builder.CreateAShr( 6191 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6192 Amt->getZExtValue())), 6193 "shrd_n"); 6194 } 6195 case NEON::BI__builtin_neon_vshrd_n_u64: { 6196 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1))); 6197 uint64_t ShiftAmt = Amt->getZExtValue(); 6198 // Right-shifting an unsigned value by its size yields 0. 6199 if (ShiftAmt == 64) 6200 return ConstantInt::get(Int64Ty, 0); 6201 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt), 6202 "shrd_n"); 6203 } 6204 case NEON::BI__builtin_neon_vsrad_n_s64: { 6205 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6206 Ops[1] = Builder.CreateAShr( 6207 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63), 6208 Amt->getZExtValue())), 6209 "shrd_n"); 6210 return Builder.CreateAdd(Ops[0], Ops[1]); 6211 } 6212 case NEON::BI__builtin_neon_vsrad_n_u64: { 6213 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2))); 6214 uint64_t ShiftAmt = Amt->getZExtValue(); 6215 // Right-shifting an unsigned value by its size yields 0. 6216 // As Op + 0 = Op, return Ops[0] directly. 6217 if (ShiftAmt == 64) 6218 return Ops[0]; 6219 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt), 6220 "shrd_n"); 6221 return Builder.CreateAdd(Ops[0], Ops[1]); 6222 } 6223 case NEON::BI__builtin_neon_vqdmlalh_lane_s16: 6224 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16: 6225 case NEON::BI__builtin_neon_vqdmlslh_lane_s16: 6226 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: { 6227 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6228 "lane"); 6229 SmallVector<Value *, 2> ProductOps; 6230 ProductOps.push_back(vectorWrapScalar16(Ops[1])); 6231 ProductOps.push_back(vectorWrapScalar16(Ops[2])); 6232 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4); 6233 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy), 6234 ProductOps, "vqdmlXl"); 6235 Constant *CI = ConstantInt::get(SizeTy, 0); 6236 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0"); 6237 Ops.pop_back(); 6238 6239 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 || 6240 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16) 6241 ? Intrinsic::aarch64_neon_sqadd 6242 : Intrinsic::aarch64_neon_sqsub; 6243 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl"); 6244 } 6245 case NEON::BI__builtin_neon_vqdmlals_s32: 6246 case NEON::BI__builtin_neon_vqdmlsls_s32: { 6247 SmallVector<Value *, 2> ProductOps; 6248 ProductOps.push_back(Ops[1]); 6249 ProductOps.push_back(EmitScalarExpr(E->getArg(2))); 6250 Ops[1] = 6251 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6252 ProductOps, "vqdmlXl"); 6253 6254 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32 6255 ? Intrinsic::aarch64_neon_sqadd 6256 : Intrinsic::aarch64_neon_sqsub; 6257 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl"); 6258 } 6259 case NEON::BI__builtin_neon_vqdmlals_lane_s32: 6260 case NEON::BI__builtin_neon_vqdmlals_laneq_s32: 6261 case NEON::BI__builtin_neon_vqdmlsls_lane_s32: 6262 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: { 6263 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)), 6264 "lane"); 6265 SmallVector<Value *, 2> ProductOps; 6266 ProductOps.push_back(Ops[1]); 6267 ProductOps.push_back(Ops[2]); 6268 Ops[1] = 6269 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar), 6270 ProductOps, "vqdmlXl"); 6271 Ops.pop_back(); 6272 6273 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 || 6274 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32) 6275 ? Intrinsic::aarch64_neon_sqadd 6276 : Intrinsic::aarch64_neon_sqsub; 6277 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl"); 6278 } 6279 } 6280 6281 llvm::VectorType *VTy = GetNeonType(this, Type); 6282 llvm::Type *Ty = VTy; 6283 if (!Ty) 6284 return nullptr; 6285 6286 // Not all intrinsics handled by the common case work for AArch64 yet, so only 6287 // defer to common code if it's been added to our special map. 6288 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID, 6289 AArch64SIMDIntrinsicsProvenSorted); 6290 6291 if (Builtin) 6292 return EmitCommonNeonBuiltinExpr( 6293 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic, 6294 Builtin->NameHint, Builtin->TypeModifier, E, Ops, 6295 /*never use addresses*/ Address::invalid(), Address::invalid()); 6296 6297 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops)) 6298 return V; 6299 6300 unsigned Int; 6301 switch (BuiltinID) { 6302 default: return nullptr; 6303 case NEON::BI__builtin_neon_vbsl_v: 6304 case NEON::BI__builtin_neon_vbslq_v: { 6305 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy); 6306 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl"); 6307 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl"); 6308 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl"); 6309 6310 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl"); 6311 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl"); 6312 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl"); 6313 return Builder.CreateBitCast(Ops[0], Ty); 6314 } 6315 case NEON::BI__builtin_neon_vfma_lane_v: 6316 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types 6317 // The ARM builtins (and instructions) have the addend as the first 6318 // operand, but the 'fma' intrinsics have it last. Swap it around here. 6319 Value *Addend = Ops[0]; 6320 Value *Multiplicand = Ops[1]; 6321 Value *LaneSource = Ops[2]; 6322 Ops[0] = Multiplicand; 6323 Ops[1] = LaneSource; 6324 Ops[2] = Addend; 6325 6326 // Now adjust things to handle the lane access. 6327 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ? 6328 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) : 6329 VTy; 6330 llvm::Constant *cst = cast<Constant>(Ops[3]); 6331 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst); 6332 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy); 6333 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane"); 6334 6335 Ops.pop_back(); 6336 Int = Intrinsic::fma; 6337 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla"); 6338 } 6339 case NEON::BI__builtin_neon_vfma_laneq_v: { 6340 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty); 6341 // v1f64 fma should be mapped to Neon scalar f64 fma 6342 if (VTy && VTy->getElementType() == DoubleTy) { 6343 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6344 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy); 6345 llvm::Type *VTy = GetNeonType(this, 6346 NeonTypeFlags(NeonTypeFlags::Float64, false, true)); 6347 Ops[2] = Builder.CreateBitCast(Ops[2], VTy); 6348 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6349 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy); 6350 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6351 return Builder.CreateBitCast(Result, Ty); 6352 } 6353 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6354 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6355 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6356 6357 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(), 6358 VTy->getNumElements() * 2); 6359 Ops[2] = Builder.CreateBitCast(Ops[2], STy); 6360 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), 6361 cast<ConstantInt>(Ops[3])); 6362 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane"); 6363 6364 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6365 } 6366 case NEON::BI__builtin_neon_vfmaq_laneq_v: { 6367 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6368 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6369 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 6370 6371 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 6372 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3])); 6373 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]}); 6374 } 6375 case NEON::BI__builtin_neon_vfmas_lane_f32: 6376 case NEON::BI__builtin_neon_vfmas_laneq_f32: 6377 case NEON::BI__builtin_neon_vfmad_lane_f64: 6378 case NEON::BI__builtin_neon_vfmad_laneq_f64: { 6379 Ops.push_back(EmitScalarExpr(E->getArg(3))); 6380 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext())); 6381 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty); 6382 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract"); 6383 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]}); 6384 } 6385 case NEON::BI__builtin_neon_vmull_v: 6386 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6387 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull; 6388 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull; 6389 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull"); 6390 case NEON::BI__builtin_neon_vmax_v: 6391 case NEON::BI__builtin_neon_vmaxq_v: 6392 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6393 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax; 6394 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax; 6395 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax"); 6396 case NEON::BI__builtin_neon_vmin_v: 6397 case NEON::BI__builtin_neon_vminq_v: 6398 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6399 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin; 6400 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin; 6401 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin"); 6402 case NEON::BI__builtin_neon_vabd_v: 6403 case NEON::BI__builtin_neon_vabdq_v: 6404 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6405 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd; 6406 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd; 6407 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd"); 6408 case NEON::BI__builtin_neon_vpadal_v: 6409 case NEON::BI__builtin_neon_vpadalq_v: { 6410 unsigned ArgElts = VTy->getNumElements(); 6411 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType()); 6412 unsigned BitWidth = EltTy->getBitWidth(); 6413 llvm::Type *ArgTy = llvm::VectorType::get( 6414 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts); 6415 llvm::Type* Tys[2] = { VTy, ArgTy }; 6416 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp; 6417 SmallVector<llvm::Value*, 1> TmpOps; 6418 TmpOps.push_back(Ops[1]); 6419 Function *F = CGM.getIntrinsic(Int, Tys); 6420 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal"); 6421 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType()); 6422 return Builder.CreateAdd(tmp, addend); 6423 } 6424 case NEON::BI__builtin_neon_vpmin_v: 6425 case NEON::BI__builtin_neon_vpminq_v: 6426 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6427 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp; 6428 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp; 6429 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin"); 6430 case NEON::BI__builtin_neon_vpmax_v: 6431 case NEON::BI__builtin_neon_vpmaxq_v: 6432 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics. 6433 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp; 6434 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp; 6435 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax"); 6436 case NEON::BI__builtin_neon_vminnm_v: 6437 case NEON::BI__builtin_neon_vminnmq_v: 6438 Int = Intrinsic::aarch64_neon_fminnm; 6439 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm"); 6440 case NEON::BI__builtin_neon_vmaxnm_v: 6441 case NEON::BI__builtin_neon_vmaxnmq_v: 6442 Int = Intrinsic::aarch64_neon_fmaxnm; 6443 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm"); 6444 case NEON::BI__builtin_neon_vrecpss_f32: { 6445 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6446 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy), 6447 Ops, "vrecps"); 6448 } 6449 case NEON::BI__builtin_neon_vrecpsd_f64: { 6450 Ops.push_back(EmitScalarExpr(E->getArg(1))); 6451 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy), 6452 Ops, "vrecps"); 6453 } 6454 case NEON::BI__builtin_neon_vqshrun_n_v: 6455 Int = Intrinsic::aarch64_neon_sqshrun; 6456 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n"); 6457 case NEON::BI__builtin_neon_vqrshrun_n_v: 6458 Int = Intrinsic::aarch64_neon_sqrshrun; 6459 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n"); 6460 case NEON::BI__builtin_neon_vqshrn_n_v: 6461 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn; 6462 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n"); 6463 case NEON::BI__builtin_neon_vrshrn_n_v: 6464 Int = Intrinsic::aarch64_neon_rshrn; 6465 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n"); 6466 case NEON::BI__builtin_neon_vqrshrn_n_v: 6467 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn; 6468 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n"); 6469 case NEON::BI__builtin_neon_vrnda_v: 6470 case NEON::BI__builtin_neon_vrndaq_v: { 6471 Int = Intrinsic::round; 6472 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda"); 6473 } 6474 case NEON::BI__builtin_neon_vrndi_v: 6475 case NEON::BI__builtin_neon_vrndiq_v: { 6476 Int = Intrinsic::nearbyint; 6477 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi"); 6478 } 6479 case NEON::BI__builtin_neon_vrndm_v: 6480 case NEON::BI__builtin_neon_vrndmq_v: { 6481 Int = Intrinsic::floor; 6482 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm"); 6483 } 6484 case NEON::BI__builtin_neon_vrndn_v: 6485 case NEON::BI__builtin_neon_vrndnq_v: { 6486 Int = Intrinsic::aarch64_neon_frintn; 6487 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn"); 6488 } 6489 case NEON::BI__builtin_neon_vrndp_v: 6490 case NEON::BI__builtin_neon_vrndpq_v: { 6491 Int = Intrinsic::ceil; 6492 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp"); 6493 } 6494 case NEON::BI__builtin_neon_vrndx_v: 6495 case NEON::BI__builtin_neon_vrndxq_v: { 6496 Int = Intrinsic::rint; 6497 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx"); 6498 } 6499 case NEON::BI__builtin_neon_vrnd_v: 6500 case NEON::BI__builtin_neon_vrndq_v: { 6501 Int = Intrinsic::trunc; 6502 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz"); 6503 } 6504 case NEON::BI__builtin_neon_vceqz_v: 6505 case NEON::BI__builtin_neon_vceqzq_v: 6506 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ, 6507 ICmpInst::ICMP_EQ, "vceqz"); 6508 case NEON::BI__builtin_neon_vcgez_v: 6509 case NEON::BI__builtin_neon_vcgezq_v: 6510 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE, 6511 ICmpInst::ICMP_SGE, "vcgez"); 6512 case NEON::BI__builtin_neon_vclez_v: 6513 case NEON::BI__builtin_neon_vclezq_v: 6514 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE, 6515 ICmpInst::ICMP_SLE, "vclez"); 6516 case NEON::BI__builtin_neon_vcgtz_v: 6517 case NEON::BI__builtin_neon_vcgtzq_v: 6518 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT, 6519 ICmpInst::ICMP_SGT, "vcgtz"); 6520 case NEON::BI__builtin_neon_vcltz_v: 6521 case NEON::BI__builtin_neon_vcltzq_v: 6522 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT, 6523 ICmpInst::ICMP_SLT, "vcltz"); 6524 case NEON::BI__builtin_neon_vcvt_f64_v: 6525 case NEON::BI__builtin_neon_vcvtq_f64_v: 6526 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6527 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad)); 6528 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt") 6529 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt"); 6530 case NEON::BI__builtin_neon_vcvt_f64_f32: { 6531 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad && 6532 "unexpected vcvt_f64_f32 builtin"); 6533 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false); 6534 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6535 6536 return Builder.CreateFPExt(Ops[0], Ty, "vcvt"); 6537 } 6538 case NEON::BI__builtin_neon_vcvt_f32_f64: { 6539 assert(Type.getEltType() == NeonTypeFlags::Float32 && 6540 "unexpected vcvt_f32_f64 builtin"); 6541 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true); 6542 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag)); 6543 6544 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt"); 6545 } 6546 case NEON::BI__builtin_neon_vcvt_s32_v: 6547 case NEON::BI__builtin_neon_vcvt_u32_v: 6548 case NEON::BI__builtin_neon_vcvt_s64_v: 6549 case NEON::BI__builtin_neon_vcvt_u64_v: 6550 case NEON::BI__builtin_neon_vcvtq_s32_v: 6551 case NEON::BI__builtin_neon_vcvtq_u32_v: 6552 case NEON::BI__builtin_neon_vcvtq_s64_v: 6553 case NEON::BI__builtin_neon_vcvtq_u64_v: { 6554 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type)); 6555 if (usgn) 6556 return Builder.CreateFPToUI(Ops[0], Ty); 6557 return Builder.CreateFPToSI(Ops[0], Ty); 6558 } 6559 case NEON::BI__builtin_neon_vcvta_s32_v: 6560 case NEON::BI__builtin_neon_vcvtaq_s32_v: 6561 case NEON::BI__builtin_neon_vcvta_u32_v: 6562 case NEON::BI__builtin_neon_vcvtaq_u32_v: 6563 case NEON::BI__builtin_neon_vcvta_s64_v: 6564 case NEON::BI__builtin_neon_vcvtaq_s64_v: 6565 case NEON::BI__builtin_neon_vcvta_u64_v: 6566 case NEON::BI__builtin_neon_vcvtaq_u64_v: { 6567 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas; 6568 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6569 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta"); 6570 } 6571 case NEON::BI__builtin_neon_vcvtm_s32_v: 6572 case NEON::BI__builtin_neon_vcvtmq_s32_v: 6573 case NEON::BI__builtin_neon_vcvtm_u32_v: 6574 case NEON::BI__builtin_neon_vcvtmq_u32_v: 6575 case NEON::BI__builtin_neon_vcvtm_s64_v: 6576 case NEON::BI__builtin_neon_vcvtmq_s64_v: 6577 case NEON::BI__builtin_neon_vcvtm_u64_v: 6578 case NEON::BI__builtin_neon_vcvtmq_u64_v: { 6579 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms; 6580 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6581 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm"); 6582 } 6583 case NEON::BI__builtin_neon_vcvtn_s32_v: 6584 case NEON::BI__builtin_neon_vcvtnq_s32_v: 6585 case NEON::BI__builtin_neon_vcvtn_u32_v: 6586 case NEON::BI__builtin_neon_vcvtnq_u32_v: 6587 case NEON::BI__builtin_neon_vcvtn_s64_v: 6588 case NEON::BI__builtin_neon_vcvtnq_s64_v: 6589 case NEON::BI__builtin_neon_vcvtn_u64_v: 6590 case NEON::BI__builtin_neon_vcvtnq_u64_v: { 6591 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns; 6592 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6593 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn"); 6594 } 6595 case NEON::BI__builtin_neon_vcvtp_s32_v: 6596 case NEON::BI__builtin_neon_vcvtpq_s32_v: 6597 case NEON::BI__builtin_neon_vcvtp_u32_v: 6598 case NEON::BI__builtin_neon_vcvtpq_u32_v: 6599 case NEON::BI__builtin_neon_vcvtp_s64_v: 6600 case NEON::BI__builtin_neon_vcvtpq_s64_v: 6601 case NEON::BI__builtin_neon_vcvtp_u64_v: 6602 case NEON::BI__builtin_neon_vcvtpq_u64_v: { 6603 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps; 6604 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) }; 6605 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp"); 6606 } 6607 case NEON::BI__builtin_neon_vmulx_v: 6608 case NEON::BI__builtin_neon_vmulxq_v: { 6609 Int = Intrinsic::aarch64_neon_fmulx; 6610 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx"); 6611 } 6612 case NEON::BI__builtin_neon_vmul_lane_v: 6613 case NEON::BI__builtin_neon_vmul_laneq_v: { 6614 // v1f64 vmul_lane should be mapped to Neon scalar mul lane 6615 bool Quad = false; 6616 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v) 6617 Quad = true; 6618 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6619 llvm::Type *VTy = GetNeonType(this, 6620 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad)); 6621 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 6622 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract"); 6623 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]); 6624 return Builder.CreateBitCast(Result, Ty); 6625 } 6626 case NEON::BI__builtin_neon_vnegd_s64: 6627 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd"); 6628 case NEON::BI__builtin_neon_vpmaxnm_v: 6629 case NEON::BI__builtin_neon_vpmaxnmq_v: { 6630 Int = Intrinsic::aarch64_neon_fmaxnmp; 6631 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm"); 6632 } 6633 case NEON::BI__builtin_neon_vpminnm_v: 6634 case NEON::BI__builtin_neon_vpminnmq_v: { 6635 Int = Intrinsic::aarch64_neon_fminnmp; 6636 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm"); 6637 } 6638 case NEON::BI__builtin_neon_vsqrt_v: 6639 case NEON::BI__builtin_neon_vsqrtq_v: { 6640 Int = Intrinsic::sqrt; 6641 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6642 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt"); 6643 } 6644 case NEON::BI__builtin_neon_vrbit_v: 6645 case NEON::BI__builtin_neon_vrbitq_v: { 6646 Int = Intrinsic::aarch64_neon_rbit; 6647 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit"); 6648 } 6649 case NEON::BI__builtin_neon_vaddv_u8: 6650 // FIXME: These are handled by the AArch64 scalar code. 6651 usgn = true; 6652 // FALLTHROUGH 6653 case NEON::BI__builtin_neon_vaddv_s8: { 6654 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6655 Ty = Int32Ty; 6656 VTy = llvm::VectorType::get(Int8Ty, 8); 6657 llvm::Type *Tys[2] = { Ty, VTy }; 6658 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6659 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6660 return Builder.CreateTrunc(Ops[0], Int8Ty); 6661 } 6662 case NEON::BI__builtin_neon_vaddv_u16: 6663 usgn = true; 6664 // FALLTHROUGH 6665 case NEON::BI__builtin_neon_vaddv_s16: { 6666 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6667 Ty = Int32Ty; 6668 VTy = llvm::VectorType::get(Int16Ty, 4); 6669 llvm::Type *Tys[2] = { Ty, VTy }; 6670 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6671 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6672 return Builder.CreateTrunc(Ops[0], Int16Ty); 6673 } 6674 case NEON::BI__builtin_neon_vaddvq_u8: 6675 usgn = true; 6676 // FALLTHROUGH 6677 case NEON::BI__builtin_neon_vaddvq_s8: { 6678 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6679 Ty = Int32Ty; 6680 VTy = llvm::VectorType::get(Int8Ty, 16); 6681 llvm::Type *Tys[2] = { Ty, VTy }; 6682 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6683 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6684 return Builder.CreateTrunc(Ops[0], Int8Ty); 6685 } 6686 case NEON::BI__builtin_neon_vaddvq_u16: 6687 usgn = true; 6688 // FALLTHROUGH 6689 case NEON::BI__builtin_neon_vaddvq_s16: { 6690 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv; 6691 Ty = Int32Ty; 6692 VTy = llvm::VectorType::get(Int16Ty, 8); 6693 llvm::Type *Tys[2] = { Ty, VTy }; 6694 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6695 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv"); 6696 return Builder.CreateTrunc(Ops[0], Int16Ty); 6697 } 6698 case NEON::BI__builtin_neon_vmaxv_u8: { 6699 Int = Intrinsic::aarch64_neon_umaxv; 6700 Ty = Int32Ty; 6701 VTy = llvm::VectorType::get(Int8Ty, 8); 6702 llvm::Type *Tys[2] = { Ty, VTy }; 6703 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6704 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6705 return Builder.CreateTrunc(Ops[0], Int8Ty); 6706 } 6707 case NEON::BI__builtin_neon_vmaxv_u16: { 6708 Int = Intrinsic::aarch64_neon_umaxv; 6709 Ty = Int32Ty; 6710 VTy = llvm::VectorType::get(Int16Ty, 4); 6711 llvm::Type *Tys[2] = { Ty, VTy }; 6712 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6713 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6714 return Builder.CreateTrunc(Ops[0], Int16Ty); 6715 } 6716 case NEON::BI__builtin_neon_vmaxvq_u8: { 6717 Int = Intrinsic::aarch64_neon_umaxv; 6718 Ty = Int32Ty; 6719 VTy = llvm::VectorType::get(Int8Ty, 16); 6720 llvm::Type *Tys[2] = { Ty, VTy }; 6721 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6722 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6723 return Builder.CreateTrunc(Ops[0], Int8Ty); 6724 } 6725 case NEON::BI__builtin_neon_vmaxvq_u16: { 6726 Int = Intrinsic::aarch64_neon_umaxv; 6727 Ty = Int32Ty; 6728 VTy = llvm::VectorType::get(Int16Ty, 8); 6729 llvm::Type *Tys[2] = { Ty, VTy }; 6730 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6731 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6732 return Builder.CreateTrunc(Ops[0], Int16Ty); 6733 } 6734 case NEON::BI__builtin_neon_vmaxv_s8: { 6735 Int = Intrinsic::aarch64_neon_smaxv; 6736 Ty = Int32Ty; 6737 VTy = llvm::VectorType::get(Int8Ty, 8); 6738 llvm::Type *Tys[2] = { Ty, VTy }; 6739 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6740 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6741 return Builder.CreateTrunc(Ops[0], Int8Ty); 6742 } 6743 case NEON::BI__builtin_neon_vmaxv_s16: { 6744 Int = Intrinsic::aarch64_neon_smaxv; 6745 Ty = Int32Ty; 6746 VTy = llvm::VectorType::get(Int16Ty, 4); 6747 llvm::Type *Tys[2] = { Ty, VTy }; 6748 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6749 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6750 return Builder.CreateTrunc(Ops[0], Int16Ty); 6751 } 6752 case NEON::BI__builtin_neon_vmaxvq_s8: { 6753 Int = Intrinsic::aarch64_neon_smaxv; 6754 Ty = Int32Ty; 6755 VTy = llvm::VectorType::get(Int8Ty, 16); 6756 llvm::Type *Tys[2] = { Ty, VTy }; 6757 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6758 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6759 return Builder.CreateTrunc(Ops[0], Int8Ty); 6760 } 6761 case NEON::BI__builtin_neon_vmaxvq_s16: { 6762 Int = Intrinsic::aarch64_neon_smaxv; 6763 Ty = Int32Ty; 6764 VTy = llvm::VectorType::get(Int16Ty, 8); 6765 llvm::Type *Tys[2] = { Ty, VTy }; 6766 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6767 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv"); 6768 return Builder.CreateTrunc(Ops[0], Int16Ty); 6769 } 6770 case NEON::BI__builtin_neon_vminv_u8: { 6771 Int = Intrinsic::aarch64_neon_uminv; 6772 Ty = Int32Ty; 6773 VTy = llvm::VectorType::get(Int8Ty, 8); 6774 llvm::Type *Tys[2] = { Ty, VTy }; 6775 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6776 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6777 return Builder.CreateTrunc(Ops[0], Int8Ty); 6778 } 6779 case NEON::BI__builtin_neon_vminv_u16: { 6780 Int = Intrinsic::aarch64_neon_uminv; 6781 Ty = Int32Ty; 6782 VTy = llvm::VectorType::get(Int16Ty, 4); 6783 llvm::Type *Tys[2] = { Ty, VTy }; 6784 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6785 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6786 return Builder.CreateTrunc(Ops[0], Int16Ty); 6787 } 6788 case NEON::BI__builtin_neon_vminvq_u8: { 6789 Int = Intrinsic::aarch64_neon_uminv; 6790 Ty = Int32Ty; 6791 VTy = llvm::VectorType::get(Int8Ty, 16); 6792 llvm::Type *Tys[2] = { Ty, VTy }; 6793 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6794 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6795 return Builder.CreateTrunc(Ops[0], Int8Ty); 6796 } 6797 case NEON::BI__builtin_neon_vminvq_u16: { 6798 Int = Intrinsic::aarch64_neon_uminv; 6799 Ty = Int32Ty; 6800 VTy = llvm::VectorType::get(Int16Ty, 8); 6801 llvm::Type *Tys[2] = { Ty, VTy }; 6802 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6803 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6804 return Builder.CreateTrunc(Ops[0], Int16Ty); 6805 } 6806 case NEON::BI__builtin_neon_vminv_s8: { 6807 Int = Intrinsic::aarch64_neon_sminv; 6808 Ty = Int32Ty; 6809 VTy = llvm::VectorType::get(Int8Ty, 8); 6810 llvm::Type *Tys[2] = { Ty, VTy }; 6811 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6812 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6813 return Builder.CreateTrunc(Ops[0], Int8Ty); 6814 } 6815 case NEON::BI__builtin_neon_vminv_s16: { 6816 Int = Intrinsic::aarch64_neon_sminv; 6817 Ty = Int32Ty; 6818 VTy = llvm::VectorType::get(Int16Ty, 4); 6819 llvm::Type *Tys[2] = { Ty, VTy }; 6820 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6821 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6822 return Builder.CreateTrunc(Ops[0], Int16Ty); 6823 } 6824 case NEON::BI__builtin_neon_vminvq_s8: { 6825 Int = Intrinsic::aarch64_neon_sminv; 6826 Ty = Int32Ty; 6827 VTy = llvm::VectorType::get(Int8Ty, 16); 6828 llvm::Type *Tys[2] = { Ty, VTy }; 6829 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6830 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6831 return Builder.CreateTrunc(Ops[0], Int8Ty); 6832 } 6833 case NEON::BI__builtin_neon_vminvq_s16: { 6834 Int = Intrinsic::aarch64_neon_sminv; 6835 Ty = Int32Ty; 6836 VTy = llvm::VectorType::get(Int16Ty, 8); 6837 llvm::Type *Tys[2] = { Ty, VTy }; 6838 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6839 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv"); 6840 return Builder.CreateTrunc(Ops[0], Int16Ty); 6841 } 6842 case NEON::BI__builtin_neon_vmul_n_f64: { 6843 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy); 6844 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy); 6845 return Builder.CreateFMul(Ops[0], RHS); 6846 } 6847 case NEON::BI__builtin_neon_vaddlv_u8: { 6848 Int = Intrinsic::aarch64_neon_uaddlv; 6849 Ty = Int32Ty; 6850 VTy = llvm::VectorType::get(Int8Ty, 8); 6851 llvm::Type *Tys[2] = { Ty, VTy }; 6852 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6853 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6854 return Builder.CreateTrunc(Ops[0], Int16Ty); 6855 } 6856 case NEON::BI__builtin_neon_vaddlv_u16: { 6857 Int = Intrinsic::aarch64_neon_uaddlv; 6858 Ty = Int32Ty; 6859 VTy = llvm::VectorType::get(Int16Ty, 4); 6860 llvm::Type *Tys[2] = { Ty, VTy }; 6861 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6862 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6863 } 6864 case NEON::BI__builtin_neon_vaddlvq_u8: { 6865 Int = Intrinsic::aarch64_neon_uaddlv; 6866 Ty = Int32Ty; 6867 VTy = llvm::VectorType::get(Int8Ty, 16); 6868 llvm::Type *Tys[2] = { Ty, VTy }; 6869 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6870 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6871 return Builder.CreateTrunc(Ops[0], Int16Ty); 6872 } 6873 case NEON::BI__builtin_neon_vaddlvq_u16: { 6874 Int = Intrinsic::aarch64_neon_uaddlv; 6875 Ty = Int32Ty; 6876 VTy = llvm::VectorType::get(Int16Ty, 8); 6877 llvm::Type *Tys[2] = { Ty, VTy }; 6878 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6879 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6880 } 6881 case NEON::BI__builtin_neon_vaddlv_s8: { 6882 Int = Intrinsic::aarch64_neon_saddlv; 6883 Ty = Int32Ty; 6884 VTy = llvm::VectorType::get(Int8Ty, 8); 6885 llvm::Type *Tys[2] = { Ty, VTy }; 6886 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6887 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6888 return Builder.CreateTrunc(Ops[0], Int16Ty); 6889 } 6890 case NEON::BI__builtin_neon_vaddlv_s16: { 6891 Int = Intrinsic::aarch64_neon_saddlv; 6892 Ty = Int32Ty; 6893 VTy = llvm::VectorType::get(Int16Ty, 4); 6894 llvm::Type *Tys[2] = { Ty, VTy }; 6895 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6896 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6897 } 6898 case NEON::BI__builtin_neon_vaddlvq_s8: { 6899 Int = Intrinsic::aarch64_neon_saddlv; 6900 Ty = Int32Ty; 6901 VTy = llvm::VectorType::get(Int8Ty, 16); 6902 llvm::Type *Tys[2] = { Ty, VTy }; 6903 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6904 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6905 return Builder.CreateTrunc(Ops[0], Int16Ty); 6906 } 6907 case NEON::BI__builtin_neon_vaddlvq_s16: { 6908 Int = Intrinsic::aarch64_neon_saddlv; 6909 Ty = Int32Ty; 6910 VTy = llvm::VectorType::get(Int16Ty, 8); 6911 llvm::Type *Tys[2] = { Ty, VTy }; 6912 Ops.push_back(EmitScalarExpr(E->getArg(0))); 6913 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv"); 6914 } 6915 case NEON::BI__builtin_neon_vsri_n_v: 6916 case NEON::BI__builtin_neon_vsriq_n_v: { 6917 Int = Intrinsic::aarch64_neon_vsri; 6918 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6919 return EmitNeonCall(Intrin, Ops, "vsri_n"); 6920 } 6921 case NEON::BI__builtin_neon_vsli_n_v: 6922 case NEON::BI__builtin_neon_vsliq_n_v: { 6923 Int = Intrinsic::aarch64_neon_vsli; 6924 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty); 6925 return EmitNeonCall(Intrin, Ops, "vsli_n"); 6926 } 6927 case NEON::BI__builtin_neon_vsra_n_v: 6928 case NEON::BI__builtin_neon_vsraq_n_v: 6929 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6930 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n"); 6931 return Builder.CreateAdd(Ops[0], Ops[1]); 6932 case NEON::BI__builtin_neon_vrsra_n_v: 6933 case NEON::BI__builtin_neon_vrsraq_n_v: { 6934 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl; 6935 SmallVector<llvm::Value*,2> TmpOps; 6936 TmpOps.push_back(Ops[1]); 6937 TmpOps.push_back(Ops[2]); 6938 Function* F = CGM.getIntrinsic(Int, Ty); 6939 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true); 6940 Ops[0] = Builder.CreateBitCast(Ops[0], VTy); 6941 return Builder.CreateAdd(Ops[0], tmp); 6942 } 6943 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence 6944 // of an Align parameter here. 6945 case NEON::BI__builtin_neon_vld1_x2_v: 6946 case NEON::BI__builtin_neon_vld1q_x2_v: 6947 case NEON::BI__builtin_neon_vld1_x3_v: 6948 case NEON::BI__builtin_neon_vld1q_x3_v: 6949 case NEON::BI__builtin_neon_vld1_x4_v: 6950 case NEON::BI__builtin_neon_vld1q_x4_v: { 6951 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6952 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 6953 llvm::Type *Tys[2] = { VTy, PTy }; 6954 unsigned Int; 6955 switch (BuiltinID) { 6956 case NEON::BI__builtin_neon_vld1_x2_v: 6957 case NEON::BI__builtin_neon_vld1q_x2_v: 6958 Int = Intrinsic::aarch64_neon_ld1x2; 6959 break; 6960 case NEON::BI__builtin_neon_vld1_x3_v: 6961 case NEON::BI__builtin_neon_vld1q_x3_v: 6962 Int = Intrinsic::aarch64_neon_ld1x3; 6963 break; 6964 case NEON::BI__builtin_neon_vld1_x4_v: 6965 case NEON::BI__builtin_neon_vld1q_x4_v: 6966 Int = Intrinsic::aarch64_neon_ld1x4; 6967 break; 6968 } 6969 Function *F = CGM.getIntrinsic(Int, Tys); 6970 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN"); 6971 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 6972 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 6973 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 6974 } 6975 case NEON::BI__builtin_neon_vst1_x2_v: 6976 case NEON::BI__builtin_neon_vst1q_x2_v: 6977 case NEON::BI__builtin_neon_vst1_x3_v: 6978 case NEON::BI__builtin_neon_vst1q_x3_v: 6979 case NEON::BI__builtin_neon_vst1_x4_v: 6980 case NEON::BI__builtin_neon_vst1q_x4_v: { 6981 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType()); 6982 llvm::Type *Tys[2] = { VTy, PTy }; 6983 unsigned Int; 6984 switch (BuiltinID) { 6985 case NEON::BI__builtin_neon_vst1_x2_v: 6986 case NEON::BI__builtin_neon_vst1q_x2_v: 6987 Int = Intrinsic::aarch64_neon_st1x2; 6988 break; 6989 case NEON::BI__builtin_neon_vst1_x3_v: 6990 case NEON::BI__builtin_neon_vst1q_x3_v: 6991 Int = Intrinsic::aarch64_neon_st1x3; 6992 break; 6993 case NEON::BI__builtin_neon_vst1_x4_v: 6994 case NEON::BI__builtin_neon_vst1q_x4_v: 6995 Int = Intrinsic::aarch64_neon_st1x4; 6996 break; 6997 } 6998 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end()); 6999 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, ""); 7000 } 7001 case NEON::BI__builtin_neon_vld1_v: 7002 case NEON::BI__builtin_neon_vld1q_v: { 7003 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 7004 auto Alignment = CharUnits::fromQuantity( 7005 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16); 7006 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment); 7007 } 7008 case NEON::BI__builtin_neon_vst1_v: 7009 case NEON::BI__builtin_neon_vst1q_v: 7010 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy)); 7011 Ops[1] = Builder.CreateBitCast(Ops[1], VTy); 7012 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7013 case NEON::BI__builtin_neon_vld1_lane_v: 7014 case NEON::BI__builtin_neon_vld1q_lane_v: { 7015 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7016 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7017 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7018 auto Alignment = CharUnits::fromQuantity( 7019 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16); 7020 Ops[0] = 7021 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7022 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane"); 7023 } 7024 case NEON::BI__builtin_neon_vld1_dup_v: 7025 case NEON::BI__builtin_neon_vld1q_dup_v: { 7026 Value *V = UndefValue::get(Ty); 7027 Ty = llvm::PointerType::getUnqual(VTy->getElementType()); 7028 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7029 auto Alignment = CharUnits::fromQuantity( 7030 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16); 7031 Ops[0] = 7032 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment); 7033 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0); 7034 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI); 7035 return EmitNeonSplat(Ops[0], CI); 7036 } 7037 case NEON::BI__builtin_neon_vst1_lane_v: 7038 case NEON::BI__builtin_neon_vst1q_lane_v: 7039 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7040 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); 7041 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7042 return Builder.CreateDefaultAlignedStore(Ops[1], 7043 Builder.CreateBitCast(Ops[0], Ty)); 7044 case NEON::BI__builtin_neon_vld2_v: 7045 case NEON::BI__builtin_neon_vld2q_v: { 7046 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7047 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7048 llvm::Type *Tys[2] = { VTy, PTy }; 7049 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys); 7050 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7051 Ops[0] = Builder.CreateBitCast(Ops[0], 7052 llvm::PointerType::getUnqual(Ops[1]->getType())); 7053 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7054 } 7055 case NEON::BI__builtin_neon_vld3_v: 7056 case NEON::BI__builtin_neon_vld3q_v: { 7057 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7058 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7059 llvm::Type *Tys[2] = { VTy, PTy }; 7060 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys); 7061 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7062 Ops[0] = Builder.CreateBitCast(Ops[0], 7063 llvm::PointerType::getUnqual(Ops[1]->getType())); 7064 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7065 } 7066 case NEON::BI__builtin_neon_vld4_v: 7067 case NEON::BI__builtin_neon_vld4q_v: { 7068 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy); 7069 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7070 llvm::Type *Tys[2] = { VTy, PTy }; 7071 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys); 7072 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7073 Ops[0] = Builder.CreateBitCast(Ops[0], 7074 llvm::PointerType::getUnqual(Ops[1]->getType())); 7075 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7076 } 7077 case NEON::BI__builtin_neon_vld2_dup_v: 7078 case NEON::BI__builtin_neon_vld2q_dup_v: { 7079 llvm::Type *PTy = 7080 llvm::PointerType::getUnqual(VTy->getElementType()); 7081 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7082 llvm::Type *Tys[2] = { VTy, PTy }; 7083 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys); 7084 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2"); 7085 Ops[0] = Builder.CreateBitCast(Ops[0], 7086 llvm::PointerType::getUnqual(Ops[1]->getType())); 7087 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7088 } 7089 case NEON::BI__builtin_neon_vld3_dup_v: 7090 case NEON::BI__builtin_neon_vld3q_dup_v: { 7091 llvm::Type *PTy = 7092 llvm::PointerType::getUnqual(VTy->getElementType()); 7093 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7094 llvm::Type *Tys[2] = { VTy, PTy }; 7095 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys); 7096 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3"); 7097 Ops[0] = Builder.CreateBitCast(Ops[0], 7098 llvm::PointerType::getUnqual(Ops[1]->getType())); 7099 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7100 } 7101 case NEON::BI__builtin_neon_vld4_dup_v: 7102 case NEON::BI__builtin_neon_vld4q_dup_v: { 7103 llvm::Type *PTy = 7104 llvm::PointerType::getUnqual(VTy->getElementType()); 7105 Ops[1] = Builder.CreateBitCast(Ops[1], PTy); 7106 llvm::Type *Tys[2] = { VTy, PTy }; 7107 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys); 7108 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4"); 7109 Ops[0] = Builder.CreateBitCast(Ops[0], 7110 llvm::PointerType::getUnqual(Ops[1]->getType())); 7111 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7112 } 7113 case NEON::BI__builtin_neon_vld2_lane_v: 7114 case NEON::BI__builtin_neon_vld2q_lane_v: { 7115 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7116 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys); 7117 Ops.push_back(Ops[1]); 7118 Ops.erase(Ops.begin()+1); 7119 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7120 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7121 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7122 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane"); 7123 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7124 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7125 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7126 } 7127 case NEON::BI__builtin_neon_vld3_lane_v: 7128 case NEON::BI__builtin_neon_vld3q_lane_v: { 7129 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7130 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys); 7131 Ops.push_back(Ops[1]); 7132 Ops.erase(Ops.begin()+1); 7133 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7134 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7135 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7136 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7137 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane"); 7138 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7139 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7140 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7141 } 7142 case NEON::BI__builtin_neon_vld4_lane_v: 7143 case NEON::BI__builtin_neon_vld4q_lane_v: { 7144 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() }; 7145 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys); 7146 Ops.push_back(Ops[1]); 7147 Ops.erase(Ops.begin()+1); 7148 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7149 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7150 Ops[3] = Builder.CreateBitCast(Ops[3], Ty); 7151 Ops[4] = Builder.CreateBitCast(Ops[4], Ty); 7152 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty); 7153 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane"); 7154 Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); 7155 Ops[0] = Builder.CreateBitCast(Ops[0], Ty); 7156 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 7157 } 7158 case NEON::BI__builtin_neon_vst2_v: 7159 case NEON::BI__builtin_neon_vst2q_v: { 7160 Ops.push_back(Ops[0]); 7161 Ops.erase(Ops.begin()); 7162 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() }; 7163 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys), 7164 Ops, ""); 7165 } 7166 case NEON::BI__builtin_neon_vst2_lane_v: 7167 case NEON::BI__builtin_neon_vst2q_lane_v: { 7168 Ops.push_back(Ops[0]); 7169 Ops.erase(Ops.begin()); 7170 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty); 7171 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7172 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys), 7173 Ops, ""); 7174 } 7175 case NEON::BI__builtin_neon_vst3_v: 7176 case NEON::BI__builtin_neon_vst3q_v: { 7177 Ops.push_back(Ops[0]); 7178 Ops.erase(Ops.begin()); 7179 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() }; 7180 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys), 7181 Ops, ""); 7182 } 7183 case NEON::BI__builtin_neon_vst3_lane_v: 7184 case NEON::BI__builtin_neon_vst3q_lane_v: { 7185 Ops.push_back(Ops[0]); 7186 Ops.erase(Ops.begin()); 7187 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty); 7188 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7189 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys), 7190 Ops, ""); 7191 } 7192 case NEON::BI__builtin_neon_vst4_v: 7193 case NEON::BI__builtin_neon_vst4q_v: { 7194 Ops.push_back(Ops[0]); 7195 Ops.erase(Ops.begin()); 7196 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() }; 7197 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys), 7198 Ops, ""); 7199 } 7200 case NEON::BI__builtin_neon_vst4_lane_v: 7201 case NEON::BI__builtin_neon_vst4q_lane_v: { 7202 Ops.push_back(Ops[0]); 7203 Ops.erase(Ops.begin()); 7204 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty); 7205 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() }; 7206 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys), 7207 Ops, ""); 7208 } 7209 case NEON::BI__builtin_neon_vtrn_v: 7210 case NEON::BI__builtin_neon_vtrnq_v: { 7211 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7212 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7213 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7214 Value *SV = nullptr; 7215 7216 for (unsigned vi = 0; vi != 2; ++vi) { 7217 SmallVector<uint32_t, 16> Indices; 7218 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7219 Indices.push_back(i+vi); 7220 Indices.push_back(i+e+vi); 7221 } 7222 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7223 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn"); 7224 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7225 } 7226 return SV; 7227 } 7228 case NEON::BI__builtin_neon_vuzp_v: 7229 case NEON::BI__builtin_neon_vuzpq_v: { 7230 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7231 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7232 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7233 Value *SV = nullptr; 7234 7235 for (unsigned vi = 0; vi != 2; ++vi) { 7236 SmallVector<uint32_t, 16> Indices; 7237 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i) 7238 Indices.push_back(2*i+vi); 7239 7240 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7241 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp"); 7242 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7243 } 7244 return SV; 7245 } 7246 case NEON::BI__builtin_neon_vzip_v: 7247 case NEON::BI__builtin_neon_vzipq_v: { 7248 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty)); 7249 Ops[1] = Builder.CreateBitCast(Ops[1], Ty); 7250 Ops[2] = Builder.CreateBitCast(Ops[2], Ty); 7251 Value *SV = nullptr; 7252 7253 for (unsigned vi = 0; vi != 2; ++vi) { 7254 SmallVector<uint32_t, 16> Indices; 7255 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) { 7256 Indices.push_back((i + vi*e) >> 1); 7257 Indices.push_back(((i + vi*e) >> 1)+e); 7258 } 7259 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi); 7260 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip"); 7261 SV = Builder.CreateDefaultAlignedStore(SV, Addr); 7262 } 7263 return SV; 7264 } 7265 case NEON::BI__builtin_neon_vqtbl1q_v: { 7266 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty), 7267 Ops, "vtbl1"); 7268 } 7269 case NEON::BI__builtin_neon_vqtbl2q_v: { 7270 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty), 7271 Ops, "vtbl2"); 7272 } 7273 case NEON::BI__builtin_neon_vqtbl3q_v: { 7274 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty), 7275 Ops, "vtbl3"); 7276 } 7277 case NEON::BI__builtin_neon_vqtbl4q_v: { 7278 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty), 7279 Ops, "vtbl4"); 7280 } 7281 case NEON::BI__builtin_neon_vqtbx1q_v: { 7282 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty), 7283 Ops, "vtbx1"); 7284 } 7285 case NEON::BI__builtin_neon_vqtbx2q_v: { 7286 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty), 7287 Ops, "vtbx2"); 7288 } 7289 case NEON::BI__builtin_neon_vqtbx3q_v: { 7290 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty), 7291 Ops, "vtbx3"); 7292 } 7293 case NEON::BI__builtin_neon_vqtbx4q_v: { 7294 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty), 7295 Ops, "vtbx4"); 7296 } 7297 case NEON::BI__builtin_neon_vsqadd_v: 7298 case NEON::BI__builtin_neon_vsqaddq_v: { 7299 Int = Intrinsic::aarch64_neon_usqadd; 7300 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd"); 7301 } 7302 case NEON::BI__builtin_neon_vuqadd_v: 7303 case NEON::BI__builtin_neon_vuqaddq_v: { 7304 Int = Intrinsic::aarch64_neon_suqadd; 7305 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd"); 7306 } 7307 } 7308 } 7309 7310 llvm::Value *CodeGenFunction:: 7311 BuildVector(ArrayRef<llvm::Value*> Ops) { 7312 assert((Ops.size() & (Ops.size() - 1)) == 0 && 7313 "Not a power-of-two sized vector!"); 7314 bool AllConstants = true; 7315 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i) 7316 AllConstants &= isa<Constant>(Ops[i]); 7317 7318 // If this is a constant vector, create a ConstantVector. 7319 if (AllConstants) { 7320 SmallVector<llvm::Constant*, 16> CstOps; 7321 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7322 CstOps.push_back(cast<Constant>(Ops[i])); 7323 return llvm::ConstantVector::get(CstOps); 7324 } 7325 7326 // Otherwise, insertelement the values to build the vector. 7327 Value *Result = 7328 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size())); 7329 7330 for (unsigned i = 0, e = Ops.size(); i != e; ++i) 7331 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i)); 7332 7333 return Result; 7334 } 7335 7336 // Convert the mask from an integer type to a vector of i1. 7337 static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask, 7338 unsigned NumElts) { 7339 7340 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(), 7341 cast<IntegerType>(Mask->getType())->getBitWidth()); 7342 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy); 7343 7344 // If we have less than 8 elements, then the starting mask was an i8 and 7345 // we need to extract down to the right number of elements. 7346 if (NumElts < 8) { 7347 uint32_t Indices[4]; 7348 for (unsigned i = 0; i != NumElts; ++i) 7349 Indices[i] = i; 7350 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec, 7351 makeArrayRef(Indices, NumElts), 7352 "extract"); 7353 } 7354 return MaskVec; 7355 } 7356 7357 static Value *EmitX86MaskedStore(CodeGenFunction &CGF, 7358 SmallVectorImpl<Value *> &Ops, 7359 unsigned Align) { 7360 // Cast the pointer to right type. 7361 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7362 llvm::PointerType::getUnqual(Ops[1]->getType())); 7363 7364 // If the mask is all ones just emit a regular store. 7365 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7366 if (C->isAllOnesValue()) 7367 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align); 7368 7369 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7370 Ops[1]->getType()->getVectorNumElements()); 7371 7372 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec); 7373 } 7374 7375 static Value *EmitX86MaskedLoad(CodeGenFunction &CGF, 7376 SmallVectorImpl<Value *> &Ops, unsigned Align) { 7377 // Cast the pointer to right type. 7378 Ops[0] = CGF.Builder.CreateBitCast(Ops[0], 7379 llvm::PointerType::getUnqual(Ops[1]->getType())); 7380 7381 // If the mask is all ones just emit a regular store. 7382 if (const auto *C = dyn_cast<Constant>(Ops[2])) 7383 if (C->isAllOnesValue()) 7384 return CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7385 7386 Value *MaskVec = getMaskVecValue(CGF, Ops[2], 7387 Ops[1]->getType()->getVectorNumElements()); 7388 7389 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]); 7390 } 7391 7392 static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF, 7393 SmallVectorImpl<Value *> &Ops, 7394 llvm::Type *DstTy, 7395 unsigned SrcSizeInBits, 7396 unsigned Align) { 7397 // Load the subvector. 7398 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align); 7399 7400 // Create broadcast mask. 7401 unsigned NumDstElts = DstTy->getVectorNumElements(); 7402 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits(); 7403 7404 SmallVector<uint32_t, 8> Mask; 7405 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts) 7406 for (unsigned j = 0; j != NumSrcElts; ++j) 7407 Mask.push_back(j); 7408 7409 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst"); 7410 } 7411 7412 static Value *EmitX86Select(CodeGenFunction &CGF, 7413 Value *Mask, Value *Op0, Value *Op1) { 7414 7415 // If the mask is all ones just return first argument. 7416 if (const auto *C = dyn_cast<Constant>(Mask)) 7417 if (C->isAllOnesValue()) 7418 return Op0; 7419 7420 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements()); 7421 7422 return CGF.Builder.CreateSelect(Mask, Op0, Op1); 7423 } 7424 7425 static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC, 7426 bool Signed, SmallVectorImpl<Value *> &Ops) { 7427 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 7428 Value *Cmp; 7429 7430 if (CC == 3) { 7431 Cmp = Constant::getNullValue( 7432 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7433 } else if (CC == 7) { 7434 Cmp = Constant::getAllOnesValue( 7435 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts)); 7436 } else { 7437 ICmpInst::Predicate Pred; 7438 switch (CC) { 7439 default: llvm_unreachable("Unknown condition code"); 7440 case 0: Pred = ICmpInst::ICMP_EQ; break; 7441 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break; 7442 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break; 7443 case 4: Pred = ICmpInst::ICMP_NE; break; 7444 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break; 7445 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; 7446 } 7447 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7448 } 7449 7450 const auto *C = dyn_cast<Constant>(Ops.back()); 7451 if (!C || !C->isAllOnesValue()) 7452 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts)); 7453 7454 if (NumElts < 8) { 7455 uint32_t Indices[8]; 7456 for (unsigned i = 0; i != NumElts; ++i) 7457 Indices[i] = i; 7458 for (unsigned i = NumElts; i != 8; ++i) 7459 Indices[i] = i % NumElts + NumElts; 7460 Cmp = CGF.Builder.CreateShuffleVector( 7461 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices); 7462 } 7463 return CGF.Builder.CreateBitCast(Cmp, 7464 IntegerType::get(CGF.getLLVMContext(), 7465 std::max(NumElts, 8U))); 7466 } 7467 7468 static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef<Value *> Ops) { 7469 7470 llvm::Type *Ty = Ops[0]->getType(); 7471 Value *Zero = llvm::Constant::getNullValue(Ty); 7472 Value *Sub = CGF.Builder.CreateSub(Zero, Ops[0]); 7473 Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Zero); 7474 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Sub); 7475 if (Ops.size() == 1) 7476 return Res; 7477 return EmitX86Select(CGF, Ops[2], Res, Ops[1]); 7478 } 7479 7480 static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred, 7481 ArrayRef<Value *> Ops) { 7482 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]); 7483 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]); 7484 7485 if (Ops.size() == 2) 7486 return Res; 7487 7488 assert(Ops.size() == 4); 7489 return EmitX86Select(CGF, Ops[3], Res, Ops[2]); 7490 } 7491 7492 static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, 7493 llvm::Type *DstTy) { 7494 unsigned NumberOfElements = DstTy->getVectorNumElements(); 7495 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements); 7496 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2"); 7497 } 7498 7499 Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) { 7500 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts(); 7501 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString(); 7502 return EmitX86CpuIs(CPUStr); 7503 } 7504 7505 Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) { 7506 7507 // This enum contains the vendor, type, and subtype enums from the 7508 // runtime library concatenated together. The _START labels mark 7509 // the start and are used to adjust the value into the correct 7510 // encoding space. 7511 enum X86CPUs { 7512 INTEL = 1, 7513 AMD, 7514 CPU_TYPE_START, 7515 INTEL_BONNELL, 7516 INTEL_CORE2, 7517 INTEL_COREI7, 7518 AMDFAM10H, 7519 AMDFAM15H, 7520 INTEL_SILVERMONT, 7521 INTEL_KNL, 7522 AMD_BTVER1, 7523 AMD_BTVER2, 7524 AMDFAM17H, 7525 CPU_SUBTYPE_START, 7526 INTEL_COREI7_NEHALEM, 7527 INTEL_COREI7_WESTMERE, 7528 INTEL_COREI7_SANDYBRIDGE, 7529 AMDFAM10H_BARCELONA, 7530 AMDFAM10H_SHANGHAI, 7531 AMDFAM10H_ISTANBUL, 7532 AMDFAM15H_BDVER1, 7533 AMDFAM15H_BDVER2, 7534 AMDFAM15H_BDVER3, 7535 AMDFAM15H_BDVER4, 7536 AMDFAM17H_ZNVER1, 7537 INTEL_COREI7_IVYBRIDGE, 7538 INTEL_COREI7_HASWELL, 7539 INTEL_COREI7_BROADWELL, 7540 INTEL_COREI7_SKYLAKE, 7541 INTEL_COREI7_SKYLAKE_AVX512, 7542 }; 7543 7544 X86CPUs CPU = 7545 StringSwitch<X86CPUs>(CPUStr) 7546 .Case("amd", AMD) 7547 .Case("amdfam10h", AMDFAM10H) 7548 .Case("amdfam10", AMDFAM10H) 7549 .Case("amdfam15h", AMDFAM15H) 7550 .Case("amdfam15", AMDFAM15H) 7551 .Case("amdfam17h", AMDFAM17H) 7552 .Case("atom", INTEL_BONNELL) 7553 .Case("barcelona", AMDFAM10H_BARCELONA) 7554 .Case("bdver1", AMDFAM15H_BDVER1) 7555 .Case("bdver2", AMDFAM15H_BDVER2) 7556 .Case("bdver3", AMDFAM15H_BDVER3) 7557 .Case("bdver4", AMDFAM15H_BDVER4) 7558 .Case("bonnell", INTEL_BONNELL) 7559 .Case("broadwell", INTEL_COREI7_BROADWELL) 7560 .Case("btver1", AMD_BTVER1) 7561 .Case("btver2", AMD_BTVER2) 7562 .Case("core2", INTEL_CORE2) 7563 .Case("corei7", INTEL_COREI7) 7564 .Case("haswell", INTEL_COREI7_HASWELL) 7565 .Case("intel", INTEL) 7566 .Case("istanbul", AMDFAM10H_ISTANBUL) 7567 .Case("ivybridge", INTEL_COREI7_IVYBRIDGE) 7568 .Case("knl", INTEL_KNL) 7569 .Case("nehalem", INTEL_COREI7_NEHALEM) 7570 .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE) 7571 .Case("shanghai", AMDFAM10H_SHANGHAI) 7572 .Case("silvermont", INTEL_SILVERMONT) 7573 .Case("skylake", INTEL_COREI7_SKYLAKE) 7574 .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512) 7575 .Case("slm", INTEL_SILVERMONT) 7576 .Case("westmere", INTEL_COREI7_WESTMERE) 7577 .Case("znver1", AMDFAM17H_ZNVER1); 7578 7579 llvm::Type *Int32Ty = Builder.getInt32Ty(); 7580 7581 // Matching the struct layout from the compiler-rt/libgcc structure that is 7582 // filled in: 7583 // unsigned int __cpu_vendor; 7584 // unsigned int __cpu_type; 7585 // unsigned int __cpu_subtype; 7586 // unsigned int __cpu_features[1]; 7587 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7588 llvm::ArrayType::get(Int32Ty, 1)); 7589 7590 // Grab the global __cpu_model. 7591 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7592 7593 // Calculate the index needed to access the correct field based on the 7594 // range. Also adjust the expected value. 7595 unsigned Index; 7596 unsigned Value; 7597 if (CPU > CPU_SUBTYPE_START) { 7598 Index = 2; 7599 Value = CPU - CPU_SUBTYPE_START; 7600 } else if (CPU > CPU_TYPE_START) { 7601 Index = 1; 7602 Value = CPU - CPU_TYPE_START; 7603 } else { 7604 Index = 0; 7605 Value = CPU; 7606 } 7607 7608 // Grab the appropriate field from __cpu_model. 7609 llvm::Value *Idxs[] = { 7610 ConstantInt::get(Int32Ty, 0), 7611 ConstantInt::get(Int32Ty, Index) 7612 }; 7613 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs); 7614 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4)); 7615 7616 // Check the value of the field against the requested value. 7617 return Builder.CreateICmpEQ(CpuValue, 7618 llvm::ConstantInt::get(Int32Ty, Value)); 7619 } 7620 7621 Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) { 7622 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts(); 7623 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString(); 7624 return EmitX86CpuSupports(FeatureStr); 7625 } 7626 7627 Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) { 7628 // TODO: When/if this becomes more than x86 specific then use a TargetInfo 7629 // based mapping. 7630 // Processor features and mapping to processor feature value. 7631 enum X86Features { 7632 CMOV = 0, 7633 MMX, 7634 POPCNT, 7635 SSE, 7636 SSE2, 7637 SSE3, 7638 SSSE3, 7639 SSE4_1, 7640 SSE4_2, 7641 AVX, 7642 AVX2, 7643 SSE4_A, 7644 FMA4, 7645 XOP, 7646 FMA, 7647 AVX512F, 7648 BMI, 7649 BMI2, 7650 AES, 7651 PCLMUL, 7652 AVX512VL, 7653 AVX512BW, 7654 AVX512DQ, 7655 AVX512CD, 7656 AVX512ER, 7657 AVX512PF, 7658 AVX512VBMI, 7659 AVX512IFMA, 7660 AVX5124VNNIW, 7661 AVX5124FMAPS, 7662 AVX512VPOPCNTDQ, 7663 MAX 7664 }; 7665 7666 uint32_t FeaturesMask = 0; 7667 7668 for (const StringRef &FeatureStr : FeatureStrs) { 7669 X86Features Feature = 7670 StringSwitch<X86Features>(FeatureStr) 7671 .Case("cmov", X86Features::CMOV) 7672 .Case("mmx", X86Features::MMX) 7673 .Case("popcnt", X86Features::POPCNT) 7674 .Case("sse", X86Features::SSE) 7675 .Case("sse2", X86Features::SSE2) 7676 .Case("sse3", X86Features::SSE3) 7677 .Case("ssse3", X86Features::SSSE3) 7678 .Case("sse4.1", X86Features::SSE4_1) 7679 .Case("sse4.2", X86Features::SSE4_2) 7680 .Case("avx", X86Features::AVX) 7681 .Case("avx2", X86Features::AVX2) 7682 .Case("sse4a", X86Features::SSE4_A) 7683 .Case("fma4", X86Features::FMA4) 7684 .Case("xop", X86Features::XOP) 7685 .Case("fma", X86Features::FMA) 7686 .Case("avx512f", X86Features::AVX512F) 7687 .Case("bmi", X86Features::BMI) 7688 .Case("bmi2", X86Features::BMI2) 7689 .Case("aes", X86Features::AES) 7690 .Case("pclmul", X86Features::PCLMUL) 7691 .Case("avx512vl", X86Features::AVX512VL) 7692 .Case("avx512bw", X86Features::AVX512BW) 7693 .Case("avx512dq", X86Features::AVX512DQ) 7694 .Case("avx512cd", X86Features::AVX512CD) 7695 .Case("avx512er", X86Features::AVX512ER) 7696 .Case("avx512pf", X86Features::AVX512PF) 7697 .Case("avx512vbmi", X86Features::AVX512VBMI) 7698 .Case("avx512ifma", X86Features::AVX512IFMA) 7699 .Case("avx5124vnniw", X86Features::AVX5124VNNIW) 7700 .Case("avx5124fmaps", X86Features::AVX5124FMAPS) 7701 .Case("avx512vpopcntdq", X86Features::AVX512VPOPCNTDQ) 7702 .Default(X86Features::MAX); 7703 assert(Feature != X86Features::MAX && "Invalid feature!"); 7704 FeaturesMask |= (1U << Feature); 7705 } 7706 7707 // Matching the struct layout from the compiler-rt/libgcc structure that is 7708 // filled in: 7709 // unsigned int __cpu_vendor; 7710 // unsigned int __cpu_type; 7711 // unsigned int __cpu_subtype; 7712 // unsigned int __cpu_features[1]; 7713 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, 7714 llvm::ArrayType::get(Int32Ty, 1)); 7715 7716 // Grab the global __cpu_model. 7717 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model"); 7718 7719 // Grab the first (0th) element from the field __cpu_features off of the 7720 // global in the struct STy. 7721 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3), 7722 ConstantInt::get(Int32Ty, 0)}; 7723 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs); 7724 Value *Features = 7725 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4)); 7726 7727 // Check the value of the bit corresponding to the feature requested. 7728 Value *Bitset = Builder.CreateAnd( 7729 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask)); 7730 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0)); 7731 } 7732 7733 Value *CodeGenFunction::EmitX86CpuInit() { 7734 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, 7735 /*Variadic*/ false); 7736 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init"); 7737 return Builder.CreateCall(Func); 7738 } 7739 7740 Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, 7741 const CallExpr *E) { 7742 if (BuiltinID == X86::BI__builtin_cpu_is) 7743 return EmitX86CpuIs(E); 7744 if (BuiltinID == X86::BI__builtin_cpu_supports) 7745 return EmitX86CpuSupports(E); 7746 if (BuiltinID == X86::BI__builtin_cpu_init) 7747 return EmitX86CpuInit(); 7748 7749 SmallVector<Value*, 4> Ops; 7750 7751 // Find out if any arguments are required to be integer constant expressions. 7752 unsigned ICEArguments = 0; 7753 ASTContext::GetBuiltinTypeError Error; 7754 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments); 7755 assert(Error == ASTContext::GE_None && "Should not codegen an error"); 7756 7757 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) { 7758 // If this is a normal argument, just emit it as a scalar. 7759 if ((ICEArguments & (1 << i)) == 0) { 7760 Ops.push_back(EmitScalarExpr(E->getArg(i))); 7761 continue; 7762 } 7763 7764 // If this is required to be a constant, constant fold it so that we know 7765 // that the generated intrinsic gets a ConstantInt. 7766 llvm::APSInt Result; 7767 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext()); 7768 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst; 7769 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result)); 7770 } 7771 7772 // These exist so that the builtin that takes an immediate can be bounds 7773 // checked by clang to avoid passing bad immediates to the backend. Since 7774 // AVX has a larger immediate than SSE we would need separate builtins to 7775 // do the different bounds checking. Rather than create a clang specific 7776 // SSE only builtin, this implements eight separate builtins to match gcc 7777 // implementation. 7778 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) { 7779 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm)); 7780 llvm::Function *F = CGM.getIntrinsic(ID); 7781 return Builder.CreateCall(F, Ops); 7782 }; 7783 7784 // For the vector forms of FP comparisons, translate the builtins directly to 7785 // IR. 7786 // TODO: The builtins could be removed if the SSE header files used vector 7787 // extension comparisons directly (vector ordered/unordered may need 7788 // additional support via __builtin_isnan()). 7789 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) { 7790 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]); 7791 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType()); 7792 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy); 7793 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy); 7794 return Builder.CreateBitCast(Sext, FPVecTy); 7795 }; 7796 7797 switch (BuiltinID) { 7798 default: return nullptr; 7799 case X86::BI_mm_prefetch: { 7800 Value *Address = Ops[0]; 7801 Value *RW = ConstantInt::get(Int32Ty, 0); 7802 Value *Locality = Ops[1]; 7803 Value *Data = ConstantInt::get(Int32Ty, 1); 7804 Value *F = CGM.getIntrinsic(Intrinsic::prefetch); 7805 return Builder.CreateCall(F, {Address, RW, Locality, Data}); 7806 } 7807 case X86::BI_mm_clflush: { 7808 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush), 7809 Ops[0]); 7810 } 7811 case X86::BI_mm_lfence: { 7812 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence)); 7813 } 7814 case X86::BI_mm_mfence: { 7815 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence)); 7816 } 7817 case X86::BI_mm_sfence: { 7818 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence)); 7819 } 7820 case X86::BI_mm_pause: { 7821 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause)); 7822 } 7823 case X86::BI__rdtsc: { 7824 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc)); 7825 } 7826 case X86::BI__builtin_ia32_undef128: 7827 case X86::BI__builtin_ia32_undef256: 7828 case X86::BI__builtin_ia32_undef512: 7829 // The x86 definition of "undef" is not the same as the LLVM definition 7830 // (PR32176). We leave optimizing away an unnecessary zero constant to the 7831 // IR optimizer and backend. 7832 // TODO: If we had a "freeze" IR instruction to generate a fixed undef 7833 // value, we should use that here instead of a zero. 7834 return llvm::Constant::getNullValue(ConvertType(E->getType())); 7835 case X86::BI__builtin_ia32_vec_init_v8qi: 7836 case X86::BI__builtin_ia32_vec_init_v4hi: 7837 case X86::BI__builtin_ia32_vec_init_v2si: 7838 return Builder.CreateBitCast(BuildVector(Ops), 7839 llvm::Type::getX86_MMXTy(getLLVMContext())); 7840 case X86::BI__builtin_ia32_vec_ext_v2si: 7841 return Builder.CreateExtractElement(Ops[0], 7842 llvm::ConstantInt::get(Ops[1]->getType(), 0)); 7843 case X86::BI_mm_setcsr: 7844 case X86::BI__builtin_ia32_ldmxcsr: { 7845 Address Tmp = CreateMemTemp(E->getArg(0)->getType()); 7846 Builder.CreateStore(Ops[0], Tmp); 7847 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr), 7848 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7849 } 7850 case X86::BI_mm_getcsr: 7851 case X86::BI__builtin_ia32_stmxcsr: { 7852 Address Tmp = CreateMemTemp(E->getType()); 7853 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr), 7854 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy)); 7855 return Builder.CreateLoad(Tmp, "stmxcsr"); 7856 } 7857 case X86::BI__builtin_ia32_xsave: 7858 case X86::BI__builtin_ia32_xsave64: 7859 case X86::BI__builtin_ia32_xrstor: 7860 case X86::BI__builtin_ia32_xrstor64: 7861 case X86::BI__builtin_ia32_xsaveopt: 7862 case X86::BI__builtin_ia32_xsaveopt64: 7863 case X86::BI__builtin_ia32_xrstors: 7864 case X86::BI__builtin_ia32_xrstors64: 7865 case X86::BI__builtin_ia32_xsavec: 7866 case X86::BI__builtin_ia32_xsavec64: 7867 case X86::BI__builtin_ia32_xsaves: 7868 case X86::BI__builtin_ia32_xsaves64: { 7869 Intrinsic::ID ID; 7870 #define INTRINSIC_X86_XSAVE_ID(NAME) \ 7871 case X86::BI__builtin_ia32_##NAME: \ 7872 ID = Intrinsic::x86_##NAME; \ 7873 break 7874 switch (BuiltinID) { 7875 default: llvm_unreachable("Unsupported intrinsic!"); 7876 INTRINSIC_X86_XSAVE_ID(xsave); 7877 INTRINSIC_X86_XSAVE_ID(xsave64); 7878 INTRINSIC_X86_XSAVE_ID(xrstor); 7879 INTRINSIC_X86_XSAVE_ID(xrstor64); 7880 INTRINSIC_X86_XSAVE_ID(xsaveopt); 7881 INTRINSIC_X86_XSAVE_ID(xsaveopt64); 7882 INTRINSIC_X86_XSAVE_ID(xrstors); 7883 INTRINSIC_X86_XSAVE_ID(xrstors64); 7884 INTRINSIC_X86_XSAVE_ID(xsavec); 7885 INTRINSIC_X86_XSAVE_ID(xsavec64); 7886 INTRINSIC_X86_XSAVE_ID(xsaves); 7887 INTRINSIC_X86_XSAVE_ID(xsaves64); 7888 } 7889 #undef INTRINSIC_X86_XSAVE_ID 7890 Value *Mhi = Builder.CreateTrunc( 7891 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty); 7892 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty); 7893 Ops[1] = Mhi; 7894 Ops.push_back(Mlo); 7895 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 7896 } 7897 case X86::BI__builtin_ia32_storedqudi128_mask: 7898 case X86::BI__builtin_ia32_storedqusi128_mask: 7899 case X86::BI__builtin_ia32_storedquhi128_mask: 7900 case X86::BI__builtin_ia32_storedquqi128_mask: 7901 case X86::BI__builtin_ia32_storeupd128_mask: 7902 case X86::BI__builtin_ia32_storeups128_mask: 7903 case X86::BI__builtin_ia32_storedqudi256_mask: 7904 case X86::BI__builtin_ia32_storedqusi256_mask: 7905 case X86::BI__builtin_ia32_storedquhi256_mask: 7906 case X86::BI__builtin_ia32_storedquqi256_mask: 7907 case X86::BI__builtin_ia32_storeupd256_mask: 7908 case X86::BI__builtin_ia32_storeups256_mask: 7909 case X86::BI__builtin_ia32_storedqudi512_mask: 7910 case X86::BI__builtin_ia32_storedqusi512_mask: 7911 case X86::BI__builtin_ia32_storedquhi512_mask: 7912 case X86::BI__builtin_ia32_storedquqi512_mask: 7913 case X86::BI__builtin_ia32_storeupd512_mask: 7914 case X86::BI__builtin_ia32_storeups512_mask: 7915 return EmitX86MaskedStore(*this, Ops, 1); 7916 7917 case X86::BI__builtin_ia32_storess128_mask: 7918 case X86::BI__builtin_ia32_storesd128_mask: { 7919 return EmitX86MaskedStore(*this, Ops, 16); 7920 } 7921 case X86::BI__builtin_ia32_vpopcntd_512: 7922 case X86::BI__builtin_ia32_vpopcntq_512: { 7923 llvm::Type *ResultType = ConvertType(E->getType()); 7924 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 7925 return Builder.CreateCall(F, Ops); 7926 } 7927 case X86::BI__builtin_ia32_cvtmask2b128: 7928 case X86::BI__builtin_ia32_cvtmask2b256: 7929 case X86::BI__builtin_ia32_cvtmask2b512: 7930 case X86::BI__builtin_ia32_cvtmask2w128: 7931 case X86::BI__builtin_ia32_cvtmask2w256: 7932 case X86::BI__builtin_ia32_cvtmask2w512: 7933 case X86::BI__builtin_ia32_cvtmask2d128: 7934 case X86::BI__builtin_ia32_cvtmask2d256: 7935 case X86::BI__builtin_ia32_cvtmask2d512: 7936 case X86::BI__builtin_ia32_cvtmask2q128: 7937 case X86::BI__builtin_ia32_cvtmask2q256: 7938 case X86::BI__builtin_ia32_cvtmask2q512: 7939 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType())); 7940 7941 case X86::BI__builtin_ia32_movdqa32store128_mask: 7942 case X86::BI__builtin_ia32_movdqa64store128_mask: 7943 case X86::BI__builtin_ia32_storeaps128_mask: 7944 case X86::BI__builtin_ia32_storeapd128_mask: 7945 case X86::BI__builtin_ia32_movdqa32store256_mask: 7946 case X86::BI__builtin_ia32_movdqa64store256_mask: 7947 case X86::BI__builtin_ia32_storeaps256_mask: 7948 case X86::BI__builtin_ia32_storeapd256_mask: 7949 case X86::BI__builtin_ia32_movdqa32store512_mask: 7950 case X86::BI__builtin_ia32_movdqa64store512_mask: 7951 case X86::BI__builtin_ia32_storeaps512_mask: 7952 case X86::BI__builtin_ia32_storeapd512_mask: { 7953 unsigned Align = 7954 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7955 return EmitX86MaskedStore(*this, Ops, Align); 7956 } 7957 case X86::BI__builtin_ia32_loadups128_mask: 7958 case X86::BI__builtin_ia32_loadups256_mask: 7959 case X86::BI__builtin_ia32_loadups512_mask: 7960 case X86::BI__builtin_ia32_loadupd128_mask: 7961 case X86::BI__builtin_ia32_loadupd256_mask: 7962 case X86::BI__builtin_ia32_loadupd512_mask: 7963 case X86::BI__builtin_ia32_loaddquqi128_mask: 7964 case X86::BI__builtin_ia32_loaddquqi256_mask: 7965 case X86::BI__builtin_ia32_loaddquqi512_mask: 7966 case X86::BI__builtin_ia32_loaddquhi128_mask: 7967 case X86::BI__builtin_ia32_loaddquhi256_mask: 7968 case X86::BI__builtin_ia32_loaddquhi512_mask: 7969 case X86::BI__builtin_ia32_loaddqusi128_mask: 7970 case X86::BI__builtin_ia32_loaddqusi256_mask: 7971 case X86::BI__builtin_ia32_loaddqusi512_mask: 7972 case X86::BI__builtin_ia32_loaddqudi128_mask: 7973 case X86::BI__builtin_ia32_loaddqudi256_mask: 7974 case X86::BI__builtin_ia32_loaddqudi512_mask: 7975 return EmitX86MaskedLoad(*this, Ops, 1); 7976 7977 case X86::BI__builtin_ia32_loadss128_mask: 7978 case X86::BI__builtin_ia32_loadsd128_mask: 7979 return EmitX86MaskedLoad(*this, Ops, 16); 7980 7981 case X86::BI__builtin_ia32_loadaps128_mask: 7982 case X86::BI__builtin_ia32_loadaps256_mask: 7983 case X86::BI__builtin_ia32_loadaps512_mask: 7984 case X86::BI__builtin_ia32_loadapd128_mask: 7985 case X86::BI__builtin_ia32_loadapd256_mask: 7986 case X86::BI__builtin_ia32_loadapd512_mask: 7987 case X86::BI__builtin_ia32_movdqa32load128_mask: 7988 case X86::BI__builtin_ia32_movdqa32load256_mask: 7989 case X86::BI__builtin_ia32_movdqa32load512_mask: 7990 case X86::BI__builtin_ia32_movdqa64load128_mask: 7991 case X86::BI__builtin_ia32_movdqa64load256_mask: 7992 case X86::BI__builtin_ia32_movdqa64load512_mask: { 7993 unsigned Align = 7994 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity(); 7995 return EmitX86MaskedLoad(*this, Ops, Align); 7996 } 7997 7998 case X86::BI__builtin_ia32_vbroadcastf128_pd256: 7999 case X86::BI__builtin_ia32_vbroadcastf128_ps256: { 8000 llvm::Type *DstTy = ConvertType(E->getType()); 8001 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1); 8002 } 8003 8004 case X86::BI__builtin_ia32_storehps: 8005 case X86::BI__builtin_ia32_storelps: { 8006 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty); 8007 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2); 8008 8009 // cast val v2i64 8010 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast"); 8011 8012 // extract (0, 1) 8013 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1; 8014 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index); 8015 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract"); 8016 8017 // cast pointer to i64 & store 8018 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); 8019 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]); 8020 } 8021 case X86::BI__builtin_ia32_palignr128: 8022 case X86::BI__builtin_ia32_palignr256: 8023 case X86::BI__builtin_ia32_palignr512_mask: { 8024 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8025 8026 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 8027 assert(NumElts % 16 == 0); 8028 8029 // If palignr is shifting the pair of vectors more than the size of two 8030 // lanes, emit zero. 8031 if (ShiftVal >= 32) 8032 return llvm::Constant::getNullValue(ConvertType(E->getType())); 8033 8034 // If palignr is shifting the pair of input vectors more than one lane, 8035 // but less than two lanes, convert to shifting in zeroes. 8036 if (ShiftVal > 16) { 8037 ShiftVal -= 16; 8038 Ops[1] = Ops[0]; 8039 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType()); 8040 } 8041 8042 uint32_t Indices[64]; 8043 // 256-bit palignr operates on 128-bit lanes so we need to handle that 8044 for (unsigned l = 0; l != NumElts; l += 16) { 8045 for (unsigned i = 0; i != 16; ++i) { 8046 unsigned Idx = ShiftVal + i; 8047 if (Idx >= 16) 8048 Idx += NumElts - 16; // End of lane, switch operand. 8049 Indices[l + i] = Idx + l; 8050 } 8051 } 8052 8053 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0], 8054 makeArrayRef(Indices, NumElts), 8055 "palignr"); 8056 8057 // If this isn't a masked builtin, just return the align operation. 8058 if (Ops.size() == 3) 8059 return Align; 8060 8061 return EmitX86Select(*this, Ops[4], Align, Ops[3]); 8062 } 8063 8064 case X86::BI__builtin_ia32_vperm2f128_pd256: 8065 case X86::BI__builtin_ia32_vperm2f128_ps256: 8066 case X86::BI__builtin_ia32_vperm2f128_si256: 8067 case X86::BI__builtin_ia32_permti256: { 8068 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8069 unsigned NumElts = Ops[0]->getType()->getVectorNumElements(); 8070 8071 // This takes a very simple approach since there are two lanes and a 8072 // shuffle can have 2 inputs. So we reserve the first input for the first 8073 // lane and the second input for the second lane. This may result in 8074 // duplicate sources, but this can be dealt with in the backend. 8075 8076 Value *OutOps[2]; 8077 uint32_t Indices[8]; 8078 for (unsigned l = 0; l != 2; ++l) { 8079 // Determine the source for this lane. 8080 if (Imm & (1 << ((l * 4) + 3))) 8081 OutOps[l] = llvm::ConstantAggregateZero::get(Ops[0]->getType()); 8082 else if (Imm & (1 << ((l * 4) + 1))) 8083 OutOps[l] = Ops[1]; 8084 else 8085 OutOps[l] = Ops[0]; 8086 8087 for (unsigned i = 0; i != NumElts/2; ++i) { 8088 // Start with ith element of the source for this lane. 8089 unsigned Idx = (l * NumElts) + i; 8090 // If bit 0 of the immediate half is set, switch to the high half of 8091 // the source. 8092 if (Imm & (1 << (l * 4))) 8093 Idx += NumElts/2; 8094 Indices[(l * (NumElts/2)) + i] = Idx; 8095 } 8096 } 8097 8098 return Builder.CreateShuffleVector(OutOps[0], OutOps[1], 8099 makeArrayRef(Indices, NumElts), 8100 "vperm"); 8101 } 8102 8103 case X86::BI__builtin_ia32_movnti: 8104 case X86::BI__builtin_ia32_movnti64: 8105 case X86::BI__builtin_ia32_movntsd: 8106 case X86::BI__builtin_ia32_movntss: { 8107 llvm::MDNode *Node = llvm::MDNode::get( 8108 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1))); 8109 8110 Value *Ptr = Ops[0]; 8111 Value *Src = Ops[1]; 8112 8113 // Extract the 0'th element of the source vector. 8114 if (BuiltinID == X86::BI__builtin_ia32_movntsd || 8115 BuiltinID == X86::BI__builtin_ia32_movntss) 8116 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract"); 8117 8118 // Convert the type of the pointer to a pointer to the stored type. 8119 Value *BC = Builder.CreateBitCast( 8120 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast"); 8121 8122 // Unaligned nontemporal store of the scalar value. 8123 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC); 8124 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node); 8125 SI->setAlignment(1); 8126 return SI; 8127 } 8128 8129 case X86::BI__builtin_ia32_selectb_128: 8130 case X86::BI__builtin_ia32_selectb_256: 8131 case X86::BI__builtin_ia32_selectb_512: 8132 case X86::BI__builtin_ia32_selectw_128: 8133 case X86::BI__builtin_ia32_selectw_256: 8134 case X86::BI__builtin_ia32_selectw_512: 8135 case X86::BI__builtin_ia32_selectd_128: 8136 case X86::BI__builtin_ia32_selectd_256: 8137 case X86::BI__builtin_ia32_selectd_512: 8138 case X86::BI__builtin_ia32_selectq_128: 8139 case X86::BI__builtin_ia32_selectq_256: 8140 case X86::BI__builtin_ia32_selectq_512: 8141 case X86::BI__builtin_ia32_selectps_128: 8142 case X86::BI__builtin_ia32_selectps_256: 8143 case X86::BI__builtin_ia32_selectps_512: 8144 case X86::BI__builtin_ia32_selectpd_128: 8145 case X86::BI__builtin_ia32_selectpd_256: 8146 case X86::BI__builtin_ia32_selectpd_512: 8147 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]); 8148 case X86::BI__builtin_ia32_pcmpeqb128_mask: 8149 case X86::BI__builtin_ia32_pcmpeqb256_mask: 8150 case X86::BI__builtin_ia32_pcmpeqb512_mask: 8151 case X86::BI__builtin_ia32_pcmpeqw128_mask: 8152 case X86::BI__builtin_ia32_pcmpeqw256_mask: 8153 case X86::BI__builtin_ia32_pcmpeqw512_mask: 8154 case X86::BI__builtin_ia32_pcmpeqd128_mask: 8155 case X86::BI__builtin_ia32_pcmpeqd256_mask: 8156 case X86::BI__builtin_ia32_pcmpeqd512_mask: 8157 case X86::BI__builtin_ia32_pcmpeqq128_mask: 8158 case X86::BI__builtin_ia32_pcmpeqq256_mask: 8159 case X86::BI__builtin_ia32_pcmpeqq512_mask: 8160 return EmitX86MaskedCompare(*this, 0, false, Ops); 8161 case X86::BI__builtin_ia32_pcmpgtb128_mask: 8162 case X86::BI__builtin_ia32_pcmpgtb256_mask: 8163 case X86::BI__builtin_ia32_pcmpgtb512_mask: 8164 case X86::BI__builtin_ia32_pcmpgtw128_mask: 8165 case X86::BI__builtin_ia32_pcmpgtw256_mask: 8166 case X86::BI__builtin_ia32_pcmpgtw512_mask: 8167 case X86::BI__builtin_ia32_pcmpgtd128_mask: 8168 case X86::BI__builtin_ia32_pcmpgtd256_mask: 8169 case X86::BI__builtin_ia32_pcmpgtd512_mask: 8170 case X86::BI__builtin_ia32_pcmpgtq128_mask: 8171 case X86::BI__builtin_ia32_pcmpgtq256_mask: 8172 case X86::BI__builtin_ia32_pcmpgtq512_mask: 8173 return EmitX86MaskedCompare(*this, 6, true, Ops); 8174 case X86::BI__builtin_ia32_cmpb128_mask: 8175 case X86::BI__builtin_ia32_cmpb256_mask: 8176 case X86::BI__builtin_ia32_cmpb512_mask: 8177 case X86::BI__builtin_ia32_cmpw128_mask: 8178 case X86::BI__builtin_ia32_cmpw256_mask: 8179 case X86::BI__builtin_ia32_cmpw512_mask: 8180 case X86::BI__builtin_ia32_cmpd128_mask: 8181 case X86::BI__builtin_ia32_cmpd256_mask: 8182 case X86::BI__builtin_ia32_cmpd512_mask: 8183 case X86::BI__builtin_ia32_cmpq128_mask: 8184 case X86::BI__builtin_ia32_cmpq256_mask: 8185 case X86::BI__builtin_ia32_cmpq512_mask: { 8186 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8187 return EmitX86MaskedCompare(*this, CC, true, Ops); 8188 } 8189 case X86::BI__builtin_ia32_ucmpb128_mask: 8190 case X86::BI__builtin_ia32_ucmpb256_mask: 8191 case X86::BI__builtin_ia32_ucmpb512_mask: 8192 case X86::BI__builtin_ia32_ucmpw128_mask: 8193 case X86::BI__builtin_ia32_ucmpw256_mask: 8194 case X86::BI__builtin_ia32_ucmpw512_mask: 8195 case X86::BI__builtin_ia32_ucmpd128_mask: 8196 case X86::BI__builtin_ia32_ucmpd256_mask: 8197 case X86::BI__builtin_ia32_ucmpd512_mask: 8198 case X86::BI__builtin_ia32_ucmpq128_mask: 8199 case X86::BI__builtin_ia32_ucmpq256_mask: 8200 case X86::BI__builtin_ia32_ucmpq512_mask: { 8201 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7; 8202 return EmitX86MaskedCompare(*this, CC, false, Ops); 8203 } 8204 8205 case X86::BI__builtin_ia32_vplzcntd_128_mask: 8206 case X86::BI__builtin_ia32_vplzcntd_256_mask: 8207 case X86::BI__builtin_ia32_vplzcntd_512_mask: 8208 case X86::BI__builtin_ia32_vplzcntq_128_mask: 8209 case X86::BI__builtin_ia32_vplzcntq_256_mask: 8210 case X86::BI__builtin_ia32_vplzcntq_512_mask: { 8211 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType()); 8212 return EmitX86Select(*this, Ops[2], 8213 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}), 8214 Ops[1]); 8215 } 8216 8217 case X86::BI__builtin_ia32_pabsb128: 8218 case X86::BI__builtin_ia32_pabsw128: 8219 case X86::BI__builtin_ia32_pabsd128: 8220 case X86::BI__builtin_ia32_pabsb256: 8221 case X86::BI__builtin_ia32_pabsw256: 8222 case X86::BI__builtin_ia32_pabsd256: 8223 case X86::BI__builtin_ia32_pabsq128_mask: 8224 case X86::BI__builtin_ia32_pabsq256_mask: 8225 case X86::BI__builtin_ia32_pabsb512_mask: 8226 case X86::BI__builtin_ia32_pabsw512_mask: 8227 case X86::BI__builtin_ia32_pabsd512_mask: 8228 case X86::BI__builtin_ia32_pabsq512_mask: 8229 return EmitX86Abs(*this, Ops); 8230 8231 case X86::BI__builtin_ia32_pmaxsb128: 8232 case X86::BI__builtin_ia32_pmaxsw128: 8233 case X86::BI__builtin_ia32_pmaxsd128: 8234 case X86::BI__builtin_ia32_pmaxsq128_mask: 8235 case X86::BI__builtin_ia32_pmaxsb256: 8236 case X86::BI__builtin_ia32_pmaxsw256: 8237 case X86::BI__builtin_ia32_pmaxsd256: 8238 case X86::BI__builtin_ia32_pmaxsq256_mask: 8239 case X86::BI__builtin_ia32_pmaxsb512_mask: 8240 case X86::BI__builtin_ia32_pmaxsw512_mask: 8241 case X86::BI__builtin_ia32_pmaxsd512_mask: 8242 case X86::BI__builtin_ia32_pmaxsq512_mask: 8243 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops); 8244 case X86::BI__builtin_ia32_pmaxub128: 8245 case X86::BI__builtin_ia32_pmaxuw128: 8246 case X86::BI__builtin_ia32_pmaxud128: 8247 case X86::BI__builtin_ia32_pmaxuq128_mask: 8248 case X86::BI__builtin_ia32_pmaxub256: 8249 case X86::BI__builtin_ia32_pmaxuw256: 8250 case X86::BI__builtin_ia32_pmaxud256: 8251 case X86::BI__builtin_ia32_pmaxuq256_mask: 8252 case X86::BI__builtin_ia32_pmaxub512_mask: 8253 case X86::BI__builtin_ia32_pmaxuw512_mask: 8254 case X86::BI__builtin_ia32_pmaxud512_mask: 8255 case X86::BI__builtin_ia32_pmaxuq512_mask: 8256 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops); 8257 case X86::BI__builtin_ia32_pminsb128: 8258 case X86::BI__builtin_ia32_pminsw128: 8259 case X86::BI__builtin_ia32_pminsd128: 8260 case X86::BI__builtin_ia32_pminsq128_mask: 8261 case X86::BI__builtin_ia32_pminsb256: 8262 case X86::BI__builtin_ia32_pminsw256: 8263 case X86::BI__builtin_ia32_pminsd256: 8264 case X86::BI__builtin_ia32_pminsq256_mask: 8265 case X86::BI__builtin_ia32_pminsb512_mask: 8266 case X86::BI__builtin_ia32_pminsw512_mask: 8267 case X86::BI__builtin_ia32_pminsd512_mask: 8268 case X86::BI__builtin_ia32_pminsq512_mask: 8269 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops); 8270 case X86::BI__builtin_ia32_pminub128: 8271 case X86::BI__builtin_ia32_pminuw128: 8272 case X86::BI__builtin_ia32_pminud128: 8273 case X86::BI__builtin_ia32_pminuq128_mask: 8274 case X86::BI__builtin_ia32_pminub256: 8275 case X86::BI__builtin_ia32_pminuw256: 8276 case X86::BI__builtin_ia32_pminud256: 8277 case X86::BI__builtin_ia32_pminuq256_mask: 8278 case X86::BI__builtin_ia32_pminub512_mask: 8279 case X86::BI__builtin_ia32_pminuw512_mask: 8280 case X86::BI__builtin_ia32_pminud512_mask: 8281 case X86::BI__builtin_ia32_pminuq512_mask: 8282 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops); 8283 8284 // 3DNow! 8285 case X86::BI__builtin_ia32_pswapdsf: 8286 case X86::BI__builtin_ia32_pswapdsi: { 8287 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext()); 8288 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast"); 8289 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd); 8290 return Builder.CreateCall(F, Ops, "pswapd"); 8291 } 8292 case X86::BI__builtin_ia32_rdrand16_step: 8293 case X86::BI__builtin_ia32_rdrand32_step: 8294 case X86::BI__builtin_ia32_rdrand64_step: 8295 case X86::BI__builtin_ia32_rdseed16_step: 8296 case X86::BI__builtin_ia32_rdseed32_step: 8297 case X86::BI__builtin_ia32_rdseed64_step: { 8298 Intrinsic::ID ID; 8299 switch (BuiltinID) { 8300 default: llvm_unreachable("Unsupported intrinsic!"); 8301 case X86::BI__builtin_ia32_rdrand16_step: 8302 ID = Intrinsic::x86_rdrand_16; 8303 break; 8304 case X86::BI__builtin_ia32_rdrand32_step: 8305 ID = Intrinsic::x86_rdrand_32; 8306 break; 8307 case X86::BI__builtin_ia32_rdrand64_step: 8308 ID = Intrinsic::x86_rdrand_64; 8309 break; 8310 case X86::BI__builtin_ia32_rdseed16_step: 8311 ID = Intrinsic::x86_rdseed_16; 8312 break; 8313 case X86::BI__builtin_ia32_rdseed32_step: 8314 ID = Intrinsic::x86_rdseed_32; 8315 break; 8316 case X86::BI__builtin_ia32_rdseed64_step: 8317 ID = Intrinsic::x86_rdseed_64; 8318 break; 8319 } 8320 8321 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID)); 8322 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0), 8323 Ops[0]); 8324 return Builder.CreateExtractValue(Call, 1); 8325 } 8326 8327 // SSE packed comparison intrinsics 8328 case X86::BI__builtin_ia32_cmpeqps: 8329 case X86::BI__builtin_ia32_cmpeqpd: 8330 return getVectorFCmpIR(CmpInst::FCMP_OEQ); 8331 case X86::BI__builtin_ia32_cmpltps: 8332 case X86::BI__builtin_ia32_cmpltpd: 8333 return getVectorFCmpIR(CmpInst::FCMP_OLT); 8334 case X86::BI__builtin_ia32_cmpleps: 8335 case X86::BI__builtin_ia32_cmplepd: 8336 return getVectorFCmpIR(CmpInst::FCMP_OLE); 8337 case X86::BI__builtin_ia32_cmpunordps: 8338 case X86::BI__builtin_ia32_cmpunordpd: 8339 return getVectorFCmpIR(CmpInst::FCMP_UNO); 8340 case X86::BI__builtin_ia32_cmpneqps: 8341 case X86::BI__builtin_ia32_cmpneqpd: 8342 return getVectorFCmpIR(CmpInst::FCMP_UNE); 8343 case X86::BI__builtin_ia32_cmpnltps: 8344 case X86::BI__builtin_ia32_cmpnltpd: 8345 return getVectorFCmpIR(CmpInst::FCMP_UGE); 8346 case X86::BI__builtin_ia32_cmpnleps: 8347 case X86::BI__builtin_ia32_cmpnlepd: 8348 return getVectorFCmpIR(CmpInst::FCMP_UGT); 8349 case X86::BI__builtin_ia32_cmpordps: 8350 case X86::BI__builtin_ia32_cmpordpd: 8351 return getVectorFCmpIR(CmpInst::FCMP_ORD); 8352 case X86::BI__builtin_ia32_cmpps: 8353 case X86::BI__builtin_ia32_cmpps256: 8354 case X86::BI__builtin_ia32_cmppd: 8355 case X86::BI__builtin_ia32_cmppd256: { 8356 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue(); 8357 // If this one of the SSE immediates, we can use native IR. 8358 if (CC < 8) { 8359 FCmpInst::Predicate Pred; 8360 switch (CC) { 8361 case 0: Pred = FCmpInst::FCMP_OEQ; break; 8362 case 1: Pred = FCmpInst::FCMP_OLT; break; 8363 case 2: Pred = FCmpInst::FCMP_OLE; break; 8364 case 3: Pred = FCmpInst::FCMP_UNO; break; 8365 case 4: Pred = FCmpInst::FCMP_UNE; break; 8366 case 5: Pred = FCmpInst::FCMP_UGE; break; 8367 case 6: Pred = FCmpInst::FCMP_UGT; break; 8368 case 7: Pred = FCmpInst::FCMP_ORD; break; 8369 } 8370 return getVectorFCmpIR(Pred); 8371 } 8372 8373 // We can't handle 8-31 immediates with native IR, use the intrinsic. 8374 // Except for predicates that create constants. 8375 Intrinsic::ID ID; 8376 switch (BuiltinID) { 8377 default: llvm_unreachable("Unsupported intrinsic!"); 8378 case X86::BI__builtin_ia32_cmpps: 8379 ID = Intrinsic::x86_sse_cmp_ps; 8380 break; 8381 case X86::BI__builtin_ia32_cmpps256: 8382 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8383 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8384 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8385 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8386 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) : 8387 llvm::Constant::getNullValue(Builder.getInt32Ty()); 8388 Value *Vec = Builder.CreateVectorSplat( 8389 Ops[0]->getType()->getVectorNumElements(), Constant); 8390 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8391 } 8392 ID = Intrinsic::x86_avx_cmp_ps_256; 8393 break; 8394 case X86::BI__builtin_ia32_cmppd: 8395 ID = Intrinsic::x86_sse2_cmp_pd; 8396 break; 8397 case X86::BI__builtin_ia32_cmppd256: 8398 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector 8399 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0... 8400 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) { 8401 Value *Constant = (CC == 0xf || CC == 0x1f) ? 8402 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) : 8403 llvm::Constant::getNullValue(Builder.getInt64Ty()); 8404 Value *Vec = Builder.CreateVectorSplat( 8405 Ops[0]->getType()->getVectorNumElements(), Constant); 8406 return Builder.CreateBitCast(Vec, Ops[0]->getType()); 8407 } 8408 ID = Intrinsic::x86_avx_cmp_pd_256; 8409 break; 8410 } 8411 8412 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops); 8413 } 8414 8415 // SSE scalar comparison intrinsics 8416 case X86::BI__builtin_ia32_cmpeqss: 8417 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0); 8418 case X86::BI__builtin_ia32_cmpltss: 8419 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1); 8420 case X86::BI__builtin_ia32_cmpless: 8421 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2); 8422 case X86::BI__builtin_ia32_cmpunordss: 8423 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3); 8424 case X86::BI__builtin_ia32_cmpneqss: 8425 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4); 8426 case X86::BI__builtin_ia32_cmpnltss: 8427 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5); 8428 case X86::BI__builtin_ia32_cmpnless: 8429 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6); 8430 case X86::BI__builtin_ia32_cmpordss: 8431 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7); 8432 case X86::BI__builtin_ia32_cmpeqsd: 8433 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0); 8434 case X86::BI__builtin_ia32_cmpltsd: 8435 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1); 8436 case X86::BI__builtin_ia32_cmplesd: 8437 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2); 8438 case X86::BI__builtin_ia32_cmpunordsd: 8439 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3); 8440 case X86::BI__builtin_ia32_cmpneqsd: 8441 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4); 8442 case X86::BI__builtin_ia32_cmpnltsd: 8443 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5); 8444 case X86::BI__builtin_ia32_cmpnlesd: 8445 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6); 8446 case X86::BI__builtin_ia32_cmpordsd: 8447 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7); 8448 8449 case X86::BI__emul: 8450 case X86::BI__emulu: { 8451 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64); 8452 bool isSigned = (BuiltinID == X86::BI__emul); 8453 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned); 8454 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned); 8455 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned); 8456 } 8457 case X86::BI__mulh: 8458 case X86::BI__umulh: 8459 case X86::BI_mul128: 8460 case X86::BI_umul128: { 8461 llvm::Type *ResType = ConvertType(E->getType()); 8462 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128); 8463 8464 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128); 8465 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned); 8466 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned); 8467 8468 Value *MulResult, *HigherBits; 8469 if (IsSigned) { 8470 MulResult = Builder.CreateNSWMul(LHS, RHS); 8471 HigherBits = Builder.CreateAShr(MulResult, 64); 8472 } else { 8473 MulResult = Builder.CreateNUWMul(LHS, RHS); 8474 HigherBits = Builder.CreateLShr(MulResult, 64); 8475 } 8476 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned); 8477 8478 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh) 8479 return HigherBits; 8480 8481 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2)); 8482 Builder.CreateStore(HigherBits, HighBitsAddress); 8483 return Builder.CreateIntCast(MulResult, ResType, IsSigned); 8484 } 8485 8486 case X86::BI__faststorefence: { 8487 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8488 llvm::SyncScope::System); 8489 } 8490 case X86::BI_ReadWriteBarrier: 8491 case X86::BI_ReadBarrier: 8492 case X86::BI_WriteBarrier: { 8493 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, 8494 llvm::SyncScope::SingleThread); 8495 } 8496 case X86::BI_BitScanForward: 8497 case X86::BI_BitScanForward64: 8498 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E); 8499 case X86::BI_BitScanReverse: 8500 case X86::BI_BitScanReverse64: 8501 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E); 8502 8503 case X86::BI_InterlockedAnd64: 8504 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E); 8505 case X86::BI_InterlockedExchange64: 8506 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E); 8507 case X86::BI_InterlockedExchangeAdd64: 8508 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E); 8509 case X86::BI_InterlockedExchangeSub64: 8510 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E); 8511 case X86::BI_InterlockedOr64: 8512 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E); 8513 case X86::BI_InterlockedXor64: 8514 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E); 8515 case X86::BI_InterlockedDecrement64: 8516 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E); 8517 case X86::BI_InterlockedIncrement64: 8518 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E); 8519 8520 case X86::BI_AddressOfReturnAddress: { 8521 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress); 8522 return Builder.CreateCall(F); 8523 } 8524 case X86::BI__stosb: { 8525 // We treat __stosb as a volatile memset - it may not generate "rep stosb" 8526 // instruction, but it will create a memset that won't be optimized away. 8527 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true); 8528 } 8529 case X86::BI__ud2: 8530 // llvm.trap makes a ud2a instruction on x86. 8531 return EmitTrapCall(Intrinsic::trap); 8532 case X86::BI__int2c: { 8533 // This syscall signals a driver assertion failure in x86 NT kernels. 8534 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false); 8535 llvm::InlineAsm *IA = 8536 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true); 8537 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get( 8538 getLLVMContext(), llvm::AttributeList::FunctionIndex, 8539 llvm::Attribute::NoReturn); 8540 CallSite CS = Builder.CreateCall(IA); 8541 CS.setAttributes(NoReturnAttr); 8542 return CS.getInstruction(); 8543 } 8544 case X86::BI__readfsbyte: 8545 case X86::BI__readfsword: 8546 case X86::BI__readfsdword: 8547 case X86::BI__readfsqword: { 8548 llvm::Type *IntTy = ConvertType(E->getType()); 8549 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8550 llvm::PointerType::get(IntTy, 257)); 8551 LoadInst *Load = Builder.CreateAlignedLoad( 8552 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8553 Load->setVolatile(true); 8554 return Load; 8555 } 8556 case X86::BI__readgsbyte: 8557 case X86::BI__readgsword: 8558 case X86::BI__readgsdword: 8559 case X86::BI__readgsqword: { 8560 llvm::Type *IntTy = ConvertType(E->getType()); 8561 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)), 8562 llvm::PointerType::get(IntTy, 256)); 8563 LoadInst *Load = Builder.CreateAlignedLoad( 8564 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType())); 8565 Load->setVolatile(true); 8566 return Load; 8567 } 8568 } 8569 } 8570 8571 8572 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, 8573 const CallExpr *E) { 8574 SmallVector<Value*, 4> Ops; 8575 8576 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) 8577 Ops.push_back(EmitScalarExpr(E->getArg(i))); 8578 8579 Intrinsic::ID ID = Intrinsic::not_intrinsic; 8580 8581 switch (BuiltinID) { 8582 default: return nullptr; 8583 8584 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we 8585 // call __builtin_readcyclecounter. 8586 case PPC::BI__builtin_ppc_get_timebase: 8587 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter)); 8588 8589 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr 8590 case PPC::BI__builtin_altivec_lvx: 8591 case PPC::BI__builtin_altivec_lvxl: 8592 case PPC::BI__builtin_altivec_lvebx: 8593 case PPC::BI__builtin_altivec_lvehx: 8594 case PPC::BI__builtin_altivec_lvewx: 8595 case PPC::BI__builtin_altivec_lvsl: 8596 case PPC::BI__builtin_altivec_lvsr: 8597 case PPC::BI__builtin_vsx_lxvd2x: 8598 case PPC::BI__builtin_vsx_lxvw4x: 8599 case PPC::BI__builtin_vsx_lxvd2x_be: 8600 case PPC::BI__builtin_vsx_lxvw4x_be: 8601 case PPC::BI__builtin_vsx_lxvl: 8602 case PPC::BI__builtin_vsx_lxvll: 8603 { 8604 if(BuiltinID == PPC::BI__builtin_vsx_lxvl || 8605 BuiltinID == PPC::BI__builtin_vsx_lxvll){ 8606 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy); 8607 }else { 8608 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8609 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]); 8610 Ops.pop_back(); 8611 } 8612 8613 switch (BuiltinID) { 8614 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!"); 8615 case PPC::BI__builtin_altivec_lvx: 8616 ID = Intrinsic::ppc_altivec_lvx; 8617 break; 8618 case PPC::BI__builtin_altivec_lvxl: 8619 ID = Intrinsic::ppc_altivec_lvxl; 8620 break; 8621 case PPC::BI__builtin_altivec_lvebx: 8622 ID = Intrinsic::ppc_altivec_lvebx; 8623 break; 8624 case PPC::BI__builtin_altivec_lvehx: 8625 ID = Intrinsic::ppc_altivec_lvehx; 8626 break; 8627 case PPC::BI__builtin_altivec_lvewx: 8628 ID = Intrinsic::ppc_altivec_lvewx; 8629 break; 8630 case PPC::BI__builtin_altivec_lvsl: 8631 ID = Intrinsic::ppc_altivec_lvsl; 8632 break; 8633 case PPC::BI__builtin_altivec_lvsr: 8634 ID = Intrinsic::ppc_altivec_lvsr; 8635 break; 8636 case PPC::BI__builtin_vsx_lxvd2x: 8637 ID = Intrinsic::ppc_vsx_lxvd2x; 8638 break; 8639 case PPC::BI__builtin_vsx_lxvw4x: 8640 ID = Intrinsic::ppc_vsx_lxvw4x; 8641 break; 8642 case PPC::BI__builtin_vsx_lxvd2x_be: 8643 ID = Intrinsic::ppc_vsx_lxvd2x_be; 8644 break; 8645 case PPC::BI__builtin_vsx_lxvw4x_be: 8646 ID = Intrinsic::ppc_vsx_lxvw4x_be; 8647 break; 8648 case PPC::BI__builtin_vsx_lxvl: 8649 ID = Intrinsic::ppc_vsx_lxvl; 8650 break; 8651 case PPC::BI__builtin_vsx_lxvll: 8652 ID = Intrinsic::ppc_vsx_lxvll; 8653 break; 8654 } 8655 llvm::Function *F = CGM.getIntrinsic(ID); 8656 return Builder.CreateCall(F, Ops, ""); 8657 } 8658 8659 // vec_st, vec_xst_be 8660 case PPC::BI__builtin_altivec_stvx: 8661 case PPC::BI__builtin_altivec_stvxl: 8662 case PPC::BI__builtin_altivec_stvebx: 8663 case PPC::BI__builtin_altivec_stvehx: 8664 case PPC::BI__builtin_altivec_stvewx: 8665 case PPC::BI__builtin_vsx_stxvd2x: 8666 case PPC::BI__builtin_vsx_stxvw4x: 8667 case PPC::BI__builtin_vsx_stxvd2x_be: 8668 case PPC::BI__builtin_vsx_stxvw4x_be: 8669 case PPC::BI__builtin_vsx_stxvl: 8670 case PPC::BI__builtin_vsx_stxvll: 8671 { 8672 if(BuiltinID == PPC::BI__builtin_vsx_stxvl || 8673 BuiltinID == PPC::BI__builtin_vsx_stxvll ){ 8674 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy); 8675 }else { 8676 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy); 8677 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]); 8678 Ops.pop_back(); 8679 } 8680 8681 switch (BuiltinID) { 8682 default: llvm_unreachable("Unsupported st intrinsic!"); 8683 case PPC::BI__builtin_altivec_stvx: 8684 ID = Intrinsic::ppc_altivec_stvx; 8685 break; 8686 case PPC::BI__builtin_altivec_stvxl: 8687 ID = Intrinsic::ppc_altivec_stvxl; 8688 break; 8689 case PPC::BI__builtin_altivec_stvebx: 8690 ID = Intrinsic::ppc_altivec_stvebx; 8691 break; 8692 case PPC::BI__builtin_altivec_stvehx: 8693 ID = Intrinsic::ppc_altivec_stvehx; 8694 break; 8695 case PPC::BI__builtin_altivec_stvewx: 8696 ID = Intrinsic::ppc_altivec_stvewx; 8697 break; 8698 case PPC::BI__builtin_vsx_stxvd2x: 8699 ID = Intrinsic::ppc_vsx_stxvd2x; 8700 break; 8701 case PPC::BI__builtin_vsx_stxvw4x: 8702 ID = Intrinsic::ppc_vsx_stxvw4x; 8703 break; 8704 case PPC::BI__builtin_vsx_stxvd2x_be: 8705 ID = Intrinsic::ppc_vsx_stxvd2x_be; 8706 break; 8707 case PPC::BI__builtin_vsx_stxvw4x_be: 8708 ID = Intrinsic::ppc_vsx_stxvw4x_be; 8709 break; 8710 case PPC::BI__builtin_vsx_stxvl: 8711 ID = Intrinsic::ppc_vsx_stxvl; 8712 break; 8713 case PPC::BI__builtin_vsx_stxvll: 8714 ID = Intrinsic::ppc_vsx_stxvll; 8715 break; 8716 } 8717 llvm::Function *F = CGM.getIntrinsic(ID); 8718 return Builder.CreateCall(F, Ops, ""); 8719 } 8720 // Square root 8721 case PPC::BI__builtin_vsx_xvsqrtsp: 8722 case PPC::BI__builtin_vsx_xvsqrtdp: { 8723 llvm::Type *ResultType = ConvertType(E->getType()); 8724 Value *X = EmitScalarExpr(E->getArg(0)); 8725 ID = Intrinsic::sqrt; 8726 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8727 return Builder.CreateCall(F, X); 8728 } 8729 // Count leading zeros 8730 case PPC::BI__builtin_altivec_vclzb: 8731 case PPC::BI__builtin_altivec_vclzh: 8732 case PPC::BI__builtin_altivec_vclzw: 8733 case PPC::BI__builtin_altivec_vclzd: { 8734 llvm::Type *ResultType = ConvertType(E->getType()); 8735 Value *X = EmitScalarExpr(E->getArg(0)); 8736 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8737 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 8738 return Builder.CreateCall(F, {X, Undef}); 8739 } 8740 case PPC::BI__builtin_altivec_vctzb: 8741 case PPC::BI__builtin_altivec_vctzh: 8742 case PPC::BI__builtin_altivec_vctzw: 8743 case PPC::BI__builtin_altivec_vctzd: { 8744 llvm::Type *ResultType = ConvertType(E->getType()); 8745 Value *X = EmitScalarExpr(E->getArg(0)); 8746 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 8747 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 8748 return Builder.CreateCall(F, {X, Undef}); 8749 } 8750 case PPC::BI__builtin_altivec_vpopcntb: 8751 case PPC::BI__builtin_altivec_vpopcnth: 8752 case PPC::BI__builtin_altivec_vpopcntw: 8753 case PPC::BI__builtin_altivec_vpopcntd: { 8754 llvm::Type *ResultType = ConvertType(E->getType()); 8755 Value *X = EmitScalarExpr(E->getArg(0)); 8756 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 8757 return Builder.CreateCall(F, X); 8758 } 8759 // Copy sign 8760 case PPC::BI__builtin_vsx_xvcpsgnsp: 8761 case PPC::BI__builtin_vsx_xvcpsgndp: { 8762 llvm::Type *ResultType = ConvertType(E->getType()); 8763 Value *X = EmitScalarExpr(E->getArg(0)); 8764 Value *Y = EmitScalarExpr(E->getArg(1)); 8765 ID = Intrinsic::copysign; 8766 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8767 return Builder.CreateCall(F, {X, Y}); 8768 } 8769 // Rounding/truncation 8770 case PPC::BI__builtin_vsx_xvrspip: 8771 case PPC::BI__builtin_vsx_xvrdpip: 8772 case PPC::BI__builtin_vsx_xvrdpim: 8773 case PPC::BI__builtin_vsx_xvrspim: 8774 case PPC::BI__builtin_vsx_xvrdpi: 8775 case PPC::BI__builtin_vsx_xvrspi: 8776 case PPC::BI__builtin_vsx_xvrdpic: 8777 case PPC::BI__builtin_vsx_xvrspic: 8778 case PPC::BI__builtin_vsx_xvrdpiz: 8779 case PPC::BI__builtin_vsx_xvrspiz: { 8780 llvm::Type *ResultType = ConvertType(E->getType()); 8781 Value *X = EmitScalarExpr(E->getArg(0)); 8782 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim || 8783 BuiltinID == PPC::BI__builtin_vsx_xvrspim) 8784 ID = Intrinsic::floor; 8785 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi || 8786 BuiltinID == PPC::BI__builtin_vsx_xvrspi) 8787 ID = Intrinsic::round; 8788 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic || 8789 BuiltinID == PPC::BI__builtin_vsx_xvrspic) 8790 ID = Intrinsic::nearbyint; 8791 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip || 8792 BuiltinID == PPC::BI__builtin_vsx_xvrspip) 8793 ID = Intrinsic::ceil; 8794 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz || 8795 BuiltinID == PPC::BI__builtin_vsx_xvrspiz) 8796 ID = Intrinsic::trunc; 8797 llvm::Function *F = CGM.getIntrinsic(ID, ResultType); 8798 return Builder.CreateCall(F, X); 8799 } 8800 8801 // Absolute value 8802 case PPC::BI__builtin_vsx_xvabsdp: 8803 case PPC::BI__builtin_vsx_xvabssp: { 8804 llvm::Type *ResultType = ConvertType(E->getType()); 8805 Value *X = EmitScalarExpr(E->getArg(0)); 8806 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 8807 return Builder.CreateCall(F, X); 8808 } 8809 8810 // FMA variations 8811 case PPC::BI__builtin_vsx_xvmaddadp: 8812 case PPC::BI__builtin_vsx_xvmaddasp: 8813 case PPC::BI__builtin_vsx_xvnmaddadp: 8814 case PPC::BI__builtin_vsx_xvnmaddasp: 8815 case PPC::BI__builtin_vsx_xvmsubadp: 8816 case PPC::BI__builtin_vsx_xvmsubasp: 8817 case PPC::BI__builtin_vsx_xvnmsubadp: 8818 case PPC::BI__builtin_vsx_xvnmsubasp: { 8819 llvm::Type *ResultType = ConvertType(E->getType()); 8820 Value *X = EmitScalarExpr(E->getArg(0)); 8821 Value *Y = EmitScalarExpr(E->getArg(1)); 8822 Value *Z = EmitScalarExpr(E->getArg(2)); 8823 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 8824 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 8825 switch (BuiltinID) { 8826 case PPC::BI__builtin_vsx_xvmaddadp: 8827 case PPC::BI__builtin_vsx_xvmaddasp: 8828 return Builder.CreateCall(F, {X, Y, Z}); 8829 case PPC::BI__builtin_vsx_xvnmaddadp: 8830 case PPC::BI__builtin_vsx_xvnmaddasp: 8831 return Builder.CreateFSub(Zero, 8832 Builder.CreateCall(F, {X, Y, Z}), "sub"); 8833 case PPC::BI__builtin_vsx_xvmsubadp: 8834 case PPC::BI__builtin_vsx_xvmsubasp: 8835 return Builder.CreateCall(F, 8836 {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8837 case PPC::BI__builtin_vsx_xvnmsubadp: 8838 case PPC::BI__builtin_vsx_xvnmsubasp: 8839 Value *FsubRes = 8840 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 8841 return Builder.CreateFSub(Zero, FsubRes, "sub"); 8842 } 8843 llvm_unreachable("Unknown FMA operation"); 8844 return nullptr; // Suppress no-return warning 8845 } 8846 8847 case PPC::BI__builtin_vsx_insertword: { 8848 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw); 8849 8850 // Third argument is a compile time constant int. It must be clamped to 8851 // to the range [0, 12]. 8852 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8853 assert(ArgCI && 8854 "Third arg to xxinsertw intrinsic must be constant integer"); 8855 const int64_t MaxIndex = 12; 8856 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8857 8858 // The builtin semantics don't exactly match the xxinsertw instructions 8859 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the 8860 // word from the first argument, and inserts it in the second argument. The 8861 // instruction extracts the word from its second input register and inserts 8862 // it into its first input register, so swap the first and second arguments. 8863 std::swap(Ops[0], Ops[1]); 8864 8865 // Need to cast the second argument from a vector of unsigned int to a 8866 // vector of long long. 8867 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8868 8869 if (getTarget().isLittleEndian()) { 8870 // Create a shuffle mask of (1, 0) 8871 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8872 ConstantInt::get(Int32Ty, 0) 8873 }; 8874 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8875 8876 // Reverse the double words in the vector we will extract from. 8877 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8878 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask); 8879 8880 // Reverse the index. 8881 Index = MaxIndex - Index; 8882 } 8883 8884 // Intrinsic expects the first arg to be a vector of int. 8885 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8886 Ops[2] = ConstantInt::getSigned(Int32Ty, Index); 8887 return Builder.CreateCall(F, Ops); 8888 } 8889 8890 case PPC::BI__builtin_vsx_extractuword: { 8891 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw); 8892 8893 // Intrinsic expects the first argument to be a vector of doublewords. 8894 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8895 8896 // The second argument is a compile time constant int that needs to 8897 // be clamped to the range [0, 12]. 8898 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]); 8899 assert(ArgCI && 8900 "Second Arg to xxextractuw intrinsic must be a constant integer!"); 8901 const int64_t MaxIndex = 12; 8902 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex); 8903 8904 if (getTarget().isLittleEndian()) { 8905 // Reverse the index. 8906 Index = MaxIndex - Index; 8907 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8908 8909 // Emit the call, then reverse the double words of the results vector. 8910 Value *Call = Builder.CreateCall(F, Ops); 8911 8912 // Create a shuffle mask of (1, 0) 8913 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1), 8914 ConstantInt::get(Int32Ty, 0) 8915 }; 8916 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8917 8918 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask); 8919 return ShuffleCall; 8920 } else { 8921 Ops[1] = ConstantInt::getSigned(Int32Ty, Index); 8922 return Builder.CreateCall(F, Ops); 8923 } 8924 } 8925 8926 case PPC::BI__builtin_vsx_xxpermdi: { 8927 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8928 assert(ArgCI && "Third arg must be constant integer!"); 8929 8930 unsigned Index = ArgCI->getZExtValue(); 8931 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2)); 8932 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2)); 8933 8934 // Element zero comes from the first input vector and element one comes from 8935 // the second. The element indices within each vector are numbered in big 8936 // endian order so the shuffle mask must be adjusted for this on little 8937 // endian platforms (i.e. index is complemented and source vector reversed). 8938 unsigned ElemIdx0; 8939 unsigned ElemIdx1; 8940 if (getTarget().isLittleEndian()) { 8941 ElemIdx0 = (~Index & 1) + 2; 8942 ElemIdx1 = (~Index & 2) >> 1; 8943 } else { // BigEndian 8944 ElemIdx0 = (Index & 2) >> 1; 8945 ElemIdx1 = 2 + (Index & 1); 8946 } 8947 8948 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0), 8949 ConstantInt::get(Int32Ty, ElemIdx1)}; 8950 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8951 8952 Value *ShuffleCall = 8953 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8954 QualType BIRetType = E->getType(); 8955 auto RetTy = ConvertType(BIRetType); 8956 return Builder.CreateBitCast(ShuffleCall, RetTy); 8957 } 8958 8959 case PPC::BI__builtin_vsx_xxsldwi: { 8960 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]); 8961 assert(ArgCI && "Third argument must be a compile time constant"); 8962 unsigned Index = ArgCI->getZExtValue() & 0x3; 8963 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4)); 8964 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4)); 8965 8966 // Create a shuffle mask 8967 unsigned ElemIdx0; 8968 unsigned ElemIdx1; 8969 unsigned ElemIdx2; 8970 unsigned ElemIdx3; 8971 if (getTarget().isLittleEndian()) { 8972 // Little endian element N comes from element 8+N-Index of the 8973 // concatenated wide vector (of course, using modulo arithmetic on 8974 // the total number of elements). 8975 ElemIdx0 = (8 - Index) % 8; 8976 ElemIdx1 = (9 - Index) % 8; 8977 ElemIdx2 = (10 - Index) % 8; 8978 ElemIdx3 = (11 - Index) % 8; 8979 } else { 8980 // Big endian ElemIdx<N> = Index + N 8981 ElemIdx0 = Index; 8982 ElemIdx1 = Index + 1; 8983 ElemIdx2 = Index + 2; 8984 ElemIdx3 = Index + 3; 8985 } 8986 8987 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0), 8988 ConstantInt::get(Int32Ty, ElemIdx1), 8989 ConstantInt::get(Int32Ty, ElemIdx2), 8990 ConstantInt::get(Int32Ty, ElemIdx3)}; 8991 8992 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts); 8993 Value *ShuffleCall = 8994 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask); 8995 QualType BIRetType = E->getType(); 8996 auto RetTy = ConvertType(BIRetType); 8997 return Builder.CreateBitCast(ShuffleCall, RetTy); 8998 } 8999 } 9000 } 9001 9002 Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID, 9003 const CallExpr *E) { 9004 switch (BuiltinID) { 9005 case AMDGPU::BI__builtin_amdgcn_div_scale: 9006 case AMDGPU::BI__builtin_amdgcn_div_scalef: { 9007 // Translate from the intrinsics's struct return to the builtin's out 9008 // argument. 9009 9010 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3)); 9011 9012 llvm::Value *X = EmitScalarExpr(E->getArg(0)); 9013 llvm::Value *Y = EmitScalarExpr(E->getArg(1)); 9014 llvm::Value *Z = EmitScalarExpr(E->getArg(2)); 9015 9016 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale, 9017 X->getType()); 9018 9019 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z}); 9020 9021 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0); 9022 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1); 9023 9024 llvm::Type *RealFlagType 9025 = FlagOutPtr.getPointer()->getType()->getPointerElementType(); 9026 9027 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType); 9028 Builder.CreateStore(FlagExt, FlagOutPtr); 9029 return Result; 9030 } 9031 case AMDGPU::BI__builtin_amdgcn_div_fmas: 9032 case AMDGPU::BI__builtin_amdgcn_div_fmasf: { 9033 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0)); 9034 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1)); 9035 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2)); 9036 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3)); 9037 9038 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas, 9039 Src0->getType()); 9040 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3); 9041 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool}); 9042 } 9043 9044 case AMDGPU::BI__builtin_amdgcn_ds_swizzle: 9045 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle); 9046 case AMDGPU::BI__builtin_amdgcn_mov_dpp: { 9047 llvm::SmallVector<llvm::Value *, 5> Args; 9048 for (unsigned I = 0; I != 5; ++I) 9049 Args.push_back(EmitScalarExpr(E->getArg(I))); 9050 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp, 9051 Args[0]->getType()); 9052 return Builder.CreateCall(F, Args); 9053 } 9054 case AMDGPU::BI__builtin_amdgcn_div_fixup: 9055 case AMDGPU::BI__builtin_amdgcn_div_fixupf: 9056 case AMDGPU::BI__builtin_amdgcn_div_fixuph: 9057 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup); 9058 case AMDGPU::BI__builtin_amdgcn_trig_preop: 9059 case AMDGPU::BI__builtin_amdgcn_trig_preopf: 9060 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop); 9061 case AMDGPU::BI__builtin_amdgcn_rcp: 9062 case AMDGPU::BI__builtin_amdgcn_rcpf: 9063 case AMDGPU::BI__builtin_amdgcn_rcph: 9064 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp); 9065 case AMDGPU::BI__builtin_amdgcn_rsq: 9066 case AMDGPU::BI__builtin_amdgcn_rsqf: 9067 case AMDGPU::BI__builtin_amdgcn_rsqh: 9068 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq); 9069 case AMDGPU::BI__builtin_amdgcn_rsq_clamp: 9070 case AMDGPU::BI__builtin_amdgcn_rsq_clampf: 9071 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp); 9072 case AMDGPU::BI__builtin_amdgcn_sinf: 9073 case AMDGPU::BI__builtin_amdgcn_sinh: 9074 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin); 9075 case AMDGPU::BI__builtin_amdgcn_cosf: 9076 case AMDGPU::BI__builtin_amdgcn_cosh: 9077 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos); 9078 case AMDGPU::BI__builtin_amdgcn_log_clampf: 9079 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp); 9080 case AMDGPU::BI__builtin_amdgcn_ldexp: 9081 case AMDGPU::BI__builtin_amdgcn_ldexpf: 9082 case AMDGPU::BI__builtin_amdgcn_ldexph: 9083 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp); 9084 case AMDGPU::BI__builtin_amdgcn_frexp_mant: 9085 case AMDGPU::BI__builtin_amdgcn_frexp_mantf: 9086 case AMDGPU::BI__builtin_amdgcn_frexp_manth: 9087 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant); 9088 case AMDGPU::BI__builtin_amdgcn_frexp_exp: 9089 case AMDGPU::BI__builtin_amdgcn_frexp_expf: { 9090 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9091 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9092 { Builder.getInt32Ty(), Src0->getType() }); 9093 return Builder.CreateCall(F, Src0); 9094 } 9095 case AMDGPU::BI__builtin_amdgcn_frexp_exph: { 9096 Value *Src0 = EmitScalarExpr(E->getArg(0)); 9097 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp, 9098 { Builder.getInt16Ty(), Src0->getType() }); 9099 return Builder.CreateCall(F, Src0); 9100 } 9101 case AMDGPU::BI__builtin_amdgcn_fract: 9102 case AMDGPU::BI__builtin_amdgcn_fractf: 9103 case AMDGPU::BI__builtin_amdgcn_fracth: 9104 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract); 9105 case AMDGPU::BI__builtin_amdgcn_lerp: 9106 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp); 9107 case AMDGPU::BI__builtin_amdgcn_uicmp: 9108 case AMDGPU::BI__builtin_amdgcn_uicmpl: 9109 case AMDGPU::BI__builtin_amdgcn_sicmp: 9110 case AMDGPU::BI__builtin_amdgcn_sicmpl: 9111 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp); 9112 case AMDGPU::BI__builtin_amdgcn_fcmp: 9113 case AMDGPU::BI__builtin_amdgcn_fcmpf: 9114 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp); 9115 case AMDGPU::BI__builtin_amdgcn_class: 9116 case AMDGPU::BI__builtin_amdgcn_classf: 9117 case AMDGPU::BI__builtin_amdgcn_classh: 9118 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class); 9119 case AMDGPU::BI__builtin_amdgcn_fmed3f: 9120 case AMDGPU::BI__builtin_amdgcn_fmed3h: 9121 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3); 9122 case AMDGPU::BI__builtin_amdgcn_read_exec: { 9123 CallInst *CI = cast<CallInst>( 9124 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec")); 9125 CI->setConvergent(); 9126 return CI; 9127 } 9128 case AMDGPU::BI__builtin_amdgcn_read_exec_lo: 9129 case AMDGPU::BI__builtin_amdgcn_read_exec_hi: { 9130 StringRef RegName = BuiltinID == AMDGPU::BI__builtin_amdgcn_read_exec_lo ? 9131 "exec_lo" : "exec_hi"; 9132 CallInst *CI = cast<CallInst>( 9133 EmitSpecialRegisterBuiltin(*this, E, Int32Ty, Int32Ty, true, RegName)); 9134 CI->setConvergent(); 9135 return CI; 9136 } 9137 9138 // amdgcn workitem 9139 case AMDGPU::BI__builtin_amdgcn_workitem_id_x: 9140 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024); 9141 case AMDGPU::BI__builtin_amdgcn_workitem_id_y: 9142 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024); 9143 case AMDGPU::BI__builtin_amdgcn_workitem_id_z: 9144 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024); 9145 9146 // r600 intrinsics 9147 case AMDGPU::BI__builtin_r600_recipsqrt_ieee: 9148 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef: 9149 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee); 9150 case AMDGPU::BI__builtin_r600_read_tidig_x: 9151 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024); 9152 case AMDGPU::BI__builtin_r600_read_tidig_y: 9153 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024); 9154 case AMDGPU::BI__builtin_r600_read_tidig_z: 9155 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024); 9156 default: 9157 return nullptr; 9158 } 9159 } 9160 9161 /// Handle a SystemZ function in which the final argument is a pointer 9162 /// to an int that receives the post-instruction CC value. At the LLVM level 9163 /// this is represented as a function that returns a {result, cc} pair. 9164 static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF, 9165 unsigned IntrinsicID, 9166 const CallExpr *E) { 9167 unsigned NumArgs = E->getNumArgs() - 1; 9168 SmallVector<Value *, 8> Args(NumArgs); 9169 for (unsigned I = 0; I < NumArgs; ++I) 9170 Args[I] = CGF.EmitScalarExpr(E->getArg(I)); 9171 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs)); 9172 Value *F = CGF.CGM.getIntrinsic(IntrinsicID); 9173 Value *Call = CGF.Builder.CreateCall(F, Args); 9174 Value *CC = CGF.Builder.CreateExtractValue(Call, 1); 9175 CGF.Builder.CreateStore(CC, CCPtr); 9176 return CGF.Builder.CreateExtractValue(Call, 0); 9177 } 9178 9179 Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID, 9180 const CallExpr *E) { 9181 switch (BuiltinID) { 9182 case SystemZ::BI__builtin_tbegin: { 9183 Value *TDB = EmitScalarExpr(E->getArg(0)); 9184 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9185 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin); 9186 return Builder.CreateCall(F, {TDB, Control}); 9187 } 9188 case SystemZ::BI__builtin_tbegin_nofloat: { 9189 Value *TDB = EmitScalarExpr(E->getArg(0)); 9190 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c); 9191 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat); 9192 return Builder.CreateCall(F, {TDB, Control}); 9193 } 9194 case SystemZ::BI__builtin_tbeginc: { 9195 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy); 9196 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08); 9197 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc); 9198 return Builder.CreateCall(F, {TDB, Control}); 9199 } 9200 case SystemZ::BI__builtin_tabort: { 9201 Value *Data = EmitScalarExpr(E->getArg(0)); 9202 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort); 9203 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort")); 9204 } 9205 case SystemZ::BI__builtin_non_tx_store: { 9206 Value *Address = EmitScalarExpr(E->getArg(0)); 9207 Value *Data = EmitScalarExpr(E->getArg(1)); 9208 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg); 9209 return Builder.CreateCall(F, {Data, Address}); 9210 } 9211 9212 // Vector builtins. Note that most vector builtins are mapped automatically 9213 // to target-specific LLVM intrinsics. The ones handled specially here can 9214 // be represented via standard LLVM IR, which is preferable to enable common 9215 // LLVM optimizations. 9216 9217 case SystemZ::BI__builtin_s390_vpopctb: 9218 case SystemZ::BI__builtin_s390_vpopcth: 9219 case SystemZ::BI__builtin_s390_vpopctf: 9220 case SystemZ::BI__builtin_s390_vpopctg: { 9221 llvm::Type *ResultType = ConvertType(E->getType()); 9222 Value *X = EmitScalarExpr(E->getArg(0)); 9223 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType); 9224 return Builder.CreateCall(F, X); 9225 } 9226 9227 case SystemZ::BI__builtin_s390_vclzb: 9228 case SystemZ::BI__builtin_s390_vclzh: 9229 case SystemZ::BI__builtin_s390_vclzf: 9230 case SystemZ::BI__builtin_s390_vclzg: { 9231 llvm::Type *ResultType = ConvertType(E->getType()); 9232 Value *X = EmitScalarExpr(E->getArg(0)); 9233 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9234 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType); 9235 return Builder.CreateCall(F, {X, Undef}); 9236 } 9237 9238 case SystemZ::BI__builtin_s390_vctzb: 9239 case SystemZ::BI__builtin_s390_vctzh: 9240 case SystemZ::BI__builtin_s390_vctzf: 9241 case SystemZ::BI__builtin_s390_vctzg: { 9242 llvm::Type *ResultType = ConvertType(E->getType()); 9243 Value *X = EmitScalarExpr(E->getArg(0)); 9244 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false); 9245 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType); 9246 return Builder.CreateCall(F, {X, Undef}); 9247 } 9248 9249 case SystemZ::BI__builtin_s390_vfsqsb: 9250 case SystemZ::BI__builtin_s390_vfsqdb: { 9251 llvm::Type *ResultType = ConvertType(E->getType()); 9252 Value *X = EmitScalarExpr(E->getArg(0)); 9253 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType); 9254 return Builder.CreateCall(F, X); 9255 } 9256 case SystemZ::BI__builtin_s390_vfmasb: 9257 case SystemZ::BI__builtin_s390_vfmadb: { 9258 llvm::Type *ResultType = ConvertType(E->getType()); 9259 Value *X = EmitScalarExpr(E->getArg(0)); 9260 Value *Y = EmitScalarExpr(E->getArg(1)); 9261 Value *Z = EmitScalarExpr(E->getArg(2)); 9262 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9263 return Builder.CreateCall(F, {X, Y, Z}); 9264 } 9265 case SystemZ::BI__builtin_s390_vfmssb: 9266 case SystemZ::BI__builtin_s390_vfmsdb: { 9267 llvm::Type *ResultType = ConvertType(E->getType()); 9268 Value *X = EmitScalarExpr(E->getArg(0)); 9269 Value *Y = EmitScalarExpr(E->getArg(1)); 9270 Value *Z = EmitScalarExpr(E->getArg(2)); 9271 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9272 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9273 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")}); 9274 } 9275 case SystemZ::BI__builtin_s390_vfnmasb: 9276 case SystemZ::BI__builtin_s390_vfnmadb: { 9277 llvm::Type *ResultType = ConvertType(E->getType()); 9278 Value *X = EmitScalarExpr(E->getArg(0)); 9279 Value *Y = EmitScalarExpr(E->getArg(1)); 9280 Value *Z = EmitScalarExpr(E->getArg(2)); 9281 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9282 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9283 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub"); 9284 } 9285 case SystemZ::BI__builtin_s390_vfnmssb: 9286 case SystemZ::BI__builtin_s390_vfnmsdb: { 9287 llvm::Type *ResultType = ConvertType(E->getType()); 9288 Value *X = EmitScalarExpr(E->getArg(0)); 9289 Value *Y = EmitScalarExpr(E->getArg(1)); 9290 Value *Z = EmitScalarExpr(E->getArg(2)); 9291 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9292 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType); 9293 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub"); 9294 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ})); 9295 } 9296 case SystemZ::BI__builtin_s390_vflpsb: 9297 case SystemZ::BI__builtin_s390_vflpdb: { 9298 llvm::Type *ResultType = ConvertType(E->getType()); 9299 Value *X = EmitScalarExpr(E->getArg(0)); 9300 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9301 return Builder.CreateCall(F, X); 9302 } 9303 case SystemZ::BI__builtin_s390_vflnsb: 9304 case SystemZ::BI__builtin_s390_vflndb: { 9305 llvm::Type *ResultType = ConvertType(E->getType()); 9306 Value *X = EmitScalarExpr(E->getArg(0)); 9307 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType); 9308 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType); 9309 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub"); 9310 } 9311 case SystemZ::BI__builtin_s390_vfisb: 9312 case SystemZ::BI__builtin_s390_vfidb: { 9313 llvm::Type *ResultType = ConvertType(E->getType()); 9314 Value *X = EmitScalarExpr(E->getArg(0)); 9315 // Constant-fold the M4 and M5 mask arguments. 9316 llvm::APSInt M4, M5; 9317 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext()); 9318 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext()); 9319 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?"); 9320 (void)IsConstM4; (void)IsConstM5; 9321 // Check whether this instance can be represented via a LLVM standard 9322 // intrinsic. We only support some combinations of M4 and M5. 9323 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9324 switch (M4.getZExtValue()) { 9325 default: break; 9326 case 0: // IEEE-inexact exception allowed 9327 switch (M5.getZExtValue()) { 9328 default: break; 9329 case 0: ID = Intrinsic::rint; break; 9330 } 9331 break; 9332 case 4: // IEEE-inexact exception suppressed 9333 switch (M5.getZExtValue()) { 9334 default: break; 9335 case 0: ID = Intrinsic::nearbyint; break; 9336 case 1: ID = Intrinsic::round; break; 9337 case 5: ID = Intrinsic::trunc; break; 9338 case 6: ID = Intrinsic::ceil; break; 9339 case 7: ID = Intrinsic::floor; break; 9340 } 9341 break; 9342 } 9343 if (ID != Intrinsic::not_intrinsic) { 9344 Function *F = CGM.getIntrinsic(ID, ResultType); 9345 return Builder.CreateCall(F, X); 9346 } 9347 switch (BuiltinID) { 9348 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break; 9349 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break; 9350 default: llvm_unreachable("Unknown BuiltinID"); 9351 } 9352 Function *F = CGM.getIntrinsic(ID); 9353 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9354 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5); 9355 return Builder.CreateCall(F, {X, M4Value, M5Value}); 9356 } 9357 case SystemZ::BI__builtin_s390_vfmaxsb: 9358 case SystemZ::BI__builtin_s390_vfmaxdb: { 9359 llvm::Type *ResultType = ConvertType(E->getType()); 9360 Value *X = EmitScalarExpr(E->getArg(0)); 9361 Value *Y = EmitScalarExpr(E->getArg(1)); 9362 // Constant-fold the M4 mask argument. 9363 llvm::APSInt M4; 9364 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9365 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9366 (void)IsConstM4; 9367 // Check whether this instance can be represented via a LLVM standard 9368 // intrinsic. We only support some values of M4. 9369 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9370 switch (M4.getZExtValue()) { 9371 default: break; 9372 case 4: ID = Intrinsic::maxnum; break; 9373 } 9374 if (ID != Intrinsic::not_intrinsic) { 9375 Function *F = CGM.getIntrinsic(ID, ResultType); 9376 return Builder.CreateCall(F, {X, Y}); 9377 } 9378 switch (BuiltinID) { 9379 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break; 9380 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break; 9381 default: llvm_unreachable("Unknown BuiltinID"); 9382 } 9383 Function *F = CGM.getIntrinsic(ID); 9384 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9385 return Builder.CreateCall(F, {X, Y, M4Value}); 9386 } 9387 case SystemZ::BI__builtin_s390_vfminsb: 9388 case SystemZ::BI__builtin_s390_vfmindb: { 9389 llvm::Type *ResultType = ConvertType(E->getType()); 9390 Value *X = EmitScalarExpr(E->getArg(0)); 9391 Value *Y = EmitScalarExpr(E->getArg(1)); 9392 // Constant-fold the M4 mask argument. 9393 llvm::APSInt M4; 9394 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext()); 9395 assert(IsConstM4 && "Constant arg isn't actually constant?"); 9396 (void)IsConstM4; 9397 // Check whether this instance can be represented via a LLVM standard 9398 // intrinsic. We only support some values of M4. 9399 Intrinsic::ID ID = Intrinsic::not_intrinsic; 9400 switch (M4.getZExtValue()) { 9401 default: break; 9402 case 4: ID = Intrinsic::minnum; break; 9403 } 9404 if (ID != Intrinsic::not_intrinsic) { 9405 Function *F = CGM.getIntrinsic(ID, ResultType); 9406 return Builder.CreateCall(F, {X, Y}); 9407 } 9408 switch (BuiltinID) { 9409 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break; 9410 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break; 9411 default: llvm_unreachable("Unknown BuiltinID"); 9412 } 9413 Function *F = CGM.getIntrinsic(ID); 9414 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4); 9415 return Builder.CreateCall(F, {X, Y, M4Value}); 9416 } 9417 9418 // Vector intrisincs that output the post-instruction CC value. 9419 9420 #define INTRINSIC_WITH_CC(NAME) \ 9421 case SystemZ::BI__builtin_##NAME: \ 9422 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E) 9423 9424 INTRINSIC_WITH_CC(s390_vpkshs); 9425 INTRINSIC_WITH_CC(s390_vpksfs); 9426 INTRINSIC_WITH_CC(s390_vpksgs); 9427 9428 INTRINSIC_WITH_CC(s390_vpklshs); 9429 INTRINSIC_WITH_CC(s390_vpklsfs); 9430 INTRINSIC_WITH_CC(s390_vpklsgs); 9431 9432 INTRINSIC_WITH_CC(s390_vceqbs); 9433 INTRINSIC_WITH_CC(s390_vceqhs); 9434 INTRINSIC_WITH_CC(s390_vceqfs); 9435 INTRINSIC_WITH_CC(s390_vceqgs); 9436 9437 INTRINSIC_WITH_CC(s390_vchbs); 9438 INTRINSIC_WITH_CC(s390_vchhs); 9439 INTRINSIC_WITH_CC(s390_vchfs); 9440 INTRINSIC_WITH_CC(s390_vchgs); 9441 9442 INTRINSIC_WITH_CC(s390_vchlbs); 9443 INTRINSIC_WITH_CC(s390_vchlhs); 9444 INTRINSIC_WITH_CC(s390_vchlfs); 9445 INTRINSIC_WITH_CC(s390_vchlgs); 9446 9447 INTRINSIC_WITH_CC(s390_vfaebs); 9448 INTRINSIC_WITH_CC(s390_vfaehs); 9449 INTRINSIC_WITH_CC(s390_vfaefs); 9450 9451 INTRINSIC_WITH_CC(s390_vfaezbs); 9452 INTRINSIC_WITH_CC(s390_vfaezhs); 9453 INTRINSIC_WITH_CC(s390_vfaezfs); 9454 9455 INTRINSIC_WITH_CC(s390_vfeebs); 9456 INTRINSIC_WITH_CC(s390_vfeehs); 9457 INTRINSIC_WITH_CC(s390_vfeefs); 9458 9459 INTRINSIC_WITH_CC(s390_vfeezbs); 9460 INTRINSIC_WITH_CC(s390_vfeezhs); 9461 INTRINSIC_WITH_CC(s390_vfeezfs); 9462 9463 INTRINSIC_WITH_CC(s390_vfenebs); 9464 INTRINSIC_WITH_CC(s390_vfenehs); 9465 INTRINSIC_WITH_CC(s390_vfenefs); 9466 9467 INTRINSIC_WITH_CC(s390_vfenezbs); 9468 INTRINSIC_WITH_CC(s390_vfenezhs); 9469 INTRINSIC_WITH_CC(s390_vfenezfs); 9470 9471 INTRINSIC_WITH_CC(s390_vistrbs); 9472 INTRINSIC_WITH_CC(s390_vistrhs); 9473 INTRINSIC_WITH_CC(s390_vistrfs); 9474 9475 INTRINSIC_WITH_CC(s390_vstrcbs); 9476 INTRINSIC_WITH_CC(s390_vstrchs); 9477 INTRINSIC_WITH_CC(s390_vstrcfs); 9478 9479 INTRINSIC_WITH_CC(s390_vstrczbs); 9480 INTRINSIC_WITH_CC(s390_vstrczhs); 9481 INTRINSIC_WITH_CC(s390_vstrczfs); 9482 9483 INTRINSIC_WITH_CC(s390_vfcesbs); 9484 INTRINSIC_WITH_CC(s390_vfcedbs); 9485 INTRINSIC_WITH_CC(s390_vfchsbs); 9486 INTRINSIC_WITH_CC(s390_vfchdbs); 9487 INTRINSIC_WITH_CC(s390_vfchesbs); 9488 INTRINSIC_WITH_CC(s390_vfchedbs); 9489 9490 INTRINSIC_WITH_CC(s390_vftcisb); 9491 INTRINSIC_WITH_CC(s390_vftcidb); 9492 9493 #undef INTRINSIC_WITH_CC 9494 9495 default: 9496 return nullptr; 9497 } 9498 } 9499 9500 Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, 9501 const CallExpr *E) { 9502 auto MakeLdg = [&](unsigned IntrinsicID) { 9503 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9504 clang::CharUnits Align = 9505 getNaturalPointeeTypeAlignment(E->getArg(0)->getType()); 9506 return Builder.CreateCall( 9507 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9508 Ptr->getType()}), 9509 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())}); 9510 }; 9511 auto MakeScopedAtomic = [&](unsigned IntrinsicID) { 9512 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9513 return Builder.CreateCall( 9514 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(), 9515 Ptr->getType()}), 9516 {Ptr, EmitScalarExpr(E->getArg(1))}); 9517 }; 9518 switch (BuiltinID) { 9519 case NVPTX::BI__nvvm_atom_add_gen_i: 9520 case NVPTX::BI__nvvm_atom_add_gen_l: 9521 case NVPTX::BI__nvvm_atom_add_gen_ll: 9522 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E); 9523 9524 case NVPTX::BI__nvvm_atom_sub_gen_i: 9525 case NVPTX::BI__nvvm_atom_sub_gen_l: 9526 case NVPTX::BI__nvvm_atom_sub_gen_ll: 9527 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E); 9528 9529 case NVPTX::BI__nvvm_atom_and_gen_i: 9530 case NVPTX::BI__nvvm_atom_and_gen_l: 9531 case NVPTX::BI__nvvm_atom_and_gen_ll: 9532 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E); 9533 9534 case NVPTX::BI__nvvm_atom_or_gen_i: 9535 case NVPTX::BI__nvvm_atom_or_gen_l: 9536 case NVPTX::BI__nvvm_atom_or_gen_ll: 9537 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E); 9538 9539 case NVPTX::BI__nvvm_atom_xor_gen_i: 9540 case NVPTX::BI__nvvm_atom_xor_gen_l: 9541 case NVPTX::BI__nvvm_atom_xor_gen_ll: 9542 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E); 9543 9544 case NVPTX::BI__nvvm_atom_xchg_gen_i: 9545 case NVPTX::BI__nvvm_atom_xchg_gen_l: 9546 case NVPTX::BI__nvvm_atom_xchg_gen_ll: 9547 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E); 9548 9549 case NVPTX::BI__nvvm_atom_max_gen_i: 9550 case NVPTX::BI__nvvm_atom_max_gen_l: 9551 case NVPTX::BI__nvvm_atom_max_gen_ll: 9552 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E); 9553 9554 case NVPTX::BI__nvvm_atom_max_gen_ui: 9555 case NVPTX::BI__nvvm_atom_max_gen_ul: 9556 case NVPTX::BI__nvvm_atom_max_gen_ull: 9557 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E); 9558 9559 case NVPTX::BI__nvvm_atom_min_gen_i: 9560 case NVPTX::BI__nvvm_atom_min_gen_l: 9561 case NVPTX::BI__nvvm_atom_min_gen_ll: 9562 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E); 9563 9564 case NVPTX::BI__nvvm_atom_min_gen_ui: 9565 case NVPTX::BI__nvvm_atom_min_gen_ul: 9566 case NVPTX::BI__nvvm_atom_min_gen_ull: 9567 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E); 9568 9569 case NVPTX::BI__nvvm_atom_cas_gen_i: 9570 case NVPTX::BI__nvvm_atom_cas_gen_l: 9571 case NVPTX::BI__nvvm_atom_cas_gen_ll: 9572 // __nvvm_atom_cas_gen_* should return the old value rather than the 9573 // success flag. 9574 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false); 9575 9576 case NVPTX::BI__nvvm_atom_add_gen_f: { 9577 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9578 Value *Val = EmitScalarExpr(E->getArg(1)); 9579 // atomicrmw only deals with integer arguments so we need to use 9580 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that. 9581 Value *FnALAF32 = 9582 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType()); 9583 return Builder.CreateCall(FnALAF32, {Ptr, Val}); 9584 } 9585 9586 case NVPTX::BI__nvvm_atom_inc_gen_ui: { 9587 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9588 Value *Val = EmitScalarExpr(E->getArg(1)); 9589 Value *FnALI32 = 9590 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType()); 9591 return Builder.CreateCall(FnALI32, {Ptr, Val}); 9592 } 9593 9594 case NVPTX::BI__nvvm_atom_dec_gen_ui: { 9595 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9596 Value *Val = EmitScalarExpr(E->getArg(1)); 9597 Value *FnALD32 = 9598 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType()); 9599 return Builder.CreateCall(FnALD32, {Ptr, Val}); 9600 } 9601 9602 case NVPTX::BI__nvvm_ldg_c: 9603 case NVPTX::BI__nvvm_ldg_c2: 9604 case NVPTX::BI__nvvm_ldg_c4: 9605 case NVPTX::BI__nvvm_ldg_s: 9606 case NVPTX::BI__nvvm_ldg_s2: 9607 case NVPTX::BI__nvvm_ldg_s4: 9608 case NVPTX::BI__nvvm_ldg_i: 9609 case NVPTX::BI__nvvm_ldg_i2: 9610 case NVPTX::BI__nvvm_ldg_i4: 9611 case NVPTX::BI__nvvm_ldg_l: 9612 case NVPTX::BI__nvvm_ldg_ll: 9613 case NVPTX::BI__nvvm_ldg_ll2: 9614 case NVPTX::BI__nvvm_ldg_uc: 9615 case NVPTX::BI__nvvm_ldg_uc2: 9616 case NVPTX::BI__nvvm_ldg_uc4: 9617 case NVPTX::BI__nvvm_ldg_us: 9618 case NVPTX::BI__nvvm_ldg_us2: 9619 case NVPTX::BI__nvvm_ldg_us4: 9620 case NVPTX::BI__nvvm_ldg_ui: 9621 case NVPTX::BI__nvvm_ldg_ui2: 9622 case NVPTX::BI__nvvm_ldg_ui4: 9623 case NVPTX::BI__nvvm_ldg_ul: 9624 case NVPTX::BI__nvvm_ldg_ull: 9625 case NVPTX::BI__nvvm_ldg_ull2: 9626 // PTX Interoperability section 2.2: "For a vector with an even number of 9627 // elements, its alignment is set to number of elements times the alignment 9628 // of its member: n*alignof(t)." 9629 return MakeLdg(Intrinsic::nvvm_ldg_global_i); 9630 case NVPTX::BI__nvvm_ldg_f: 9631 case NVPTX::BI__nvvm_ldg_f2: 9632 case NVPTX::BI__nvvm_ldg_f4: 9633 case NVPTX::BI__nvvm_ldg_d: 9634 case NVPTX::BI__nvvm_ldg_d2: 9635 return MakeLdg(Intrinsic::nvvm_ldg_global_f); 9636 9637 case NVPTX::BI__nvvm_atom_cta_add_gen_i: 9638 case NVPTX::BI__nvvm_atom_cta_add_gen_l: 9639 case NVPTX::BI__nvvm_atom_cta_add_gen_ll: 9640 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta); 9641 case NVPTX::BI__nvvm_atom_sys_add_gen_i: 9642 case NVPTX::BI__nvvm_atom_sys_add_gen_l: 9643 case NVPTX::BI__nvvm_atom_sys_add_gen_ll: 9644 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys); 9645 case NVPTX::BI__nvvm_atom_cta_add_gen_f: 9646 case NVPTX::BI__nvvm_atom_cta_add_gen_d: 9647 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta); 9648 case NVPTX::BI__nvvm_atom_sys_add_gen_f: 9649 case NVPTX::BI__nvvm_atom_sys_add_gen_d: 9650 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys); 9651 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i: 9652 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l: 9653 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll: 9654 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta); 9655 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i: 9656 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l: 9657 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll: 9658 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys); 9659 case NVPTX::BI__nvvm_atom_cta_max_gen_i: 9660 case NVPTX::BI__nvvm_atom_cta_max_gen_ui: 9661 case NVPTX::BI__nvvm_atom_cta_max_gen_l: 9662 case NVPTX::BI__nvvm_atom_cta_max_gen_ul: 9663 case NVPTX::BI__nvvm_atom_cta_max_gen_ll: 9664 case NVPTX::BI__nvvm_atom_cta_max_gen_ull: 9665 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta); 9666 case NVPTX::BI__nvvm_atom_sys_max_gen_i: 9667 case NVPTX::BI__nvvm_atom_sys_max_gen_ui: 9668 case NVPTX::BI__nvvm_atom_sys_max_gen_l: 9669 case NVPTX::BI__nvvm_atom_sys_max_gen_ul: 9670 case NVPTX::BI__nvvm_atom_sys_max_gen_ll: 9671 case NVPTX::BI__nvvm_atom_sys_max_gen_ull: 9672 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys); 9673 case NVPTX::BI__nvvm_atom_cta_min_gen_i: 9674 case NVPTX::BI__nvvm_atom_cta_min_gen_ui: 9675 case NVPTX::BI__nvvm_atom_cta_min_gen_l: 9676 case NVPTX::BI__nvvm_atom_cta_min_gen_ul: 9677 case NVPTX::BI__nvvm_atom_cta_min_gen_ll: 9678 case NVPTX::BI__nvvm_atom_cta_min_gen_ull: 9679 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta); 9680 case NVPTX::BI__nvvm_atom_sys_min_gen_i: 9681 case NVPTX::BI__nvvm_atom_sys_min_gen_ui: 9682 case NVPTX::BI__nvvm_atom_sys_min_gen_l: 9683 case NVPTX::BI__nvvm_atom_sys_min_gen_ul: 9684 case NVPTX::BI__nvvm_atom_sys_min_gen_ll: 9685 case NVPTX::BI__nvvm_atom_sys_min_gen_ull: 9686 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys); 9687 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui: 9688 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta); 9689 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui: 9690 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta); 9691 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui: 9692 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys); 9693 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui: 9694 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys); 9695 case NVPTX::BI__nvvm_atom_cta_and_gen_i: 9696 case NVPTX::BI__nvvm_atom_cta_and_gen_l: 9697 case NVPTX::BI__nvvm_atom_cta_and_gen_ll: 9698 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta); 9699 case NVPTX::BI__nvvm_atom_sys_and_gen_i: 9700 case NVPTX::BI__nvvm_atom_sys_and_gen_l: 9701 case NVPTX::BI__nvvm_atom_sys_and_gen_ll: 9702 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys); 9703 case NVPTX::BI__nvvm_atom_cta_or_gen_i: 9704 case NVPTX::BI__nvvm_atom_cta_or_gen_l: 9705 case NVPTX::BI__nvvm_atom_cta_or_gen_ll: 9706 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta); 9707 case NVPTX::BI__nvvm_atom_sys_or_gen_i: 9708 case NVPTX::BI__nvvm_atom_sys_or_gen_l: 9709 case NVPTX::BI__nvvm_atom_sys_or_gen_ll: 9710 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys); 9711 case NVPTX::BI__nvvm_atom_cta_xor_gen_i: 9712 case NVPTX::BI__nvvm_atom_cta_xor_gen_l: 9713 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll: 9714 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta); 9715 case NVPTX::BI__nvvm_atom_sys_xor_gen_i: 9716 case NVPTX::BI__nvvm_atom_sys_xor_gen_l: 9717 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll: 9718 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys); 9719 case NVPTX::BI__nvvm_atom_cta_cas_gen_i: 9720 case NVPTX::BI__nvvm_atom_cta_cas_gen_l: 9721 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: { 9722 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9723 return Builder.CreateCall( 9724 CGM.getIntrinsic( 9725 Intrinsic::nvvm_atomic_cas_gen_i_cta, 9726 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9727 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9728 } 9729 case NVPTX::BI__nvvm_atom_sys_cas_gen_i: 9730 case NVPTX::BI__nvvm_atom_sys_cas_gen_l: 9731 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: { 9732 Value *Ptr = EmitScalarExpr(E->getArg(0)); 9733 return Builder.CreateCall( 9734 CGM.getIntrinsic( 9735 Intrinsic::nvvm_atomic_cas_gen_i_sys, 9736 {Ptr->getType()->getPointerElementType(), Ptr->getType()}), 9737 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))}); 9738 } 9739 case NVPTX::BI__nvvm_match_all_sync_i32p: 9740 case NVPTX::BI__nvvm_match_all_sync_i64p: { 9741 Value *Mask = EmitScalarExpr(E->getArg(0)); 9742 Value *Val = EmitScalarExpr(E->getArg(1)); 9743 Address PredOutPtr = EmitPointerWithAlignment(E->getArg(2)); 9744 Value *ResultPair = Builder.CreateCall( 9745 CGM.getIntrinsic(BuiltinID == NVPTX::BI__nvvm_match_all_sync_i32p 9746 ? Intrinsic::nvvm_match_all_sync_i32p 9747 : Intrinsic::nvvm_match_all_sync_i64p), 9748 {Mask, Val}); 9749 Value *Pred = Builder.CreateZExt(Builder.CreateExtractValue(ResultPair, 1), 9750 PredOutPtr.getElementType()); 9751 Builder.CreateStore(Pred, PredOutPtr); 9752 return Builder.CreateExtractValue(ResultPair, 0); 9753 } 9754 case NVPTX::BI__hmma_m16n16k16_ld_a: 9755 case NVPTX::BI__hmma_m16n16k16_ld_b: 9756 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9757 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: { 9758 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9759 Value *Src = EmitScalarExpr(E->getArg(1)); 9760 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9761 llvm::APSInt isColMajorArg; 9762 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9763 return nullptr; 9764 bool isColMajor = isColMajorArg.getSExtValue(); 9765 unsigned IID; 9766 unsigned NumResults; 9767 switch (BuiltinID) { 9768 case NVPTX::BI__hmma_m16n16k16_ld_a: 9769 IID = isColMajor ? Intrinsic::nvvm_wmma_load_a_f16_col_stride 9770 : Intrinsic::nvvm_wmma_load_a_f16_row_stride; 9771 NumResults = 8; 9772 break; 9773 case NVPTX::BI__hmma_m16n16k16_ld_b: 9774 IID = isColMajor ? Intrinsic::nvvm_wmma_load_b_f16_col_stride 9775 : Intrinsic::nvvm_wmma_load_b_f16_row_stride; 9776 NumResults = 8; 9777 break; 9778 case NVPTX::BI__hmma_m16n16k16_ld_c_f16: 9779 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f16_col_stride 9780 : Intrinsic::nvvm_wmma_load_c_f16_row_stride; 9781 NumResults = 4; 9782 break; 9783 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: 9784 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f32_col_stride 9785 : Intrinsic::nvvm_wmma_load_c_f32_row_stride; 9786 NumResults = 8; 9787 break; 9788 default: 9789 llvm_unreachable("Unexpected builtin ID."); 9790 } 9791 Value *Result = 9792 Builder.CreateCall(CGM.getIntrinsic(IID), 9793 {Builder.CreatePointerCast(Src, VoidPtrTy), Ldm}); 9794 9795 // Save returned values. 9796 for (unsigned i = 0; i < NumResults; ++i) { 9797 Builder.CreateAlignedStore( 9798 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), 9799 Dst.getElementType()), 9800 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9801 CharUnits::fromQuantity(4)); 9802 } 9803 return Result; 9804 } 9805 9806 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9807 case NVPTX::BI__hmma_m16n16k16_st_c_f32: { 9808 Value *Dst = EmitScalarExpr(E->getArg(0)); 9809 Address Src = EmitPointerWithAlignment(E->getArg(1)); 9810 Value *Ldm = EmitScalarExpr(E->getArg(2)); 9811 llvm::APSInt isColMajorArg; 9812 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext())) 9813 return nullptr; 9814 bool isColMajor = isColMajorArg.getSExtValue(); 9815 unsigned IID; 9816 unsigned NumResults = 8; 9817 // PTX Instructions (and LLVM instrinsics) are defined for slice _d_, yet 9818 // for some reason nvcc builtins use _c_. 9819 switch (BuiltinID) { 9820 case NVPTX::BI__hmma_m16n16k16_st_c_f16: 9821 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f16_col_stride 9822 : Intrinsic::nvvm_wmma_store_d_f16_row_stride; 9823 NumResults = 4; 9824 break; 9825 case NVPTX::BI__hmma_m16n16k16_st_c_f32: 9826 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f32_col_stride 9827 : Intrinsic::nvvm_wmma_store_d_f32_row_stride; 9828 break; 9829 default: 9830 llvm_unreachable("Unexpected builtin ID."); 9831 } 9832 Function *Intrinsic = CGM.getIntrinsic(IID); 9833 llvm::Type *ParamType = Intrinsic->getFunctionType()->getParamType(1); 9834 SmallVector<Value *, 10> Values; 9835 Values.push_back(Builder.CreatePointerCast(Dst, VoidPtrTy)); 9836 for (unsigned i = 0; i < NumResults; ++i) { 9837 Value *V = Builder.CreateAlignedLoad( 9838 Builder.CreateGEP(Src.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9839 CharUnits::fromQuantity(4)); 9840 Values.push_back(Builder.CreateBitCast(V, ParamType)); 9841 } 9842 Values.push_back(Ldm); 9843 Value *Result = Builder.CreateCall(Intrinsic, Values); 9844 return Result; 9845 } 9846 9847 // BI__hmma_m16n16k16_mma_<Dtype><CType>(d, a, b, c, layout, satf) 9848 // --> Intrinsic::nvvm_wmma_mma_sync<layout A,B><DType><CType><Satf> 9849 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9850 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9851 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9852 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: { 9853 Address Dst = EmitPointerWithAlignment(E->getArg(0)); 9854 Address SrcA = EmitPointerWithAlignment(E->getArg(1)); 9855 Address SrcB = EmitPointerWithAlignment(E->getArg(2)); 9856 Address SrcC = EmitPointerWithAlignment(E->getArg(3)); 9857 llvm::APSInt LayoutArg; 9858 if (!E->getArg(4)->isIntegerConstantExpr(LayoutArg, getContext())) 9859 return nullptr; 9860 int Layout = LayoutArg.getSExtValue(); 9861 if (Layout < 0 || Layout > 3) 9862 return nullptr; 9863 llvm::APSInt SatfArg; 9864 if (!E->getArg(5)->isIntegerConstantExpr(SatfArg, getContext())) 9865 return nullptr; 9866 bool Satf = SatfArg.getSExtValue(); 9867 9868 // clang-format off 9869 #define MMA_VARIANTS(type) {{ \ 9870 Intrinsic::nvvm_wmma_mma_sync_row_row_##type, \ 9871 Intrinsic::nvvm_wmma_mma_sync_row_row_##type##_satfinite, \ 9872 Intrinsic::nvvm_wmma_mma_sync_row_col_##type, \ 9873 Intrinsic::nvvm_wmma_mma_sync_row_col_##type##_satfinite, \ 9874 Intrinsic::nvvm_wmma_mma_sync_col_row_##type, \ 9875 Intrinsic::nvvm_wmma_mma_sync_col_row_##type##_satfinite, \ 9876 Intrinsic::nvvm_wmma_mma_sync_col_col_##type, \ 9877 Intrinsic::nvvm_wmma_mma_sync_col_col_##type##_satfinite \ 9878 }} 9879 // clang-format on 9880 9881 auto getMMAIntrinsic = [Layout, Satf](std::array<unsigned, 8> Variants) { 9882 unsigned Index = Layout * 2 + Satf; 9883 assert(Index < 8); 9884 return Variants[Index]; 9885 }; 9886 unsigned IID; 9887 unsigned NumEltsC; 9888 unsigned NumEltsD; 9889 switch (BuiltinID) { 9890 case NVPTX::BI__hmma_m16n16k16_mma_f16f16: 9891 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f16)); 9892 NumEltsC = 4; 9893 NumEltsD = 4; 9894 break; 9895 case NVPTX::BI__hmma_m16n16k16_mma_f32f16: 9896 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f16)); 9897 NumEltsC = 4; 9898 NumEltsD = 8; 9899 break; 9900 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: 9901 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f32)); 9902 NumEltsC = 8; 9903 NumEltsD = 4; 9904 break; 9905 case NVPTX::BI__hmma_m16n16k16_mma_f32f32: 9906 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f32)); 9907 NumEltsC = 8; 9908 NumEltsD = 8; 9909 break; 9910 default: 9911 llvm_unreachable("Unexpected builtin ID."); 9912 } 9913 #undef MMA_VARIANTS 9914 9915 SmallVector<Value *, 24> Values; 9916 Function *Intrinsic = CGM.getIntrinsic(IID); 9917 llvm::Type *ABType = Intrinsic->getFunctionType()->getParamType(0); 9918 // Load A 9919 for (unsigned i = 0; i < 8; ++i) { 9920 Value *V = Builder.CreateAlignedLoad( 9921 Builder.CreateGEP(SrcA.getPointer(), 9922 llvm::ConstantInt::get(IntTy, i)), 9923 CharUnits::fromQuantity(4)); 9924 Values.push_back(Builder.CreateBitCast(V, ABType)); 9925 } 9926 // Load B 9927 for (unsigned i = 0; i < 8; ++i) { 9928 Value *V = Builder.CreateAlignedLoad( 9929 Builder.CreateGEP(SrcB.getPointer(), 9930 llvm::ConstantInt::get(IntTy, i)), 9931 CharUnits::fromQuantity(4)); 9932 Values.push_back(Builder.CreateBitCast(V, ABType)); 9933 } 9934 // Load C 9935 llvm::Type *CType = Intrinsic->getFunctionType()->getParamType(16); 9936 for (unsigned i = 0; i < NumEltsC; ++i) { 9937 Value *V = Builder.CreateAlignedLoad( 9938 Builder.CreateGEP(SrcC.getPointer(), 9939 llvm::ConstantInt::get(IntTy, i)), 9940 CharUnits::fromQuantity(4)); 9941 Values.push_back(Builder.CreateBitCast(V, CType)); 9942 } 9943 Value *Result = Builder.CreateCall(Intrinsic, Values); 9944 llvm::Type *DType = Dst.getElementType(); 9945 for (unsigned i = 0; i < NumEltsD; ++i) 9946 Builder.CreateAlignedStore( 9947 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType), 9948 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)), 9949 CharUnits::fromQuantity(4)); 9950 return Result; 9951 } 9952 default: 9953 return nullptr; 9954 } 9955 } 9956 9957 Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID, 9958 const CallExpr *E) { 9959 switch (BuiltinID) { 9960 case WebAssembly::BI__builtin_wasm_current_memory: { 9961 llvm::Type *ResultType = ConvertType(E->getType()); 9962 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType); 9963 return Builder.CreateCall(Callee); 9964 } 9965 case WebAssembly::BI__builtin_wasm_grow_memory: { 9966 Value *X = EmitScalarExpr(E->getArg(0)); 9967 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType()); 9968 return Builder.CreateCall(Callee, X); 9969 } 9970 case WebAssembly::BI__builtin_wasm_throw: { 9971 Value *Tag = EmitScalarExpr(E->getArg(0)); 9972 Value *Obj = EmitScalarExpr(E->getArg(1)); 9973 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw); 9974 return Builder.CreateCall(Callee, {Tag, Obj}); 9975 } 9976 case WebAssembly::BI__builtin_wasm_rethrow: { 9977 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow); 9978 return Builder.CreateCall(Callee); 9979 } 9980 9981 default: 9982 return nullptr; 9983 } 9984 } 9985