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