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