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