blob: 5c8b36cdfa413b4eb634ba7183c1ceba8977c7b0 [file] [log] [blame]
Anders Carlsson1d8e5212007-08-20 18:05:56 +00001//===---- CGBuiltin.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Anders Carlsson1d8e5212007-08-20 18:05:56 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This contains code to emit Builtin calls as LLVM code.
11//
12//===----------------------------------------------------------------------===//
13
David Majnemerba3e5ec2015-03-13 18:26:17 +000014#include "CGCXXABI.h"
Fariborz Jahanian021510e2010-06-15 22:44:06 +000015#include "CGObjCRuntime.h"
Alexey Bader465c1892016-09-23 14:20:00 +000016#include "CGOpenCLRuntime.h"
Mehdi Amini06d367c2016-10-24 20:39:34 +000017#include "CodeGenFunction.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000018#include "CodeGenModule.h"
John McCallde0fe072017-08-15 21:42:52 +000019#include "ConstantEmitter.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "TargetInfo.h"
Chris Lattner1eec6602007-08-31 04:31:45 +000021#include "clang/AST/ASTContext.h"
Daniel Dunbar6e8aa532008-08-11 05:35:13 +000022#include "clang/AST/Decl.h"
Mehdi Amini06d367c2016-10-24 20:39:34 +000023#include "clang/Analysis/Analyses/OSLog.h"
Chris Lattner5abdec72009-06-14 01:05:48 +000024#include "clang/Basic/TargetBuiltins.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000025#include "clang/Basic/TargetInfo.h"
Mark Laceya8e7df32013-10-30 21:53:58 +000026#include "clang/CodeGen/CGFunctionInfo.h"
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +000027#include "llvm/ADT/StringExtras.h"
David Majnemer310e3a82015-01-29 09:29:21 +000028#include "llvm/IR/CallSite.h"
Chandler Carruthffd55512013-01-02 11:45:17 +000029#include "llvm/IR/DataLayout.h"
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +000030#include "llvm/IR/InlineAsm.h"
Chandler Carruthffd55512013-01-02 11:45:17 +000031#include "llvm/IR/Intrinsics.h"
Jan Veselyd7e03a52016-07-10 22:38:04 +000032#include "llvm/IR/MDBuilder.h"
Reid Kleckner30701ed2017-09-05 20:27:35 +000033#include "llvm/Support/ConvertUTF.h"
Kit Barton8246f282015-03-25 19:41:41 +000034#include <sstream>
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +000035
Anders Carlsson1d8e5212007-08-20 18:05:56 +000036using namespace clang;
37using namespace CodeGen;
Anders Carlssona020c432007-12-09 21:20:04 +000038using namespace llvm;
39
Sean Fertile96d9e0e2017-01-05 21:43:30 +000040static
41int64_t clamp(int64_t Value, int64_t Low, int64_t High) {
42 return std::min(High, std::max(Low, Value));
43}
44
John McCall30e4efd2011-09-13 23:05:03 +000045/// getBuiltinLibFunction - Given a builtin id for a function like
46/// "__builtin_fabsf", return a Function* for "fabsf".
John McCallb92ab1a2016-10-26 23:46:34 +000047llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
48 unsigned BuiltinID) {
John McCall30e4efd2011-09-13 23:05:03 +000049 assert(Context.BuiltinInfo.isLibFunction(BuiltinID));
50
51 // Get the name, skip over the __builtin_ prefix (if necessary).
52 StringRef Name;
53 GlobalDecl D(FD);
54
55 // If the builtin has been declared explicitly with an assembler label,
56 // use the mangled name. This differs from the plain label on platforms
57 // that prefix labels.
58 if (FD->hasAttr<AsmLabelAttr>())
59 Name = getMangledName(D);
60 else
Mehdi Amini7186a432016-10-11 19:04:24 +000061 Name = Context.BuiltinInfo.getName(BuiltinID) + 10;
John McCall30e4efd2011-09-13 23:05:03 +000062
63 llvm::FunctionType *Ty =
64 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType()));
65
66 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false);
67}
68
John McCall3a7f6922010-10-27 20:58:56 +000069/// Emit the conversions required to turn the given value into an
70/// integer of the given size.
71static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V,
Chris Lattner2192fe52011-07-18 04:24:23 +000072 QualType T, llvm::IntegerType *IntType) {
John McCall3a7f6922010-10-27 20:58:56 +000073 V = CGF.EmitToMemory(V, T);
Chris Lattner07e96862010-10-01 23:43:16 +000074
John McCall3a7f6922010-10-27 20:58:56 +000075 if (V->getType()->isPointerTy())
76 return CGF.Builder.CreatePtrToInt(V, IntType);
77
78 assert(V->getType() == IntType);
79 return V;
Chandler Carruthbc8cab12010-07-18 07:23:17 +000080}
81
John McCall3a7f6922010-10-27 20:58:56 +000082static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V,
Chris Lattner2192fe52011-07-18 04:24:23 +000083 QualType T, llvm::Type *ResultType) {
John McCall3a7f6922010-10-27 20:58:56 +000084 V = CGF.EmitFromMemory(V, T);
85
86 if (ResultType->isPointerTy())
87 return CGF.Builder.CreateIntToPtr(V, ResultType);
88
89 assert(V->getType() == ResultType);
90 return V;
Chandler Carruthbc8cab12010-07-18 07:23:17 +000091}
92
Daniel Dunbar4fab57d2009-04-07 00:55:51 +000093/// Utility to insert an atomic instruction based on Instrinsic::ID
94/// and the expression node.
Artem Belevichd21e5c62015-06-25 18:29:42 +000095static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF,
96 llvm::AtomicRMWInst::BinOp Kind,
97 const CallExpr *E) {
John McCall3a7f6922010-10-27 20:58:56 +000098 QualType T = E->getType();
99 assert(E->getArg(0)->getType()->isPointerType());
100 assert(CGF.getContext().hasSameUnqualifiedType(T,
101 E->getArg(0)->getType()->getPointeeType()));
102 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
103
Chris Lattnerb2f659b2010-09-21 23:40:48 +0000104 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +0000105 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
John McCall6bde9542010-10-26 22:09:15 +0000106
Chris Lattnera5f58b02011-07-09 17:41:47 +0000107 llvm::IntegerType *IntType =
John McCall3a7f6922010-10-27 20:58:56 +0000108 llvm::IntegerType::get(CGF.getLLVMContext(),
109 CGF.getContext().getTypeSize(T));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000110 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
John McCall3a7f6922010-10-27 20:58:56 +0000111
John McCall3a7f6922010-10-27 20:58:56 +0000112 llvm::Value *Args[2];
113 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
114 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
Chris Lattner2192fe52011-07-18 04:24:23 +0000115 llvm::Type *ValueType = Args[1]->getType();
John McCall3a7f6922010-10-27 20:58:56 +0000116 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
117
JF Bastien92f4ef12016-04-06 17:26:42 +0000118 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
119 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
Artem Belevichd21e5c62015-06-25 18:29:42 +0000120 return EmitFromInt(CGF, Result, T, ValueType);
121}
122
Michael Zolotukhin84df1232015-09-08 23:52:33 +0000123static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) {
124 Value *Val = CGF.EmitScalarExpr(E->getArg(0));
125 Value *Address = CGF.EmitScalarExpr(E->getArg(1));
126
127 // Convert the type of the pointer to a pointer to the stored type.
128 Val = CGF.EmitToMemory(Val, E->getArg(0)->getType());
129 Value *BC = CGF.Builder.CreateBitCast(
130 Address, llvm::PointerType::getUnqual(Val->getType()), "cast");
131 LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType());
132 LV.setNontemporal(true);
133 CGF.EmitStoreOfScalar(Val, LV, false);
134 return nullptr;
135}
136
137static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) {
138 Value *Address = CGF.EmitScalarExpr(E->getArg(0));
139
140 LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType());
141 LV.setNontemporal(true);
142 return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
143}
144
Artem Belevichd21e5c62015-06-25 18:29:42 +0000145static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
146 llvm::AtomicRMWInst::BinOp Kind,
147 const CallExpr *E) {
148 return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +0000149}
150
151/// Utility to insert an atomic instruction based Instrinsic::ID and
John McCall3a7f6922010-10-27 20:58:56 +0000152/// the expression node, where the return value is the result of the
153/// operation.
Chris Lattner43660c52010-05-06 05:35:16 +0000154static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
Eli Friedmane9f81132011-09-07 01:41:24 +0000155 llvm::AtomicRMWInst::BinOp Kind,
156 const CallExpr *E,
Hal Finkeld2208b52014-10-02 20:53:50 +0000157 Instruction::BinaryOps Op,
158 bool Invert = false) {
John McCall3a7f6922010-10-27 20:58:56 +0000159 QualType T = E->getType();
160 assert(E->getArg(0)->getType()->isPointerType());
161 assert(CGF.getContext().hasSameUnqualifiedType(T,
162 E->getArg(0)->getType()->getPointeeType()));
163 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
164
Chris Lattnerb2f659b2010-09-21 23:40:48 +0000165 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +0000166 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
John McCall6bde9542010-10-26 22:09:15 +0000167
Chris Lattnera5f58b02011-07-09 17:41:47 +0000168 llvm::IntegerType *IntType =
John McCall3a7f6922010-10-27 20:58:56 +0000169 llvm::IntegerType::get(CGF.getLLVMContext(),
170 CGF.getContext().getTypeSize(T));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000171 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
John McCall3a7f6922010-10-27 20:58:56 +0000172
John McCall3a7f6922010-10-27 20:58:56 +0000173 llvm::Value *Args[2];
174 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
Chris Lattner2192fe52011-07-18 04:24:23 +0000175 llvm::Type *ValueType = Args[1]->getType();
John McCall3a7f6922010-10-27 20:58:56 +0000176 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
177 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
178
JF Bastien92f4ef12016-04-06 17:26:42 +0000179 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
180 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
John McCall3a7f6922010-10-27 20:58:56 +0000181 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]);
Hal Finkeld2208b52014-10-02 20:53:50 +0000182 if (Invert)
183 Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
184 llvm::ConstantInt::get(IntType, -1));
John McCall3a7f6922010-10-27 20:58:56 +0000185 Result = EmitFromInt(CGF, Result, T, ValueType);
186 return RValue::get(Result);
Mon P Wangb84407d2008-05-09 22:40:52 +0000187}
188
Artem Belevichd21e5c62015-06-25 18:29:42 +0000189/// @brief Utility to insert an atomic cmpxchg instruction.
190///
191/// @param CGF The current codegen function.
192/// @param E Builtin call expression to convert to cmpxchg.
193/// arg0 - address to operate on
194/// arg1 - value to compare with
195/// arg2 - new value
196/// @param ReturnBool Specifies whether to return success flag of
197/// cmpxchg result or the old value.
198///
199/// @returns result of cmpxchg, according to ReturnBool
200static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E,
201 bool ReturnBool) {
202 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType();
203 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
204 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
205
206 llvm::IntegerType *IntType = llvm::IntegerType::get(
207 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T));
208 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
209
210 Value *Args[3];
211 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
212 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
213 llvm::Type *ValueType = Args[1]->getType();
214 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
215 Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType);
216
JF Bastien92f4ef12016-04-06 17:26:42 +0000217 Value *Pair = CGF.Builder.CreateAtomicCmpXchg(
218 Args[0], Args[1], Args[2], llvm::AtomicOrdering::SequentiallyConsistent,
219 llvm::AtomicOrdering::SequentiallyConsistent);
Artem Belevichd21e5c62015-06-25 18:29:42 +0000220 if (ReturnBool)
221 // Extract boolean success flag and zext it to int.
222 return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1),
223 CGF.ConvertType(E->getType()));
224 else
225 // Extract old value and emit it using the same type as compare value.
226 return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T,
227 ValueType);
228}
229
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000230// Emit a simple mangled intrinsic that has 1 argument and a return type
231// matching the argument type.
232static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
233 const CallExpr *E,
234 unsigned IntrinsicID) {
235 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
236
237 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
238 return CGF.Builder.CreateCall(F, Src0);
239}
240
241// Emit an intrinsic that has 2 operands of the same type as its result.
242static Value *emitBinaryBuiltin(CodeGenFunction &CGF,
243 const CallExpr *E,
244 unsigned IntrinsicID) {
245 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
246 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
247
248 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
249 return CGF.Builder.CreateCall(F, { Src0, Src1 });
250}
251
252// Emit an intrinsic that has 3 operands of the same type as its result.
253static Value *emitTernaryBuiltin(CodeGenFunction &CGF,
254 const CallExpr *E,
255 unsigned IntrinsicID) {
256 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
257 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
258 llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2));
259
260 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
261 return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 });
262}
263
264// Emit an intrinsic that has 1 float or double operand, and 1 integer.
265static Value *emitFPIntBuiltin(CodeGenFunction &CGF,
266 const CallExpr *E,
267 unsigned IntrinsicID) {
268 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
269 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
270
271 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
272 return CGF.Builder.CreateCall(F, {Src0, Src1});
273}
274
Tom Stellardc4e0c102014-09-03 15:24:29 +0000275/// EmitFAbs - Emit a call to @llvm.fabs().
Reid Kleckner4cad00a2014-11-03 23:51:40 +0000276static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
Tom Stellardc4e0c102014-09-03 15:24:29 +0000277 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
278 llvm::CallInst *Call = CGF.Builder.CreateCall(F, V);
279 Call->setDoesNotAccessMemory();
280 return Call;
Chris Lattner43660c52010-05-06 05:35:16 +0000281}
282
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000283/// Emit the computation of the sign bit for a floating point value. Returns
284/// the i1 sign bit value.
285static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {
286 LLVMContext &C = CGF.CGM.getLLVMContext();
287
288 llvm::Type *Ty = V->getType();
289 int Width = Ty->getPrimitiveSizeInBits();
290 llvm::Type *IntTy = llvm::IntegerType::get(C, Width);
291 V = CGF.Builder.CreateBitCast(V, IntTy);
292 if (Ty->isPPC_FP128Ty()) {
Petar Jovanovic73d10442015-11-06 14:52:46 +0000293 // We want the sign bit of the higher-order double. The bitcast we just
294 // did works as if the double-double was stored to memory and then
295 // read as an i128. The "store" will put the higher-order double in the
296 // lower address in both little- and big-Endian modes, but the "load"
297 // will treat those bits as a different part of the i128: the low bits in
298 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian
299 // we need to shift the high bits down to the low before truncating.
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000300 Width >>= 1;
Simon Pilgrim532de1c2016-06-13 10:05:19 +0000301 if (CGF.getTarget().isBigEndian()) {
302 Value *ShiftCst = llvm::ConstantInt::get(IntTy, Width);
303 V = CGF.Builder.CreateLShr(V, ShiftCst);
304 }
305 // We are truncating value in order to extract the higher-order
306 // double, which we will be using to extract the sign from.
307 IntTy = llvm::IntegerType::get(C, Width);
308 V = CGF.Builder.CreateTrunc(V, IntTy);
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000309 }
310 Value *Zero = llvm::Constant::getNullValue(IntTy);
311 return CGF.Builder.CreateICmpSLT(V, Zero);
312}
313
John McCallb92ab1a2016-10-26 23:46:34 +0000314static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
315 const CallExpr *E, llvm::Constant *calleeValue) {
316 CGCallee callee = CGCallee::forDirect(calleeValue, FD);
317 return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
John McCall30e4efd2011-09-13 23:05:03 +0000318}
319
Michael Gottesman54398012013-01-13 02:22:39 +0000320/// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.*
321/// depending on IntrinsicID.
322///
323/// \arg CGF The current codegen function.
324/// \arg IntrinsicID The ID for the Intrinsic we wish to generate.
325/// \arg X The first argument to the llvm.*.with.overflow.*.
326/// \arg Y The second argument to the llvm.*.with.overflow.*.
327/// \arg Carry The carry returned by the llvm.*.with.overflow.*.
328/// \returns The result (i.e. sum/product) returned by the intrinsic.
329static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF,
330 const llvm::Intrinsic::ID IntrinsicID,
331 llvm::Value *X, llvm::Value *Y,
332 llvm::Value *&Carry) {
333 // Make sure we have integers of the same width.
334 assert(X->getType() == Y->getType() &&
335 "Arguments must be the same type. (Did you forget to make sure both "
336 "arguments have the same integer width?)");
337
NAKAMURA Takumi7ab4fbf2013-01-13 11:26:44 +0000338 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +0000339 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y});
Michael Gottesman54398012013-01-13 02:22:39 +0000340 Carry = CGF.Builder.CreateExtractValue(Tmp, 1);
341 return CGF.Builder.CreateExtractValue(Tmp, 0);
342}
343
Jan Veselyd7e03a52016-07-10 22:38:04 +0000344static Value *emitRangedBuiltin(CodeGenFunction &CGF,
345 unsigned IntrinsicID,
346 int low, int high) {
347 llvm::MDBuilder MDHelper(CGF.getLLVMContext());
348 llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high));
349 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {});
350 llvm::Instruction *Call = CGF.Builder.CreateCall(F);
351 Call->setMetadata(llvm::LLVMContext::MD_range, RNode);
352 return Call;
353}
354
John McCall03107a42015-10-29 20:48:01 +0000355namespace {
356 struct WidthAndSignedness {
357 unsigned Width;
358 bool Signed;
359 };
360}
361
362static WidthAndSignedness
363getIntegerWidthAndSignedness(const clang::ASTContext &context,
364 const clang::QualType Type) {
365 assert(Type->isIntegerType() && "Given type is not an integer.");
366 unsigned Width = Type->isBooleanType() ? 1 : context.getTypeInfo(Type).Width;
367 bool Signed = Type->isSignedIntegerType();
368 return {Width, Signed};
369}
370
371// Given one or more integer types, this function produces an integer type that
372// encompasses them: any value in one of the given types could be expressed in
373// the encompassing type.
374static struct WidthAndSignedness
375EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) {
376 assert(Types.size() > 0 && "Empty list of types.");
377
378 // If any of the given types is signed, we must return a signed type.
379 bool Signed = false;
380 for (const auto &Type : Types) {
381 Signed |= Type.Signed;
382 }
383
384 // The encompassing type must have a width greater than or equal to the width
385 // of the specified types. Aditionally, if the encompassing type is signed,
386 // its width must be strictly greater than the width of any unsigned types
387 // given.
388 unsigned Width = 0;
389 for (const auto &Type : Types) {
390 unsigned MinWidth = Type.Width + (Signed && !Type.Signed);
391 if (Width < MinWidth) {
392 Width = MinWidth;
393 }
394 }
395
396 return {Width, Signed};
397}
398
Charles Davisc7d5c942015-09-17 20:55:33 +0000399Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) {
400 llvm::Type *DestType = Int8PtrTy;
401 if (ArgValue->getType() != DestType)
402 ArgValue =
403 Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data());
404
405 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend;
406 return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue);
407}
408
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000409/// Checks if using the result of __builtin_object_size(p, @p From) in place of
410/// __builtin_object_size(p, @p To) is correct
411static bool areBOSTypesCompatible(int From, int To) {
412 // Note: Our __builtin_object_size implementation currently treats Type=0 and
413 // Type=2 identically. Encoding this implementation detail here may make
414 // improving __builtin_object_size difficult in the future, so it's omitted.
415 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2);
416}
417
418static llvm::Value *
419getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) {
420 return ConstantInt::get(ResType, (Type & 2) ? 0 : -1, /*isSigned=*/true);
421}
422
423llvm::Value *
424CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
George Burgess IV0d6592a2017-02-23 05:59:56 +0000425 llvm::IntegerType *ResType,
426 llvm::Value *EmittedE) {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000427 uint64_t ObjectSize;
428 if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type))
George Burgess IV0d6592a2017-02-23 05:59:56 +0000429 return emitBuiltinObjectSize(E, Type, ResType, EmittedE);
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000430 return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
431}
432
433/// Returns a Value corresponding to the size of the given expression.
434/// This Value may be either of the following:
435/// - A llvm::Argument (if E is a param with the pass_object_size attribute on
436/// it)
437/// - A call to the @llvm.objectsize intrinsic
George Burgess IV0d6592a2017-02-23 05:59:56 +0000438///
439/// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null
440/// and we wouldn't otherwise try to reference a pass_object_size parameter,
441/// we'll call @llvm.objectsize on EmittedE, rather than emitting E.
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000442llvm::Value *
443CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
George Burgess IV0d6592a2017-02-23 05:59:56 +0000444 llvm::IntegerType *ResType,
445 llvm::Value *EmittedE) {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000446 // We need to reference an argument if the pointer is a parameter with the
447 // pass_object_size attribute.
448 if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
449 auto *Param = dyn_cast<ParmVarDecl>(D->getDecl());
450 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>();
451 if (Param != nullptr && PS != nullptr &&
452 areBOSTypesCompatible(PS->getType(), Type)) {
453 auto Iter = SizeArguments.find(Param);
454 assert(Iter != SizeArguments.end());
455
456 const ImplicitParamDecl *D = Iter->second;
457 auto DIter = LocalDeclMap.find(D);
458 assert(DIter != LocalDeclMap.end());
459
460 return EmitLoadOfScalar(DIter->second, /*volatile=*/false,
461 getContext().getSizeType(), E->getLocStart());
462 }
463 }
464
465 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't
466 // evaluate E for side-effects. In either case, we shouldn't lower to
467 // @llvm.objectsize.
George Burgess IV0d6592a2017-02-23 05:59:56 +0000468 if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext())))
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000469 return getDefaultBuiltinObjectSizeResult(Type, ResType);
470
George Burgess IV0d6592a2017-02-23 05:59:56 +0000471 Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E);
George Burgess IV8856aa92017-02-22 02:35:51 +0000472 assert(Ptr->getType()->isPointerTy() &&
473 "Non-pointer passed to __builtin_object_size?");
474
George Burgess IV8856aa92017-02-22 02:35:51 +0000475 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()});
George Burgess IVa63f9152017-03-21 20:09:35 +0000476
477 // LLVM only supports 0 and 2, make sure that we pass along that as a boolean.
478 Value *Min = Builder.getInt1((Type & 2) != 0);
479 // For GCC compatability, __builtin_object_size treat NULL as unknown size.
480 Value *NullIsUnknown = Builder.getTrue();
481 return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown});
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000482}
483
Albert Gutowski5e08df02016-10-13 22:35:07 +0000484// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we
485// handle them here.
486enum class CodeGenFunction::MSVCIntrin {
487 _BitScanForward,
488 _BitScanReverse,
489 _InterlockedAnd,
490 _InterlockedDecrement,
491 _InterlockedExchange,
492 _InterlockedExchangeAdd,
493 _InterlockedExchangeSub,
494 _InterlockedIncrement,
495 _InterlockedOr,
496 _InterlockedXor,
Hans Wennborg5c3c51f2017-04-07 16:41:47 +0000497 _interlockedbittestandset,
Reid Kleckner04f9f912017-02-09 18:31:06 +0000498 __fastfail,
Albert Gutowski5e08df02016-10-13 22:35:07 +0000499};
500
501Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
Reid Kleckner04f9f912017-02-09 18:31:06 +0000502 const CallExpr *E) {
Albert Gutowski5e08df02016-10-13 22:35:07 +0000503 switch (BuiltinID) {
504 case MSVCIntrin::_BitScanForward:
505 case MSVCIntrin::_BitScanReverse: {
506 Value *ArgValue = EmitScalarExpr(E->getArg(1));
507
508 llvm::Type *ArgType = ArgValue->getType();
509 llvm::Type *IndexType =
510 EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType();
511 llvm::Type *ResultType = ConvertType(E->getType());
512
513 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
514 Value *ResZero = llvm::Constant::getNullValue(ResultType);
515 Value *ResOne = llvm::ConstantInt::get(ResultType, 1);
516
517 BasicBlock *Begin = Builder.GetInsertBlock();
518 BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn);
519 Builder.SetInsertPoint(End);
520 PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result");
521
522 Builder.SetInsertPoint(Begin);
523 Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero);
524 BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn);
525 Builder.CreateCondBr(IsZero, End, NotZero);
526 Result->addIncoming(ResZero, Begin);
527
528 Builder.SetInsertPoint(NotZero);
529 Address IndexAddress = EmitPointerWithAlignment(E->getArg(0));
530
531 if (BuiltinID == MSVCIntrin::_BitScanForward) {
532 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
533 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
534 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
535 Builder.CreateStore(ZeroCount, IndexAddress, false);
536 } else {
537 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
538 Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1);
539
540 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
541 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
542 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
543 Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount);
544 Builder.CreateStore(Index, IndexAddress, false);
545 }
546 Builder.CreateBr(End);
547 Result->addIncoming(ResOne, NotZero);
548
549 Builder.SetInsertPoint(End);
550 return Result;
551 }
552 case MSVCIntrin::_InterlockedAnd:
553 return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E);
554 case MSVCIntrin::_InterlockedExchange:
555 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E);
556 case MSVCIntrin::_InterlockedExchangeAdd:
557 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E);
558 case MSVCIntrin::_InterlockedExchangeSub:
559 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Sub, E);
560 case MSVCIntrin::_InterlockedOr:
561 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E);
562 case MSVCIntrin::_InterlockedXor:
563 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E);
564
Hans Wennborg5c3c51f2017-04-07 16:41:47 +0000565 case MSVCIntrin::_interlockedbittestandset: {
566 llvm::Value *Addr = EmitScalarExpr(E->getArg(0));
567 llvm::Value *Bit = EmitScalarExpr(E->getArg(1));
568 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
569 AtomicRMWInst::Or, Addr,
570 Builder.CreateShl(ConstantInt::get(Bit->getType(), 1), Bit),
571 llvm::AtomicOrdering::SequentiallyConsistent);
572 // Shift the relevant bit to the least significant position, truncate to
573 // the result type, and test the low bit.
574 llvm::Value *Shifted = Builder.CreateLShr(RMWI, Bit);
575 llvm::Value *Truncated =
576 Builder.CreateTrunc(Shifted, ConvertType(E->getType()));
577 return Builder.CreateAnd(Truncated,
578 ConstantInt::get(Truncated->getType(), 1));
579 }
580
Albert Gutowski5e08df02016-10-13 22:35:07 +0000581 case MSVCIntrin::_InterlockedDecrement: {
582 llvm::Type *IntTy = ConvertType(E->getType());
583 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
584 AtomicRMWInst::Sub,
585 EmitScalarExpr(E->getArg(0)),
586 ConstantInt::get(IntTy, 1),
587 llvm::AtomicOrdering::SequentiallyConsistent);
588 return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1));
589 }
590 case MSVCIntrin::_InterlockedIncrement: {
591 llvm::Type *IntTy = ConvertType(E->getType());
592 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
593 AtomicRMWInst::Add,
594 EmitScalarExpr(E->getArg(0)),
595 ConstantInt::get(IntTy, 1),
596 llvm::AtomicOrdering::SequentiallyConsistent);
597 return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1));
598 }
Reid Kleckner04f9f912017-02-09 18:31:06 +0000599
600 case MSVCIntrin::__fastfail: {
601 // Request immediate process termination from the kernel. The instruction
602 // sequences to do this are documented on MSDN:
603 // https://msdn.microsoft.com/en-us/library/dn774154.aspx
604 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch();
605 StringRef Asm, Constraints;
606 switch (ISA) {
607 default:
608 ErrorUnsupported(E, "__fastfail call for this architecture");
609 break;
610 case llvm::Triple::x86:
611 case llvm::Triple::x86_64:
612 Asm = "int $$0x29";
613 Constraints = "{cx}";
614 break;
615 case llvm::Triple::thumb:
616 Asm = "udf #251";
617 Constraints = "{r0}";
618 break;
619 }
620 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false);
621 llvm::InlineAsm *IA =
622 llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true);
Reid Klecknerde864822017-03-21 16:57:30 +0000623 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
624 getLLVMContext(), llvm::AttributeList::FunctionIndex,
625 llvm::Attribute::NoReturn);
Reid Kleckner04f9f912017-02-09 18:31:06 +0000626 CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0)));
627 CS.setAttributes(NoReturnAttr);
628 return CS.getInstruction();
629 }
Albert Gutowski5e08df02016-10-13 22:35:07 +0000630 }
631 llvm_unreachable("Incorrect MSVC intrinsic!");
632}
633
Mehdi Amini06d367c2016-10-24 20:39:34 +0000634namespace {
635// ARC cleanup for __builtin_os_log_format
636struct CallObjCArcUse final : EHScopeStack::Cleanup {
637 CallObjCArcUse(llvm::Value *object) : object(object) {}
638 llvm::Value *object;
639
640 void Emit(CodeGenFunction &CGF, Flags flags) override {
641 CGF.EmitARCIntrinsicUse(object);
642 }
643};
644}
645
Vedant Kumar10c31022017-07-29 00:19:51 +0000646Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
647 BuiltinCheckKind Kind) {
Victor Leschuk198357b2017-07-29 08:18:38 +0000648 assert((Kind == BCK_CLZPassedZero || Kind == BCK_CTZPassedZero)
649 && "Unsupported builtin check kind");
Vedant Kumar10c31022017-07-29 00:19:51 +0000650
651 Value *ArgValue = EmitScalarExpr(E);
652 if (!SanOpts.has(SanitizerKind::Builtin) || !getTarget().isCLZForZeroUndef())
653 return ArgValue;
654
655 SanitizerScope SanScope(this);
656 Value *Cond = Builder.CreateICmpNE(
657 ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
658 EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin),
659 SanitizerHandler::InvalidBuiltin,
660 {EmitCheckSourceLocation(E->getExprLoc()),
661 llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)},
662 None);
663 return ArgValue;
664}
665
Akira Hatanaka6b103bc2017-10-06 07:12:46 +0000666/// Get the argument type for arguments to os_log_helper.
667static CanQualType getOSLogArgType(ASTContext &C, int Size) {
668 QualType UnsignedTy = C.getIntTypeForBitwidth(Size * 8, /*Signed=*/false);
669 return C.getCanonicalType(UnsignedTy);
670}
671
672llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
673 const analyze_os_log::OSLogBufferLayout &Layout,
674 CharUnits BufferAlignment) {
675 ASTContext &Ctx = getContext();
676
677 llvm::SmallString<64> Name;
678 {
679 raw_svector_ostream OS(Name);
680 OS << "__os_log_helper";
681 OS << "_" << BufferAlignment.getQuantity();
682 OS << "_" << int(Layout.getSummaryByte());
683 OS << "_" << int(Layout.getNumArgsByte());
684 for (const auto &Item : Layout.Items)
685 OS << "_" << int(Item.getSizeByte()) << "_"
686 << int(Item.getDescriptorByte());
687 }
688
689 if (llvm::Function *F = CGM.getModule().getFunction(Name))
690 return F;
691
692 llvm::SmallVector<ImplicitParamDecl, 4> Params;
693 Params.emplace_back(Ctx, nullptr, SourceLocation(), &Ctx.Idents.get("buffer"),
694 Ctx.VoidPtrTy, ImplicitParamDecl::Other);
695
696 for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) {
697 char Size = Layout.Items[I].getSizeByte();
698 if (!Size)
699 continue;
700
701 Params.emplace_back(Ctx, nullptr, SourceLocation(),
702 &Ctx.Idents.get(std::string("arg") + std::to_string(I)),
703 getOSLogArgType(Ctx, Size), ImplicitParamDecl::Other);
704 }
705
706 FunctionArgList Args;
707 for (auto &P : Params)
708 Args.push_back(&P);
709
710 // The helper function has linkonce_odr linkage to enable the linker to merge
711 // identical functions. To ensure the merging always happens, 'noinline' is
712 // attached to the function when compiling with -Oz.
713 const CGFunctionInfo &FI =
714 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
715 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
716 llvm::Function *Fn = llvm::Function::Create(
717 FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule());
718 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
719 CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn);
720 CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
721
722 // Attach 'noinline' at -Oz.
723 if (CGM.getCodeGenOpts().OptimizeSize == 2)
724 Fn->addFnAttr(llvm::Attribute::NoInline);
725
726 auto NL = ApplyDebugLocation::CreateEmpty(*this);
727 IdentifierInfo *II = &Ctx.Idents.get(Name);
728 FunctionDecl *FD = FunctionDecl::Create(
729 Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
730 Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false);
731
732 StartFunction(FD, Ctx.VoidTy, Fn, FI, Args);
733
734 // Create a scope with an artificial location for the body of this function.
735 auto AL = ApplyDebugLocation::CreateArtificial(*this);
736
737 CharUnits Offset;
738 Address BufAddr(Builder.CreateLoad(GetAddrOfLocalVar(&Params[0]), "buf"),
739 BufferAlignment);
740 Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()),
741 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary"));
742 Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()),
743 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs"));
744
745 unsigned I = 1;
746 for (const auto &Item : Layout.Items) {
747 Builder.CreateStore(
748 Builder.getInt8(Item.getDescriptorByte()),
749 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor"));
750 Builder.CreateStore(
751 Builder.getInt8(Item.getSizeByte()),
752 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize"));
753
754 CharUnits Size = Item.size();
755 if (!Size.getQuantity())
756 continue;
757
758 Address Arg = GetAddrOfLocalVar(&Params[I]);
759 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset, "argData");
760 Addr = Builder.CreateBitCast(Addr, Arg.getPointer()->getType(),
761 "argDataCast");
762 Builder.CreateStore(Builder.CreateLoad(Arg), Addr);
763 Offset += Size;
764 ++I;
765 }
766
767 FinishFunction();
768
769 return Fn;
770}
771
772RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
773 assert(E.getNumArgs() >= 2 &&
774 "__builtin_os_log_format takes at least 2 arguments");
775 ASTContext &Ctx = getContext();
776 analyze_os_log::OSLogBufferLayout Layout;
777 analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout);
778 Address BufAddr = EmitPointerWithAlignment(E.getArg(0));
779 llvm::SmallVector<llvm::Value *, 4> RetainableOperands;
780
781 // Ignore argument 1, the format string. It is not currently used.
782 CallArgList Args;
783 Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy);
784
785 for (const auto &Item : Layout.Items) {
786 int Size = Item.getSizeByte();
787 if (!Size)
788 continue;
789
790 llvm::Value *ArgVal;
791
792 if (const Expr *TheExpr = Item.getExpr()) {
793 ArgVal = EmitScalarExpr(TheExpr, /*Ignore*/ false);
794
795 // Check if this is a retainable type.
796 if (TheExpr->getType()->isObjCRetainableType()) {
797 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar &&
798 "Only scalar can be a ObjC retainable type");
799 // Check if the object is constant, if not, save it in
800 // RetainableOperands.
801 if (!isa<Constant>(ArgVal))
802 RetainableOperands.push_back(ArgVal);
803 }
804 } else {
805 ArgVal = Builder.getInt32(Item.getConstValue().getQuantity());
806 }
807
808 unsigned ArgValSize =
809 CGM.getDataLayout().getTypeSizeInBits(ArgVal->getType());
810 llvm::IntegerType *IntTy = llvm::Type::getIntNTy(getLLVMContext(),
811 ArgValSize);
812 ArgVal = Builder.CreateBitOrPointerCast(ArgVal, IntTy);
813 CanQualType ArgTy = getOSLogArgType(Ctx, Size);
814 // If ArgVal has type x86_fp80, zero-extend ArgVal.
815 ArgVal = Builder.CreateZExtOrBitCast(ArgVal, ConvertType(ArgTy));
816 Args.add(RValue::get(ArgVal), ArgTy);
817 }
818
819 const CGFunctionInfo &FI =
820 CGM.getTypes().arrangeBuiltinFunctionCall(Ctx.VoidTy, Args);
821 llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction(
822 Layout, BufAddr.getAlignment());
823 EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args);
824
825 // Push a clang.arc.use cleanup for each object in RetainableOperands. The
826 // cleanup will cause the use to appear after the final log call, keeping
827 // the object valid while it’s held in the log buffer. Note that if there’s
828 // a release cleanup on the object, it will already be active; since
829 // cleanups are emitted in reverse order, the use will occur before the
830 // object is released.
831 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount &&
832 CGM.getCodeGenOpts().OptimizationLevel != 0)
833 for (llvm::Value *Object : RetainableOperands)
834 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), Object);
835
836 return RValue::get(BufAddr.getPointer());
837}
838
Mike Stump11289f42009-09-09 15:08:12 +0000839RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Peter Collingbournef7706832014-12-12 23:41:25 +0000840 unsigned BuiltinID, const CallExpr *E,
841 ReturnValueSlot ReturnValue) {
Chris Lattner24355b52008-10-06 06:56:41 +0000842 // See if we can constant fold this builtin. If so, don't emit it at all.
Anders Carlssonc9687902008-12-01 02:31:41 +0000843 Expr::EvalResult Result;
Eli Friedmandf88c542012-01-06 20:03:09 +0000844 if (E->EvaluateAsRValue(Result, CGM.getContext()) &&
Fariborz Jahanian24ac1592011-04-25 23:10:07 +0000845 !Result.hasSideEffects()) {
Anders Carlssonc9687902008-12-01 02:31:41 +0000846 if (Result.Val.isInt())
John McCallad7c5c12011-02-08 08:22:06 +0000847 return RValue::get(llvm::ConstantInt::get(getLLVMContext(),
Owen Andersonb7a2fe62009-07-24 23:12:58 +0000848 Result.Val.getInt()));
Chris Lattner07e96862010-10-01 23:43:16 +0000849 if (Result.Val.isFloat())
John McCallad7c5c12011-02-08 08:22:06 +0000850 return RValue::get(llvm::ConstantFP::get(getLLVMContext(),
851 Result.Val.getFloat()));
Chris Lattnera1518b12008-10-06 06:09:18 +0000852 }
Mike Stump11289f42009-09-09 15:08:12 +0000853
Chris Lattner24355b52008-10-06 06:56:41 +0000854 switch (BuiltinID) {
855 default: break; // Handle intrinsics and libm functions below.
Chris Lattnera97132a2008-10-06 07:26:43 +0000856 case Builtin::BI__builtin___CFStringMakeConstantString:
David Chisnall481e3a82010-01-23 02:40:42 +0000857 case Builtin::BI__builtin___NSStringMakeConstantString:
John McCallde0fe072017-08-15 21:42:52 +0000858 return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType()));
Chris Lattner0bf67912008-07-09 17:28:44 +0000859 case Builtin::BI__builtin_stdarg_start:
Anders Carlsson24ebce62007-10-12 23:56:29 +0000860 case Builtin::BI__builtin_va_start:
Reid Kleckner597e81d2014-03-26 15:38:33 +0000861 case Builtin::BI__va_start:
Charles Davisc7d5c942015-09-17 20:55:33 +0000862 case Builtin::BI__builtin_va_end:
863 return RValue::get(
864 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start
865 ? EmitScalarExpr(E->getArg(0))
866 : EmitVAListRef(E->getArg(0)).getPointer(),
867 BuiltinID != Builtin::BI__builtin_va_end));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000868 case Builtin::BI__builtin_va_copy: {
John McCall7f416cc2015-09-08 08:05:57 +0000869 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer();
870 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer();
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000871
Chris Lattner2192fe52011-07-18 04:24:23 +0000872 llvm::Type *Type = Int8PtrTy;
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000873
874 DstPtr = Builder.CreateBitCast(DstPtr, Type);
875 SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
David Blaikie43f9bb72015-05-18 22:14:03 +0000876 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy),
877 {DstPtr, SrcPtr}));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000878 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000879 case Builtin::BI__builtin_abs:
Eli Friedman65499b42012-01-17 22:11:30 +0000880 case Builtin::BI__builtin_labs:
881 case Builtin::BI__builtin_llabs: {
Mike Stump11289f42009-09-09 15:08:12 +0000882 Value *ArgValue = EmitScalarExpr(E->getArg(0));
883
Chris Lattner28ee5b32008-07-23 06:53:34 +0000884 Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
Mike Stump11289f42009-09-09 15:08:12 +0000885 Value *CmpResult =
886 Builder.CreateICmpSGE(ArgValue,
Owen Anderson0b75f232009-07-31 20:28:54 +0000887 llvm::Constant::getNullValue(ArgValue->getType()),
Chris Lattner28ee5b32008-07-23 06:53:34 +0000888 "abscond");
Mike Stump11289f42009-09-09 15:08:12 +0000889 Value *Result =
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000890 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
Mike Stump11289f42009-09-09 15:08:12 +0000891
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000892 return RValue::get(Result);
893 }
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000894 case Builtin::BI__builtin_fabs:
895 case Builtin::BI__builtin_fabsf:
896 case Builtin::BI__builtin_fabsl: {
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000897 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs));
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000898 }
Jan Veselyb4379f92014-09-26 01:19:41 +0000899 case Builtin::BI__builtin_fmod:
900 case Builtin::BI__builtin_fmodf:
901 case Builtin::BI__builtin_fmodl: {
902 Value *Arg1 = EmitScalarExpr(E->getArg(0));
903 Value *Arg2 = EmitScalarExpr(E->getArg(1));
904 Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod");
905 return RValue::get(Result);
906 }
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000907 case Builtin::BI__builtin_copysign:
908 case Builtin::BI__builtin_copysignf:
909 case Builtin::BI__builtin_copysignl: {
910 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign));
911 }
912 case Builtin::BI__builtin_ceil:
913 case Builtin::BI__builtin_ceilf:
914 case Builtin::BI__builtin_ceill: {
915 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil));
916 }
917 case Builtin::BI__builtin_floor:
918 case Builtin::BI__builtin_floorf:
919 case Builtin::BI__builtin_floorl: {
920 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor));
921 }
922 case Builtin::BI__builtin_trunc:
923 case Builtin::BI__builtin_truncf:
924 case Builtin::BI__builtin_truncl: {
925 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc));
926 }
927 case Builtin::BI__builtin_rint:
928 case Builtin::BI__builtin_rintf:
929 case Builtin::BI__builtin_rintl: {
930 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint));
931 }
932 case Builtin::BI__builtin_nearbyint:
933 case Builtin::BI__builtin_nearbyintf:
934 case Builtin::BI__builtin_nearbyintl: {
935 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint));
936 }
937 case Builtin::BI__builtin_round:
938 case Builtin::BI__builtin_roundf:
939 case Builtin::BI__builtin_roundl: {
940 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round));
941 }
942 case Builtin::BI__builtin_fmin:
943 case Builtin::BI__builtin_fminf:
944 case Builtin::BI__builtin_fminl: {
945 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum));
946 }
947 case Builtin::BI__builtin_fmax:
948 case Builtin::BI__builtin_fmaxf:
949 case Builtin::BI__builtin_fmaxl: {
950 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum));
951 }
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000952 case Builtin::BI__builtin_conj:
953 case Builtin::BI__builtin_conjf:
954 case Builtin::BI__builtin_conjl: {
955 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
956 Value *Real = ComplexVal.first;
957 Value *Imag = ComplexVal.second;
Jim Grosbachd3608f42012-09-21 00:18:27 +0000958 Value *Zero =
959 Imag->getType()->isFPOrFPVectorTy()
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000960 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType())
961 : llvm::Constant::getNullValue(Imag->getType());
Jim Grosbachd3608f42012-09-21 00:18:27 +0000962
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000963 Imag = Builder.CreateFSub(Zero, Imag, "sub");
964 return RValue::getComplex(std::make_pair(Real, Imag));
965 }
966 case Builtin::BI__builtin_creal:
967 case Builtin::BI__builtin_crealf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000968 case Builtin::BI__builtin_creall:
969 case Builtin::BIcreal:
970 case Builtin::BIcrealf:
971 case Builtin::BIcreall: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000972 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
973 return RValue::get(ComplexVal.first);
974 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000975
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000976 case Builtin::BI__builtin_cimag:
977 case Builtin::BI__builtin_cimagf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000978 case Builtin::BI__builtin_cimagl:
979 case Builtin::BIcimag:
980 case Builtin::BIcimagf:
981 case Builtin::BIcimagl: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000982 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
983 return RValue::get(ComplexVal.second);
984 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000985
Benjamin Kramer14128162012-01-28 18:42:57 +0000986 case Builtin::BI__builtin_ctzs:
Anders Carlsson093f1a02008-02-06 07:19:27 +0000987 case Builtin::BI__builtin_ctz:
988 case Builtin::BI__builtin_ctzl:
989 case Builtin::BI__builtin_ctzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +0000990 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +0000991
Chris Lattnera5f58b02011-07-09 17:41:47 +0000992 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000993 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Anders Carlsson093f1a02008-02-06 07:19:27 +0000994
Chris Lattner2192fe52011-07-18 04:24:23 +0000995 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +0000996 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +0000997 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Anders Carlsson093f1a02008-02-06 07:19:27 +0000998 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000999 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1000 "cast");
Anders Carlsson093f1a02008-02-06 07:19:27 +00001001 return RValue::get(Result);
1002 }
Benjamin Kramer14128162012-01-28 18:42:57 +00001003 case Builtin::BI__builtin_clzs:
Eli Friedman5e2281e2008-05-27 15:32:46 +00001004 case Builtin::BI__builtin_clz:
1005 case Builtin::BI__builtin_clzl:
1006 case Builtin::BI__builtin_clzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +00001007 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +00001008
Chris Lattnera5f58b02011-07-09 17:41:47 +00001009 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001010 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
Eli Friedman5e2281e2008-05-27 15:32:46 +00001011
Chris Lattner2192fe52011-07-18 04:24:23 +00001012 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +00001013 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +00001014 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Eli Friedman5e2281e2008-05-27 15:32:46 +00001015 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001016 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1017 "cast");
Eli Friedman5e2281e2008-05-27 15:32:46 +00001018 return RValue::get(Result);
1019 }
Daniel Dunbard93abc32008-07-21 17:19:41 +00001020 case Builtin::BI__builtin_ffs:
1021 case Builtin::BI__builtin_ffsl:
1022 case Builtin::BI__builtin_ffsll: {
1023 // ffs(x) -> x ? cttz(x) + 1 : 0
1024 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +00001025
Chris Lattnera5f58b02011-07-09 17:41:47 +00001026 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001027 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +00001028
Chris Lattner2192fe52011-07-18 04:24:23 +00001029 llvm::Type *ResultType = ConvertType(E->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00001030 Value *Tmp =
1031 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}),
1032 llvm::ConstantInt::get(ArgType, 1));
Owen Anderson0b75f232009-07-31 20:28:54 +00001033 Value *Zero = llvm::Constant::getNullValue(ArgType);
Daniel Dunbard93abc32008-07-21 17:19:41 +00001034 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
1035 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs");
1036 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001037 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1038 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +00001039 return RValue::get(Result);
1040 }
1041 case Builtin::BI__builtin_parity:
1042 case Builtin::BI__builtin_parityl:
1043 case Builtin::BI__builtin_parityll: {
1044 // parity(x) -> ctpop(x) & 1
1045 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +00001046
Chris Lattnera5f58b02011-07-09 17:41:47 +00001047 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001048 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +00001049
Chris Lattner2192fe52011-07-18 04:24:23 +00001050 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001051 Value *Tmp = Builder.CreateCall(F, ArgValue);
1052 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1));
Daniel Dunbard93abc32008-07-21 17:19:41 +00001053 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001054 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1055 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +00001056 return RValue::get(Result);
1057 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00001058 case Builtin::BI__popcnt16:
1059 case Builtin::BI__popcnt:
1060 case Builtin::BI__popcnt64:
Daniel Dunbard93abc32008-07-21 17:19:41 +00001061 case Builtin::BI__builtin_popcount:
1062 case Builtin::BI__builtin_popcountl:
1063 case Builtin::BI__builtin_popcountll: {
1064 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +00001065
Chris Lattnera5f58b02011-07-09 17:41:47 +00001066 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001067 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +00001068
Chris Lattner2192fe52011-07-18 04:24:23 +00001069 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001070 Value *Result = Builder.CreateCall(F, ArgValue);
Daniel Dunbard93abc32008-07-21 17:19:41 +00001071 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001072 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1073 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +00001074 return RValue::get(Result);
1075 }
Albert Gutowskib6a11ac2016-09-08 22:32:19 +00001076 case Builtin::BI_rotr8:
1077 case Builtin::BI_rotr16:
1078 case Builtin::BI_rotr:
1079 case Builtin::BI_lrotr:
1080 case Builtin::BI_rotr64: {
1081 Value *Val = EmitScalarExpr(E->getArg(0));
1082 Value *Shift = EmitScalarExpr(E->getArg(1));
1083
1084 llvm::Type *ArgType = Val->getType();
1085 Shift = Builder.CreateIntCast(Shift, ArgType, false);
1086 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
1087 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
1088 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
1089
1090 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
1091 Shift = Builder.CreateAnd(Shift, Mask);
1092 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift);
1093
1094 Value *RightShifted = Builder.CreateLShr(Val, Shift);
1095 Value *LeftShifted = Builder.CreateShl(Val, LeftShift);
1096 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
1097
1098 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
1099 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
1100 return RValue::get(Result);
1101 }
1102 case Builtin::BI_rotl8:
1103 case Builtin::BI_rotl16:
1104 case Builtin::BI_rotl:
1105 case Builtin::BI_lrotl:
1106 case Builtin::BI_rotl64: {
1107 Value *Val = EmitScalarExpr(E->getArg(0));
1108 Value *Shift = EmitScalarExpr(E->getArg(1));
1109
1110 llvm::Type *ArgType = Val->getType();
1111 Shift = Builder.CreateIntCast(Shift, ArgType, false);
1112 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
1113 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
1114 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
1115
1116 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
1117 Shift = Builder.CreateAnd(Shift, Mask);
1118 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift);
1119
1120 Value *LeftShifted = Builder.CreateShl(Val, Shift);
1121 Value *RightShifted = Builder.CreateLShr(Val, RightShift);
1122 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
1123
1124 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
1125 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
1126 return RValue::get(Result);
1127 }
Sanjay Patela24296b2015-09-02 20:01:30 +00001128 case Builtin::BI__builtin_unpredictable: {
1129 // Always return the argument of __builtin_unpredictable. LLVM does not
1130 // handle this builtin. Metadata for this builtin should be added directly
1131 // to instructions such as branches or switches that use it.
1132 return RValue::get(EmitScalarExpr(E->getArg(0)));
1133 }
Fariborz Jahanian0ebca282010-07-26 23:11:03 +00001134 case Builtin::BI__builtin_expect: {
Fariborz Jahanian24ac1592011-04-25 23:10:07 +00001135 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001136 llvm::Type *ArgType = ArgValue->getType();
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001137
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001138 Value *ExpectedValue = EmitScalarExpr(E->getArg(1));
Pete Cooperf051cbf2015-01-26 20:51:58 +00001139 // Don't generate llvm.expect on -O0 as the backend won't use it for
1140 // anything.
1141 // Note, we still IRGen ExpectedValue because it could have side-effects.
1142 if (CGM.getCodeGenOpts().OptimizationLevel == 0)
1143 return RValue::get(ArgValue);
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001144
Pete Cooperf051cbf2015-01-26 20:51:58 +00001145 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001146 Value *Result =
1147 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval");
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001148 return RValue::get(Result);
Fariborz Jahanian0ebca282010-07-26 23:11:03 +00001149 }
Hal Finkelbcc06082014-09-07 22:58:14 +00001150 case Builtin::BI__builtin_assume_aligned: {
1151 Value *PtrValue = EmitScalarExpr(E->getArg(0));
1152 Value *OffsetValue =
1153 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
1154
1155 Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
1156 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
1157 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();
1158
1159 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);
1160 return RValue::get(PtrValue);
1161 }
1162 case Builtin::BI__assume:
1163 case Builtin::BI__builtin_assume: {
1164 if (E->getArg(0)->HasSideEffects(getContext()))
1165 return RValue::get(nullptr);
1166
1167 Value *ArgValue = EmitScalarExpr(E->getArg(0));
1168 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
1169 return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
1170 }
Benjamin Kramera801f4a2012-10-06 14:42:22 +00001171 case Builtin::BI__builtin_bswap16:
Anders Carlssonef93b9d2007-12-02 21:58:10 +00001172 case Builtin::BI__builtin_bswap32:
1173 case Builtin::BI__builtin_bswap64: {
Matt Arsenault105e8922016-02-03 17:49:38 +00001174 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap));
1175 }
Matt Arsenault08087c52016-03-23 22:14:43 +00001176 case Builtin::BI__builtin_bitreverse8:
Matt Arsenault105e8922016-02-03 17:49:38 +00001177 case Builtin::BI__builtin_bitreverse16:
1178 case Builtin::BI__builtin_bitreverse32:
1179 case Builtin::BI__builtin_bitreverse64: {
1180 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse));
Mike Stump11289f42009-09-09 15:08:12 +00001181 }
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001182 case Builtin::BI__builtin_object_size: {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001183 unsigned Type =
1184 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
1185 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType()));
Richard Smith01ade172012-05-23 04:13:20 +00001186
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001187 // We pass this builtin onto the optimizer so that it can figure out the
1188 // object size in more complex cases.
George Burgess IV0d6592a2017-02-23 05:59:56 +00001189 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType,
1190 /*EmittedE=*/nullptr));
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001191 }
Daniel Dunbarb7257262008-07-21 22:59:13 +00001192 case Builtin::BI__builtin_prefetch: {
1193 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
1194 // FIXME: Technically these constants should of type 'int', yes?
Mike Stump11289f42009-09-09 15:08:12 +00001195 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001196 llvm::ConstantInt::get(Int32Ty, 0);
Mike Stump11289f42009-09-09 15:08:12 +00001197 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001198 llvm::ConstantInt::get(Int32Ty, 3);
Bruno Cardoso Lopes3b0297a2011-06-14 05:00:30 +00001199 Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001200 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00001201 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data}));
Anders Carlssonef93b9d2007-12-02 21:58:10 +00001202 }
Hal Finkel3fadbb52012-08-05 22:03:08 +00001203 case Builtin::BI__builtin_readcyclecounter: {
1204 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
David Blaikie4ba525b2015-07-14 17:27:39 +00001205 return RValue::get(Builder.CreateCall(F));
Hal Finkel3fadbb52012-08-05 22:03:08 +00001206 }
Renato Golinc491a8d2014-03-26 15:36:05 +00001207 case Builtin::BI__builtin___clear_cache: {
1208 Value *Begin = EmitScalarExpr(E->getArg(0));
1209 Value *End = EmitScalarExpr(E->getArg(1));
1210 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache);
David Blaikie43f9bb72015-05-18 22:14:03 +00001211 return RValue::get(Builder.CreateCall(F, {Begin, End}));
Renato Golinc491a8d2014-03-26 15:36:05 +00001212 }
Akira Hatanaka85365cd2015-07-02 22:15:41 +00001213 case Builtin::BI__builtin_trap:
1214 return RValue::get(EmitTrapCall(Intrinsic::trap));
1215 case Builtin::BI__debugbreak:
1216 return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
Chris Lattnerbf206382009-09-21 03:09:59 +00001217 case Builtin::BI__builtin_unreachable: {
Alexey Samsonovedf99a92014-11-07 22:29:38 +00001218 if (SanOpts.has(SanitizerKind::Unreachable)) {
Alexey Samsonov24cad992014-07-17 18:46:27 +00001219 SanitizerScope SanScope(this);
Alexey Samsonove396bfc2014-11-11 22:03:54 +00001220 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
1221 SanitizerKind::Unreachable),
Filipe Cabecinhas322ecd92016-12-12 16:18:40 +00001222 SanitizerHandler::BuiltinUnreachable,
1223 EmitCheckSourceLocation(E->getExprLoc()), None);
Alexey Samsonov24cad992014-07-17 18:46:27 +00001224 } else
John McCall20f6ab82011-01-12 03:41:02 +00001225 Builder.CreateUnreachable();
1226
1227 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001228 EmitBlock(createBasicBlock("unreachable.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001229
Craig Topper8a13c412014-05-21 05:09:00 +00001230 return RValue::get(nullptr);
Chris Lattnerbf206382009-09-21 03:09:59 +00001231 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001232
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001233 case Builtin::BI__builtin_powi:
1234 case Builtin::BI__builtin_powif:
Reid Kleckner1fcccdd2015-02-05 00:24:57 +00001235 case Builtin::BI__builtin_powil: {
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001236 Value *Base = EmitScalarExpr(E->getArg(0));
1237 Value *Exponent = EmitScalarExpr(E->getArg(1));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001238 llvm::Type *ArgType = Base->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001239 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001240 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001241 }
1242
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001243 case Builtin::BI__builtin_isgreater:
1244 case Builtin::BI__builtin_isgreaterequal:
1245 case Builtin::BI__builtin_isless:
1246 case Builtin::BI__builtin_islessequal:
1247 case Builtin::BI__builtin_islessgreater:
1248 case Builtin::BI__builtin_isunordered: {
1249 // Ordered comparisons: we know the arguments to these are matching scalar
1250 // floating point values.
Mike Stump11289f42009-09-09 15:08:12 +00001251 Value *LHS = EmitScalarExpr(E->getArg(0));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001252 Value *RHS = EmitScalarExpr(E->getArg(1));
Mike Stump11289f42009-09-09 15:08:12 +00001253
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001254 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00001255 default: llvm_unreachable("Unknown ordered comparison");
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001256 case Builtin::BI__builtin_isgreater:
1257 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
1258 break;
1259 case Builtin::BI__builtin_isgreaterequal:
1260 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
1261 break;
1262 case Builtin::BI__builtin_isless:
1263 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
1264 break;
1265 case Builtin::BI__builtin_islessequal:
1266 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
1267 break;
1268 case Builtin::BI__builtin_islessgreater:
1269 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
1270 break;
Mike Stump11289f42009-09-09 15:08:12 +00001271 case Builtin::BI__builtin_isunordered:
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001272 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
1273 break;
1274 }
1275 // ZExt bool to int type.
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001276 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType())));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001277 }
Eli Friedman1c277d02009-09-01 04:19:44 +00001278 case Builtin::BI__builtin_isnan: {
1279 Value *V = EmitScalarExpr(E->getArg(0));
1280 V = Builder.CreateFCmpUNO(V, V, "cmp");
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001281 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
Eli Friedman1c277d02009-09-01 04:19:44 +00001282 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001283
Dehao Chen5d4f0be2016-09-14 17:34:14 +00001284 case Builtin::BIfinite:
1285 case Builtin::BI__finite:
1286 case Builtin::BIfinitef:
1287 case Builtin::BI__finitef:
1288 case Builtin::BIfinitel:
1289 case Builtin::BI__finitel:
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001290 case Builtin::BI__builtin_isinf:
1291 case Builtin::BI__builtin_isfinite: {
1292 // isinf(x) --> fabs(x) == infinity
1293 // isfinite(x) --> fabs(x) != infinity
1294 // x != NaN via the ordered compare in either case.
Chris Lattner43660c52010-05-06 05:35:16 +00001295 Value *V = EmitScalarExpr(E->getArg(0));
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001296 Value *Fabs = EmitFAbs(*this, V);
1297 Constant *Infinity = ConstantFP::getInfinity(V->getType());
1298 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf)
1299 ? CmpInst::FCMP_OEQ
1300 : CmpInst::FCMP_ONE;
1301 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf");
1302 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType())));
Chris Lattner43660c52010-05-06 05:35:16 +00001303 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001304
Chandler Carruthc66deaf2015-03-19 22:39:51 +00001305 case Builtin::BI__builtin_isinf_sign: {
1306 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0
1307 Value *Arg = EmitScalarExpr(E->getArg(0));
1308 Value *AbsArg = EmitFAbs(*this, Arg);
1309 Value *IsInf = Builder.CreateFCmpOEQ(
1310 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf");
1311 Value *IsNeg = EmitSignBit(*this, Arg);
1312
1313 llvm::Type *IntTy = ConvertType(E->getType());
1314 Value *Zero = Constant::getNullValue(IntTy);
1315 Value *One = ConstantInt::get(IntTy, 1);
1316 Value *NegativeOne = ConstantInt::get(IntTy, -1);
1317 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One);
1318 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero);
1319 return RValue::get(Result);
1320 }
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001321
1322 case Builtin::BI__builtin_isnormal: {
1323 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min
1324 Value *V = EmitScalarExpr(E->getArg(0));
1325 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
1326
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001327 Value *Abs = EmitFAbs(*this, V);
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001328 Value *IsLessThanInf =
1329 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf");
1330 APFloat Smallest = APFloat::getSmallestNormalized(
1331 getContext().getFloatTypeSemantics(E->getArg(0)->getType()));
1332 Value *IsNormal =
1333 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest),
1334 "isnormal");
1335 V = Builder.CreateAnd(Eq, IsLessThanInf, "and");
1336 V = Builder.CreateAnd(V, IsNormal, "and");
1337 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
1338 }
1339
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001340 case Builtin::BI__builtin_fpclassify: {
1341 Value *V = EmitScalarExpr(E->getArg(5));
Chris Lattner2192fe52011-07-18 04:24:23 +00001342 llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001343
1344 // Create Result
1345 BasicBlock *Begin = Builder.GetInsertBlock();
1346 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn);
1347 Builder.SetInsertPoint(End);
1348 PHINode *Result =
Jay Foad20c0f022011-03-30 11:28:58 +00001349 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4,
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001350 "fpclassify_result");
1351
1352 // if (V==0) return FP_ZERO
1353 Builder.SetInsertPoint(Begin);
1354 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty),
1355 "iszero");
1356 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4));
1357 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn);
1358 Builder.CreateCondBr(IsZero, End, NotZero);
1359 Result->addIncoming(ZeroLiteral, Begin);
1360
1361 // if (V != V) return FP_NAN
1362 Builder.SetInsertPoint(NotZero);
1363 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp");
1364 Value *NanLiteral = EmitScalarExpr(E->getArg(0));
1365 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn);
1366 Builder.CreateCondBr(IsNan, End, NotNan);
1367 Result->addIncoming(NanLiteral, NotZero);
1368
1369 // if (fabs(V) == infinity) return FP_INFINITY
1370 Builder.SetInsertPoint(NotNan);
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001371 Value *VAbs = EmitFAbs(*this, V);
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001372 Value *IsInf =
1373 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()),
1374 "isinf");
1375 Value *InfLiteral = EmitScalarExpr(E->getArg(1));
1376 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn);
1377 Builder.CreateCondBr(IsInf, End, NotInf);
1378 Result->addIncoming(InfLiteral, NotNan);
1379
1380 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL
1381 Builder.SetInsertPoint(NotInf);
1382 APFloat Smallest = APFloat::getSmallestNormalized(
1383 getContext().getFloatTypeSemantics(E->getArg(5)->getType()));
1384 Value *IsNormal =
1385 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest),
1386 "isnormal");
1387 Value *NormalResult =
1388 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)),
1389 EmitScalarExpr(E->getArg(3)));
1390 Builder.CreateBr(End);
1391 Result->addIncoming(NormalResult, NotInf);
1392
1393 // return Result
1394 Builder.SetInsertPoint(End);
1395 return RValue::get(Result);
1396 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001397
Eli Friedmanf6bd1502009-06-02 07:10:30 +00001398 case Builtin::BIalloca:
Reid Kleckner59e4a6f2013-11-13 22:58:53 +00001399 case Builtin::BI_alloca:
Chris Lattner22b9ff42008-06-16 17:15:14 +00001400 case Builtin::BI__builtin_alloca: {
Chris Lattner22b9ff42008-06-16 17:15:14 +00001401 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemer1878da42016-10-27 17:18:24 +00001402 const TargetInfo &TI = getContext().getTargetInfo();
1403 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
1404 unsigned SuitableAlignmentInBytes =
David Majnemerbb103d92016-10-31 16:48:30 +00001405 CGM.getContext()
1406 .toCharUnitsFromBits(TI.getSuitableAlign())
1407 .getQuantity();
David Majnemer1878da42016-10-27 17:18:24 +00001408 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1409 AI->setAlignment(SuitableAlignmentInBytes);
1410 return RValue::get(AI);
Daniel Dunbar327acd72008-07-22 00:26:45 +00001411 }
David Majnemer51169932016-10-31 05:37:48 +00001412
1413 case Builtin::BI__builtin_alloca_with_align: {
1414 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemerbb103d92016-10-31 16:48:30 +00001415 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1));
1416 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue);
1417 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue();
1418 unsigned AlignmentInBytes =
1419 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity();
David Majnemer51169932016-10-31 05:37:48 +00001420 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1421 AI->setAlignment(AlignmentInBytes);
1422 return RValue::get(AI);
1423 }
1424
Eli Friedmand6ef69a2010-01-23 19:00:10 +00001425 case Builtin::BIbzero:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001426 case Builtin::BI__builtin_bzero: {
John McCall7f416cc2015-09-08 08:05:57 +00001427 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001428 Value *SizeVal = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00001429 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001430 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001431 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false);
1432 return RValue::get(Dest.getPointer());
Chris Lattner22b9ff42008-06-16 17:15:14 +00001433 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001434 case Builtin::BImemcpy:
Eli Friedmana3a40682008-05-19 23:27:48 +00001435 case Builtin::BI__builtin_memcpy: {
John McCall7f416cc2015-09-08 08:05:57 +00001436 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1437 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001438 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001439 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001440 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001441 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001442 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001443 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1444 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001445 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001446
Richard Smith5e29dd32017-01-20 00:45:35 +00001447 case Builtin::BI__builtin_char_memchr:
1448 BuiltinID = Builtin::BI__builtin_memchr;
1449 break;
1450
Chris Lattner30107ed2011-04-17 00:40:24 +00001451 case Builtin::BI__builtin___memcpy_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001452 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001453 llvm::APSInt Size, DstSize;
1454 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1455 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001456 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001457 if (Size.ugt(DstSize))
1458 break;
John McCall7f416cc2015-09-08 08:05:57 +00001459 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1460 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001461 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001462 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1463 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001464 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001465
Fariborz Jahanian4a303072010-06-16 16:22:04 +00001466 case Builtin::BI__builtin_objc_memmove_collectable: {
John McCall7f416cc2015-09-08 08:05:57 +00001467 Address DestAddr = EmitPointerWithAlignment(E->getArg(0));
1468 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1));
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001469 Value *SizeVal = EmitScalarExpr(E->getArg(2));
Jim Grosbachd3608f42012-09-21 00:18:27 +00001470 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this,
John McCall7f416cc2015-09-08 08:05:57 +00001471 DestAddr, SrcAddr, SizeVal);
1472 return RValue::get(DestAddr.getPointer());
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001473 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001474
1475 case Builtin::BI__builtin___memmove_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001476 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001477 llvm::APSInt Size, DstSize;
1478 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1479 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001480 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001481 if (Size.ugt(DstSize))
1482 break;
John McCall7f416cc2015-09-08 08:05:57 +00001483 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1484 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001485 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001486 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1487 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001488 }
1489
Eli Friedman7f4933f2009-12-17 00:14:28 +00001490 case Builtin::BImemmove:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001491 case Builtin::BI__builtin_memmove: {
John McCall7f416cc2015-09-08 08:05:57 +00001492 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1493 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001494 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001495 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001496 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001497 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001498 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001499 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1500 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001501 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001502 case Builtin::BImemset:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001503 case Builtin::BI__builtin_memset: {
John McCall7f416cc2015-09-08 08:05:57 +00001504 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Benjamin Krameracc6b4e2010-12-30 00:13:21 +00001505 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1506 Builder.getInt8Ty());
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001507 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001508 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001509 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001510 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1511 return RValue::get(Dest.getPointer());
Eli Friedmana3a40682008-05-19 23:27:48 +00001512 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001513 case Builtin::BI__builtin___memset_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001514 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001515 llvm::APSInt Size, DstSize;
1516 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1517 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001518 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001519 if (Size.ugt(DstSize))
1520 break;
John McCall7f416cc2015-09-08 08:05:57 +00001521 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Chris Lattner30107ed2011-04-17 00:40:24 +00001522 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1523 Builder.getInt8Ty());
1524 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001525 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1526 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001527 }
John McCall515c3c52010-03-03 10:30:05 +00001528 case Builtin::BI__builtin_dwarf_cfa: {
1529 // The offset in bytes from the first argument to the CFA.
1530 //
1531 // Why on earth is this in the frontend? Is there any reason at
1532 // all that the backend can't reasonably determine this while
1533 // lowering llvm.eh.dwarf.cfa()?
1534 //
1535 // TODO: If there's a satisfactory reason, add a target hook for
1536 // this instead of hard-coding 0, which is correct for most targets.
1537 int32_t Offset = 0;
1538
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001539 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa);
Jim Grosbachd3608f42012-09-21 00:18:27 +00001540 return RValue::get(Builder.CreateCall(F,
Chris Lattner5e016ae2010-06-27 07:15:29 +00001541 llvm::ConstantInt::get(Int32Ty, Offset)));
John McCall515c3c52010-03-03 10:30:05 +00001542 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001543 case Builtin::BI__builtin_return_address: {
John McCallde0fe072017-08-15 21:42:52 +00001544 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1545 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001546 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001547 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001548 }
Albert Gutowski397d81b2016-10-13 16:03:42 +00001549 case Builtin::BI_ReturnAddress: {
1550 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
1551 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
1552 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001553 case Builtin::BI__builtin_frame_address: {
John McCallde0fe072017-08-15 21:42:52 +00001554 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1555 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001556 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001557 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001558 }
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001559 case Builtin::BI__builtin_extract_return_addr: {
John McCalld4f4b7f2010-03-03 04:15:11 +00001560 Value *Address = EmitScalarExpr(E->getArg(0));
1561 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address);
1562 return RValue::get(Result);
1563 }
1564 case Builtin::BI__builtin_frob_return_addr: {
1565 Value *Address = EmitScalarExpr(E->getArg(0));
1566 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address);
1567 return RValue::get(Result);
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001568 }
John McCallbeec5a02010-03-06 00:35:14 +00001569 case Builtin::BI__builtin_dwarf_sp_column: {
Chris Lattner2192fe52011-07-18 04:24:23 +00001570 llvm::IntegerType *Ty
John McCallbeec5a02010-03-06 00:35:14 +00001571 = cast<llvm::IntegerType>(ConvertType(E->getType()));
1572 int Column = getTargetHooks().getDwarfEHStackPointer(CGM);
1573 if (Column == -1) {
1574 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column");
1575 return RValue::get(llvm::UndefValue::get(Ty));
1576 }
1577 return RValue::get(llvm::ConstantInt::get(Ty, Column, true));
1578 }
1579 case Builtin::BI__builtin_init_dwarf_reg_size_table: {
1580 Value *Address = EmitScalarExpr(E->getArg(0));
1581 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address))
1582 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table");
1583 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
1584 }
John McCall66769f82010-03-03 05:38:58 +00001585 case Builtin::BI__builtin_eh_return: {
1586 Value *Int = EmitScalarExpr(E->getArg(0));
1587 Value *Ptr = EmitScalarExpr(E->getArg(1));
1588
Chris Lattner2192fe52011-07-18 04:24:23 +00001589 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType());
John McCall66769f82010-03-03 05:38:58 +00001590 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) &&
1591 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants");
1592 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32
1593 ? Intrinsic::eh_return_i32
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001594 : Intrinsic::eh_return_i64);
David Blaikie43f9bb72015-05-18 22:14:03 +00001595 Builder.CreateCall(F, {Int, Ptr});
John McCall20f6ab82011-01-12 03:41:02 +00001596 Builder.CreateUnreachable();
1597
1598 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001599 EmitBlock(createBasicBlock("builtin_eh_return.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001600
Craig Topper8a13c412014-05-21 05:09:00 +00001601 return RValue::get(nullptr);
John McCall66769f82010-03-03 05:38:58 +00001602 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001603 case Builtin::BI__builtin_unwind_init: {
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001604 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
David Blaikie4ba525b2015-07-14 17:27:39 +00001605 return RValue::get(Builder.CreateCall(F));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001606 }
John McCall4b613fa2010-03-02 02:31:24 +00001607 case Builtin::BI__builtin_extend_pointer: {
1608 // Extends a pointer to the size of an _Unwind_Word, which is
John McCallb6cc2c042010-03-02 03:50:12 +00001609 // uint64_t on all platforms. Generally this gets poked into a
1610 // register and eventually used as an address, so if the
1611 // addressing registers are wider than pointers and the platform
1612 // doesn't implicitly ignore high-order bits when doing
1613 // addressing, we need to make sure we zext / sext based on
1614 // the platform's expectations.
John McCall4b613fa2010-03-02 02:31:24 +00001615 //
1616 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html
John McCallb6cc2c042010-03-02 03:50:12 +00001617
John McCallb6cc2c042010-03-02 03:50:12 +00001618 // Cast the pointer to intptr_t.
John McCall4b613fa2010-03-02 02:31:24 +00001619 Value *Ptr = EmitScalarExpr(E->getArg(0));
John McCallb6cc2c042010-03-02 03:50:12 +00001620 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast");
1621
1622 // If that's 64 bits, we're done.
1623 if (IntPtrTy->getBitWidth() == 64)
1624 return RValue::get(Result);
1625
1626 // Otherwise, ask the codegen data what to do.
John McCalld4f4b7f2010-03-03 04:15:11 +00001627 if (getTargetHooks().extendPointerWithSExt())
John McCallb6cc2c042010-03-02 03:50:12 +00001628 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext"));
1629 else
1630 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
John McCall4b613fa2010-03-02 02:31:24 +00001631 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001632 case Builtin::BI__builtin_setjmp: {
John McCall02269a62010-05-27 18:47:06 +00001633 // Buffer is a void**.
John McCall7f416cc2015-09-08 08:05:57 +00001634 Address Buf = EmitPointerWithAlignment(E->getArg(0));
John McCall02269a62010-05-27 18:47:06 +00001635
1636 // Store the frame pointer to the setjmp buffer.
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001637 Value *FrameAddr =
John McCall02269a62010-05-27 18:47:06 +00001638 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
Chris Lattner5e016ae2010-06-27 07:15:29 +00001639 ConstantInt::get(Int32Ty, 0));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001640 Builder.CreateStore(FrameAddr, Buf);
John McCall02269a62010-05-27 18:47:06 +00001641
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001642 // Store the stack pointer to the setjmp buffer.
1643 Value *StackAddr =
David Blaikie4ba525b2015-07-14 17:27:39 +00001644 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave));
John McCall7f416cc2015-09-08 08:05:57 +00001645 Address StackSaveSlot =
1646 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize());
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001647 Builder.CreateStore(StackAddr, StackSaveSlot);
1648
John McCall02269a62010-05-27 18:47:06 +00001649 // Call LLVM's EH setjmp, which is lightweight.
1650 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
John McCallad7c5c12011-02-08 08:22:06 +00001651 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00001652 return RValue::get(Builder.CreateCall(F, Buf.getPointer()));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001653 }
1654 case Builtin::BI__builtin_longjmp: {
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001655 Value *Buf = EmitScalarExpr(E->getArg(0));
John McCallad7c5c12011-02-08 08:22:06 +00001656 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall02269a62010-05-27 18:47:06 +00001657
1658 // Call LLVM's EH longjmp, which is lightweight.
1659 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf);
1660
John McCall20f6ab82011-01-12 03:41:02 +00001661 // longjmp doesn't return; mark this as unreachable.
1662 Builder.CreateUnreachable();
1663
1664 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001665 EmitBlock(createBasicBlock("longjmp.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001666
Craig Topper8a13c412014-05-21 05:09:00 +00001667 return RValue::get(nullptr);
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001668 }
Mon P Wangb84407d2008-05-09 22:40:52 +00001669 case Builtin::BI__sync_fetch_and_add:
Mon P Wangb84407d2008-05-09 22:40:52 +00001670 case Builtin::BI__sync_fetch_and_sub:
Chris Lattnerdc046542009-05-08 06:58:22 +00001671 case Builtin::BI__sync_fetch_and_or:
1672 case Builtin::BI__sync_fetch_and_and:
1673 case Builtin::BI__sync_fetch_and_xor:
Hal Finkeld2208b52014-10-02 20:53:50 +00001674 case Builtin::BI__sync_fetch_and_nand:
Chris Lattnerdc046542009-05-08 06:58:22 +00001675 case Builtin::BI__sync_add_and_fetch:
1676 case Builtin::BI__sync_sub_and_fetch:
1677 case Builtin::BI__sync_and_and_fetch:
1678 case Builtin::BI__sync_or_and_fetch:
1679 case Builtin::BI__sync_xor_and_fetch:
Hal Finkeld2208b52014-10-02 20:53:50 +00001680 case Builtin::BI__sync_nand_and_fetch:
Chris Lattnerdc046542009-05-08 06:58:22 +00001681 case Builtin::BI__sync_val_compare_and_swap:
1682 case Builtin::BI__sync_bool_compare_and_swap:
1683 case Builtin::BI__sync_lock_test_and_set:
1684 case Builtin::BI__sync_lock_release:
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001685 case Builtin::BI__sync_swap:
David Blaikie83d382b2011-09-23 05:06:16 +00001686 llvm_unreachable("Shouldn't make it through sema");
Chris Lattnerdc046542009-05-08 06:58:22 +00001687 case Builtin::BI__sync_fetch_and_add_1:
1688 case Builtin::BI__sync_fetch_and_add_2:
1689 case Builtin::BI__sync_fetch_and_add_4:
1690 case Builtin::BI__sync_fetch_and_add_8:
1691 case Builtin::BI__sync_fetch_and_add_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001692 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001693 case Builtin::BI__sync_fetch_and_sub_1:
1694 case Builtin::BI__sync_fetch_and_sub_2:
1695 case Builtin::BI__sync_fetch_and_sub_4:
1696 case Builtin::BI__sync_fetch_and_sub_8:
1697 case Builtin::BI__sync_fetch_and_sub_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001698 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001699 case Builtin::BI__sync_fetch_and_or_1:
1700 case Builtin::BI__sync_fetch_and_or_2:
1701 case Builtin::BI__sync_fetch_and_or_4:
1702 case Builtin::BI__sync_fetch_and_or_8:
1703 case Builtin::BI__sync_fetch_and_or_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001704 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001705 case Builtin::BI__sync_fetch_and_and_1:
1706 case Builtin::BI__sync_fetch_and_and_2:
1707 case Builtin::BI__sync_fetch_and_and_4:
1708 case Builtin::BI__sync_fetch_and_and_8:
1709 case Builtin::BI__sync_fetch_and_and_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001710 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001711 case Builtin::BI__sync_fetch_and_xor_1:
1712 case Builtin::BI__sync_fetch_and_xor_2:
1713 case Builtin::BI__sync_fetch_and_xor_4:
1714 case Builtin::BI__sync_fetch_and_xor_8:
1715 case Builtin::BI__sync_fetch_and_xor_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001716 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E);
Hal Finkeld2208b52014-10-02 20:53:50 +00001717 case Builtin::BI__sync_fetch_and_nand_1:
1718 case Builtin::BI__sync_fetch_and_nand_2:
1719 case Builtin::BI__sync_fetch_and_nand_4:
1720 case Builtin::BI__sync_fetch_and_nand_8:
1721 case Builtin::BI__sync_fetch_and_nand_16:
1722 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E);
Mike Stump11289f42009-09-09 15:08:12 +00001723
Chris Lattnerdc046542009-05-08 06:58:22 +00001724 // Clang extensions: not overloaded yet.
Mon P Wangb84407d2008-05-09 22:40:52 +00001725 case Builtin::BI__sync_fetch_and_min:
Eli Friedmane9f81132011-09-07 01:41:24 +00001726 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001727 case Builtin::BI__sync_fetch_and_max:
Eli Friedmane9f81132011-09-07 01:41:24 +00001728 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001729 case Builtin::BI__sync_fetch_and_umin:
Eli Friedmane9f81132011-09-07 01:41:24 +00001730 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001731 case Builtin::BI__sync_fetch_and_umax:
Eli Friedmane9f81132011-09-07 01:41:24 +00001732 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E);
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001733
Chris Lattnerdc046542009-05-08 06:58:22 +00001734 case Builtin::BI__sync_add_and_fetch_1:
1735 case Builtin::BI__sync_add_and_fetch_2:
1736 case Builtin::BI__sync_add_and_fetch_4:
1737 case Builtin::BI__sync_add_and_fetch_8:
1738 case Builtin::BI__sync_add_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001739 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001740 llvm::Instruction::Add);
Chris Lattnerdc046542009-05-08 06:58:22 +00001741 case Builtin::BI__sync_sub_and_fetch_1:
1742 case Builtin::BI__sync_sub_and_fetch_2:
1743 case Builtin::BI__sync_sub_and_fetch_4:
1744 case Builtin::BI__sync_sub_and_fetch_8:
1745 case Builtin::BI__sync_sub_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001746 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001747 llvm::Instruction::Sub);
Chris Lattnerdc046542009-05-08 06:58:22 +00001748 case Builtin::BI__sync_and_and_fetch_1:
1749 case Builtin::BI__sync_and_and_fetch_2:
1750 case Builtin::BI__sync_and_and_fetch_4:
1751 case Builtin::BI__sync_and_and_fetch_8:
1752 case Builtin::BI__sync_and_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001753 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001754 llvm::Instruction::And);
Chris Lattnerdc046542009-05-08 06:58:22 +00001755 case Builtin::BI__sync_or_and_fetch_1:
1756 case Builtin::BI__sync_or_and_fetch_2:
1757 case Builtin::BI__sync_or_and_fetch_4:
1758 case Builtin::BI__sync_or_and_fetch_8:
1759 case Builtin::BI__sync_or_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001760 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001761 llvm::Instruction::Or);
Chris Lattnerdc046542009-05-08 06:58:22 +00001762 case Builtin::BI__sync_xor_and_fetch_1:
1763 case Builtin::BI__sync_xor_and_fetch_2:
1764 case Builtin::BI__sync_xor_and_fetch_4:
1765 case Builtin::BI__sync_xor_and_fetch_8:
1766 case Builtin::BI__sync_xor_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001767 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001768 llvm::Instruction::Xor);
Hal Finkeld2208b52014-10-02 20:53:50 +00001769 case Builtin::BI__sync_nand_and_fetch_1:
1770 case Builtin::BI__sync_nand_and_fetch_2:
1771 case Builtin::BI__sync_nand_and_fetch_4:
1772 case Builtin::BI__sync_nand_and_fetch_8:
1773 case Builtin::BI__sync_nand_and_fetch_16:
1774 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E,
1775 llvm::Instruction::And, true);
Mike Stump11289f42009-09-09 15:08:12 +00001776
Chris Lattnerdc046542009-05-08 06:58:22 +00001777 case Builtin::BI__sync_val_compare_and_swap_1:
1778 case Builtin::BI__sync_val_compare_and_swap_2:
1779 case Builtin::BI__sync_val_compare_and_swap_4:
1780 case Builtin::BI__sync_val_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001781 case Builtin::BI__sync_val_compare_and_swap_16:
1782 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001783
Chris Lattnerdc046542009-05-08 06:58:22 +00001784 case Builtin::BI__sync_bool_compare_and_swap_1:
1785 case Builtin::BI__sync_bool_compare_and_swap_2:
1786 case Builtin::BI__sync_bool_compare_and_swap_4:
1787 case Builtin::BI__sync_bool_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001788 case Builtin::BI__sync_bool_compare_and_swap_16:
1789 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001790
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001791 case Builtin::BI__sync_swap_1:
1792 case Builtin::BI__sync_swap_2:
1793 case Builtin::BI__sync_swap_4:
1794 case Builtin::BI__sync_swap_8:
1795 case Builtin::BI__sync_swap_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001796 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001797
Chris Lattnerdc046542009-05-08 06:58:22 +00001798 case Builtin::BI__sync_lock_test_and_set_1:
1799 case Builtin::BI__sync_lock_test_and_set_2:
1800 case Builtin::BI__sync_lock_test_and_set_4:
1801 case Builtin::BI__sync_lock_test_and_set_8:
1802 case Builtin::BI__sync_lock_test_and_set_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001803 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Daniel Dunbar4ff562d2010-03-20 07:04:11 +00001804
Chris Lattnerdc046542009-05-08 06:58:22 +00001805 case Builtin::BI__sync_lock_release_1:
1806 case Builtin::BI__sync_lock_release_2:
1807 case Builtin::BI__sync_lock_release_4:
1808 case Builtin::BI__sync_lock_release_8:
Chris Lattnerafde2592009-05-13 04:46:13 +00001809 case Builtin::BI__sync_lock_release_16: {
1810 Value *Ptr = EmitScalarExpr(E->getArg(0));
Eli Friedman84d28122011-09-13 22:21:56 +00001811 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
1812 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
Eli Friedmanfefe0d02012-03-16 01:48:04 +00001813 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
1814 StoreSize.getQuantity() * 8);
1815 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
Jim Grosbachd3608f42012-09-21 00:18:27 +00001816 llvm::StoreInst *Store =
John McCall7f416cc2015-09-08 08:05:57 +00001817 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr,
1818 StoreSize);
JF Bastien92f4ef12016-04-06 17:26:42 +00001819 Store->setAtomic(llvm::AtomicOrdering::Release);
Craig Topper8a13c412014-05-21 05:09:00 +00001820 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001821 }
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001822
Chris Lattnerafde2592009-05-13 04:46:13 +00001823 case Builtin::BI__sync_synchronize: {
Eli Friedmane9f81132011-09-07 01:41:24 +00001824 // We assume this is supposed to correspond to a C++0x-style
1825 // sequentially-consistent fence (i.e. this is only usable for
1826 // synchonization, not device I/O or anything like that). This intrinsic
Jim Grosbachd3608f42012-09-21 00:18:27 +00001827 // is really badly designed in the sense that in theory, there isn't
Eli Friedmane9f81132011-09-07 01:41:24 +00001828 // any way to safely use it... but in practice, it mostly works
1829 // to use it with non-atomic loads and stores to get acquire/release
1830 // semantics.
JF Bastien92f4ef12016-04-06 17:26:42 +00001831 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent);
Craig Topper8a13c412014-05-21 05:09:00 +00001832 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001833 }
Mike Stump11289f42009-09-09 15:08:12 +00001834
Michael Zolotukhin84df1232015-09-08 23:52:33 +00001835 case Builtin::BI__builtin_nontemporal_load:
1836 return RValue::get(EmitNontemporalLoad(*this, E));
1837 case Builtin::BI__builtin_nontemporal_store:
1838 return RValue::get(EmitNontemporalStore(*this, E));
Richard Smith01ba47d2012-04-13 00:45:38 +00001839 case Builtin::BI__c11_atomic_is_lock_free:
1840 case Builtin::BI__atomic_is_lock_free: {
1841 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the
1842 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since
1843 // _Atomic(T) is always properly-aligned.
1844 const char *LibCallName = "__atomic_is_lock_free";
1845 CallArgList Args;
1846 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))),
1847 getContext().getSizeType());
1848 if (BuiltinID == Builtin::BI__atomic_is_lock_free)
1849 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))),
1850 getContext().VoidPtrTy);
1851 else
1852 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)),
1853 getContext().VoidPtrTy);
1854 const CGFunctionInfo &FuncInfo =
John McCallc56a8b32016-03-11 04:30:31 +00001855 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001856 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
1857 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
John McCallb92ab1a2016-10-26 23:46:34 +00001858 return EmitCall(FuncInfo, CGCallee::forDirect(Func),
1859 ReturnValueSlot(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001860 }
1861
1862 case Builtin::BI__atomic_test_and_set: {
1863 // Look at the argument type to determine whether this is a volatile
1864 // operation. The parameter type is always volatile.
1865 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1866 bool Volatile =
1867 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1868
1869 Value *Ptr = EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +00001870 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001871 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1872 Value *NewVal = Builder.getInt8(1);
1873 Value *Order = EmitScalarExpr(E->getArg(1));
1874 if (isa<llvm::ConstantInt>(Order)) {
1875 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
Craig Topper8a13c412014-05-21 05:09:00 +00001876 AtomicRMWInst *Result = nullptr;
Richard Smith01ba47d2012-04-13 00:45:38 +00001877 switch (ord) {
1878 case 0: // memory_order_relaxed
1879 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001880 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1881 llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001882 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001883 case 1: // memory_order_consume
1884 case 2: // memory_order_acquire
1885 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1886 llvm::AtomicOrdering::Acquire);
Richard Smith01ba47d2012-04-13 00:45:38 +00001887 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001888 case 3: // memory_order_release
1889 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1890 llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001891 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001892 case 4: // memory_order_acq_rel
1893
1894 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1895 llvm::AtomicOrdering::AcquireRelease);
Richard Smith01ba47d2012-04-13 00:45:38 +00001896 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001897 case 5: // memory_order_seq_cst
1898 Result = Builder.CreateAtomicRMW(
1899 llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1900 llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001901 break;
1902 }
1903 Result->setVolatile(Volatile);
1904 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1905 }
1906
1907 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1908
1909 llvm::BasicBlock *BBs[5] = {
1910 createBasicBlock("monotonic", CurFn),
1911 createBasicBlock("acquire", CurFn),
1912 createBasicBlock("release", CurFn),
1913 createBasicBlock("acqrel", CurFn),
1914 createBasicBlock("seqcst", CurFn)
1915 };
1916 llvm::AtomicOrdering Orders[5] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001917 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire,
1918 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease,
1919 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001920
1921 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1922 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1923
1924 Builder.SetInsertPoint(ContBB);
1925 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set");
1926
1927 for (unsigned i = 0; i < 5; ++i) {
1928 Builder.SetInsertPoint(BBs[i]);
1929 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg,
1930 Ptr, NewVal, Orders[i]);
1931 RMW->setVolatile(Volatile);
1932 Result->addIncoming(RMW, BBs[i]);
1933 Builder.CreateBr(ContBB);
1934 }
1935
1936 SI->addCase(Builder.getInt32(0), BBs[0]);
1937 SI->addCase(Builder.getInt32(1), BBs[1]);
1938 SI->addCase(Builder.getInt32(2), BBs[1]);
1939 SI->addCase(Builder.getInt32(3), BBs[2]);
1940 SI->addCase(Builder.getInt32(4), BBs[3]);
1941 SI->addCase(Builder.getInt32(5), BBs[4]);
1942
1943 Builder.SetInsertPoint(ContBB);
1944 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1945 }
1946
1947 case Builtin::BI__atomic_clear: {
1948 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1949 bool Volatile =
1950 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1951
John McCall7f416cc2015-09-08 08:05:57 +00001952 Address Ptr = EmitPointerWithAlignment(E->getArg(0));
1953 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001954 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1955 Value *NewVal = Builder.getInt8(0);
1956 Value *Order = EmitScalarExpr(E->getArg(1));
1957 if (isa<llvm::ConstantInt>(Order)) {
1958 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1959 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001960 switch (ord) {
1961 case 0: // memory_order_relaxed
1962 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001963 Store->setOrdering(llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001964 break;
1965 case 3: // memory_order_release
JF Bastien92f4ef12016-04-06 17:26:42 +00001966 Store->setOrdering(llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001967 break;
1968 case 5: // memory_order_seq_cst
JF Bastien92f4ef12016-04-06 17:26:42 +00001969 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001970 break;
1971 }
Craig Topper8a13c412014-05-21 05:09:00 +00001972 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00001973 }
1974
1975 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1976
1977 llvm::BasicBlock *BBs[3] = {
1978 createBasicBlock("monotonic", CurFn),
1979 createBasicBlock("release", CurFn),
1980 createBasicBlock("seqcst", CurFn)
1981 };
1982 llvm::AtomicOrdering Orders[3] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001983 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release,
1984 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001985
1986 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1987 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1988
1989 for (unsigned i = 0; i < 3; ++i) {
1990 Builder.SetInsertPoint(BBs[i]);
1991 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001992 Store->setOrdering(Orders[i]);
1993 Builder.CreateBr(ContBB);
1994 }
1995
1996 SI->addCase(Builder.getInt32(0), BBs[0]);
1997 SI->addCase(Builder.getInt32(3), BBs[1]);
1998 SI->addCase(Builder.getInt32(5), BBs[2]);
1999
2000 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00002001 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00002002 }
2003
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002004 case Builtin::BI__atomic_thread_fence:
Richard Smithb1e36c62012-04-11 17:55:32 +00002005 case Builtin::BI__atomic_signal_fence:
2006 case Builtin::BI__c11_atomic_thread_fence:
2007 case Builtin::BI__c11_atomic_signal_fence: {
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002008 llvm::SyncScope::ID SSID;
Richard Smithb1e36c62012-04-11 17:55:32 +00002009 if (BuiltinID == Builtin::BI__atomic_signal_fence ||
2010 BuiltinID == Builtin::BI__c11_atomic_signal_fence)
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002011 SSID = llvm::SyncScope::SingleThread;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002012 else
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002013 SSID = llvm::SyncScope::System;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002014 Value *Order = EmitScalarExpr(E->getArg(0));
2015 if (isa<llvm::ConstantInt>(Order)) {
2016 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
2017 switch (ord) {
2018 case 0: // memory_order_relaxed
2019 default: // invalid order
2020 break;
2021 case 1: // memory_order_consume
2022 case 2: // memory_order_acquire
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002023 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002024 break;
2025 case 3: // memory_order_release
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002026 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002027 break;
2028 case 4: // memory_order_acq_rel
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002029 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002030 break;
2031 case 5: // memory_order_seq_cst
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002032 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002033 break;
2034 }
Craig Topper8a13c412014-05-21 05:09:00 +00002035 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002036 }
2037
2038 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB;
2039 AcquireBB = createBasicBlock("acquire", CurFn);
2040 ReleaseBB = createBasicBlock("release", CurFn);
2041 AcqRelBB = createBasicBlock("acqrel", CurFn);
2042 SeqCstBB = createBasicBlock("seqcst", CurFn);
2043 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
2044
2045 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
2046 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB);
2047
2048 Builder.SetInsertPoint(AcquireBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002049 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002050 Builder.CreateBr(ContBB);
2051 SI->addCase(Builder.getInt32(1), AcquireBB);
2052 SI->addCase(Builder.getInt32(2), AcquireBB);
2053
2054 Builder.SetInsertPoint(ReleaseBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002055 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002056 Builder.CreateBr(ContBB);
2057 SI->addCase(Builder.getInt32(3), ReleaseBB);
2058
2059 Builder.SetInsertPoint(AcqRelBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002060 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002061 Builder.CreateBr(ContBB);
2062 SI->addCase(Builder.getInt32(4), AcqRelBB);
2063
2064 Builder.SetInsertPoint(SeqCstBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002065 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002066 Builder.CreateBr(ContBB);
2067 SI->addCase(Builder.getInt32(5), SeqCstBB);
2068
2069 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00002070 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002071 }
2072
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002073 // Library functions with special handling.
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002074 case Builtin::BIsqrt:
2075 case Builtin::BIsqrtf:
2076 case Builtin::BIsqrtl: {
Hal Finkel28b2ae32013-09-12 23:57:55 +00002077 // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only
2078 // in finite- or unsafe-math mode (the intrinsic has different semantics
2079 // for handling negative numbers compared to the library function, so
2080 // -fmath-errno=0 is not enough).
2081 if (!FD->hasAttr<ConstAttr>())
2082 break;
2083 if (!(CGM.getCodeGenOpts().UnsafeFPMath ||
2084 CGM.getCodeGenOpts().NoNaNsFPMath))
2085 break;
2086 Value *Arg0 = EmitScalarExpr(E->getArg(0));
2087 llvm::Type *ArgType = Arg0->getType();
2088 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType);
2089 return RValue::get(Builder.CreateCall(F, Arg0));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002090 }
2091
Reid Kleckner8a8c1292015-02-05 00:18:01 +00002092 case Builtin::BI__builtin_pow:
2093 case Builtin::BI__builtin_powf:
2094 case Builtin::BI__builtin_powl:
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002095 case Builtin::BIpow:
2096 case Builtin::BIpowf:
2097 case Builtin::BIpowl: {
Eli Benderskyc3496b02013-07-24 21:22:01 +00002098 // Transform a call to pow* into a @llvm.pow.* intrinsic call.
2099 if (!FD->hasAttr<ConstAttr>())
2100 break;
2101 Value *Base = EmitScalarExpr(E->getArg(0));
2102 Value *Exponent = EmitScalarExpr(E->getArg(1));
2103 llvm::Type *ArgType = Base->getType();
2104 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00002105 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002106 }
Eli Friedman99d20f82010-03-06 02:17:52 +00002107
Cameron Zwarichae7bc982011-07-08 21:39:34 +00002108 case Builtin::BIfma:
2109 case Builtin::BIfmaf:
2110 case Builtin::BIfmal:
2111 case Builtin::BI__builtin_fma:
2112 case Builtin::BI__builtin_fmaf:
2113 case Builtin::BI__builtin_fmal: {
2114 // Rewrite fma to intrinsic.
2115 Value *FirstArg = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +00002116 llvm::Type *ArgType = FirstArg->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00002117 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00002118 return RValue::get(
2119 Builder.CreateCall(F, {FirstArg, EmitScalarExpr(E->getArg(1)),
2120 EmitScalarExpr(E->getArg(2))}));
Cameron Zwarichae7bc982011-07-08 21:39:34 +00002121 }
2122
Eli Friedman99d20f82010-03-06 02:17:52 +00002123 case Builtin::BI__builtin_signbit:
2124 case Builtin::BI__builtin_signbitf:
2125 case Builtin::BI__builtin_signbitl: {
Chandler Carruthc66deaf2015-03-19 22:39:51 +00002126 return RValue::get(
2127 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))),
2128 ConvertType(E->getType())));
Eli Friedman99d20f82010-03-06 02:17:52 +00002129 }
Reid Kleckner30701ed2017-09-05 20:27:35 +00002130 case Builtin::BI__annotation: {
2131 // Re-encode each wide string to UTF8 and make an MDString.
2132 SmallVector<Metadata *, 1> Strings;
2133 for (const Expr *Arg : E->arguments()) {
2134 const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts());
2135 assert(Str->getCharByteWidth() == 2);
2136 StringRef WideBytes = Str->getBytes();
2137 std::string StrUtf8;
2138 if (!convertUTF16ToUTF8String(
2139 makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) {
2140 CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument");
2141 continue;
2142 }
2143 Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8));
2144 }
2145
2146 // Build and MDTuple of MDStrings and emit the intrinsic call.
Reid Klecknerd53c39b2017-09-05 20:38:29 +00002147 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {});
Reid Kleckner30701ed2017-09-05 20:27:35 +00002148 MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings);
2149 Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple));
2150 return RValue::getIgnored();
2151 }
Julien Lerouge5a6b6982011-09-09 22:41:49 +00002152 case Builtin::BI__builtin_annotation: {
2153 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0));
2154 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation,
2155 AnnVal->getType());
2156
2157 // Get the annotation string, go through casts. Sema requires this to be a
2158 // non-wide string literal, potentially casted, so the cast<> is safe.
2159 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts();
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002160 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString();
Julien Lerouge5a6b6982011-09-09 22:41:49 +00002161 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc()));
2162 }
Michael Gottesman15343992013-06-18 20:40:40 +00002163 case Builtin::BI__builtin_addcb:
Michael Gottesman54398012013-01-13 02:22:39 +00002164 case Builtin::BI__builtin_addcs:
2165 case Builtin::BI__builtin_addc:
2166 case Builtin::BI__builtin_addcl:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002167 case Builtin::BI__builtin_addcll:
Michael Gottesman15343992013-06-18 20:40:40 +00002168 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002169 case Builtin::BI__builtin_subcs:
2170 case Builtin::BI__builtin_subc:
2171 case Builtin::BI__builtin_subcl:
2172 case Builtin::BI__builtin_subcll: {
Michael Gottesman54398012013-01-13 02:22:39 +00002173
2174 // We translate all of these builtins from expressions of the form:
2175 // int x = ..., y = ..., carryin = ..., carryout, result;
2176 // result = __builtin_addc(x, y, carryin, &carryout);
2177 //
2178 // to LLVM IR of the form:
2179 //
2180 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
2181 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0
2182 // %carry1 = extractvalue {i32, i1} %tmp1, 1
2183 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1,
2184 // i32 %carryin)
2185 // %result = extractvalue {i32, i1} %tmp2, 0
2186 // %carry2 = extractvalue {i32, i1} %tmp2, 1
2187 // %tmp3 = or i1 %carry1, %carry2
2188 // %tmp4 = zext i1 %tmp3 to i32
2189 // store i32 %tmp4, i32* %carryout
2190
2191 // Scalarize our inputs.
2192 llvm::Value *X = EmitScalarExpr(E->getArg(0));
2193 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
2194 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00002195 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3));
Michael Gottesman54398012013-01-13 02:22:39 +00002196
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002197 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow.
2198 llvm::Intrinsic::ID IntrinsicId;
2199 switch (BuiltinID) {
2200 default: llvm_unreachable("Unknown multiprecision builtin id.");
Michael Gottesman15343992013-06-18 20:40:40 +00002201 case Builtin::BI__builtin_addcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002202 case Builtin::BI__builtin_addcs:
2203 case Builtin::BI__builtin_addc:
2204 case Builtin::BI__builtin_addcl:
2205 case Builtin::BI__builtin_addcll:
2206 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2207 break;
Michael Gottesman15343992013-06-18 20:40:40 +00002208 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002209 case Builtin::BI__builtin_subcs:
2210 case Builtin::BI__builtin_subc:
2211 case Builtin::BI__builtin_subcl:
2212 case Builtin::BI__builtin_subcll:
2213 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2214 break;
2215 }
Michael Gottesman54398012013-01-13 02:22:39 +00002216
2217 // Construct our resulting LLVM IR expression.
2218 llvm::Value *Carry1;
2219 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId,
2220 X, Y, Carry1);
2221 llvm::Value *Carry2;
2222 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId,
2223 Sum1, Carryin, Carry2);
2224 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2),
2225 X->getType());
John McCall7f416cc2015-09-08 08:05:57 +00002226 Builder.CreateStore(CarryOut, CarryOutPtr);
Michael Gottesman54398012013-01-13 02:22:39 +00002227 return RValue::get(Sum2);
2228 }
John McCall03107a42015-10-29 20:48:01 +00002229
2230 case Builtin::BI__builtin_add_overflow:
2231 case Builtin::BI__builtin_sub_overflow:
2232 case Builtin::BI__builtin_mul_overflow: {
2233 const clang::Expr *LeftArg = E->getArg(0);
2234 const clang::Expr *RightArg = E->getArg(1);
2235 const clang::Expr *ResultArg = E->getArg(2);
2236
2237 clang::QualType ResultQTy =
2238 ResultArg->getType()->castAs<PointerType>()->getPointeeType();
2239
2240 WidthAndSignedness LeftInfo =
2241 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType());
2242 WidthAndSignedness RightInfo =
2243 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType());
2244 WidthAndSignedness ResultInfo =
2245 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy);
2246 WidthAndSignedness EncompassingInfo =
2247 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo});
2248
2249 llvm::Type *EncompassingLLVMTy =
2250 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width);
2251
2252 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy);
2253
2254 llvm::Intrinsic::ID IntrinsicId;
2255 switch (BuiltinID) {
2256 default:
2257 llvm_unreachable("Unknown overflow builtin id.");
2258 case Builtin::BI__builtin_add_overflow:
2259 IntrinsicId = EncompassingInfo.Signed
2260 ? llvm::Intrinsic::sadd_with_overflow
2261 : llvm::Intrinsic::uadd_with_overflow;
2262 break;
2263 case Builtin::BI__builtin_sub_overflow:
2264 IntrinsicId = EncompassingInfo.Signed
2265 ? llvm::Intrinsic::ssub_with_overflow
2266 : llvm::Intrinsic::usub_with_overflow;
2267 break;
2268 case Builtin::BI__builtin_mul_overflow:
2269 IntrinsicId = EncompassingInfo.Signed
2270 ? llvm::Intrinsic::smul_with_overflow
2271 : llvm::Intrinsic::umul_with_overflow;
2272 break;
2273 }
2274
2275 llvm::Value *Left = EmitScalarExpr(LeftArg);
2276 llvm::Value *Right = EmitScalarExpr(RightArg);
2277 Address ResultPtr = EmitPointerWithAlignment(ResultArg);
2278
2279 // Extend each operand to the encompassing type.
2280 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed);
2281 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed);
2282
2283 // Perform the operation on the extended values.
2284 llvm::Value *Overflow, *Result;
2285 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow);
2286
2287 if (EncompassingInfo.Width > ResultInfo.Width) {
2288 // The encompassing type is wider than the result type, so we need to
2289 // truncate it.
2290 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy);
2291
2292 // To see if the truncation caused an overflow, we will extend
2293 // the result and then compare it to the original result.
2294 llvm::Value *ResultTruncExt = Builder.CreateIntCast(
2295 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed);
2296 llvm::Value *TruncationOverflow =
2297 Builder.CreateICmpNE(Result, ResultTruncExt);
2298
2299 Overflow = Builder.CreateOr(Overflow, TruncationOverflow);
2300 Result = ResultTrunc;
2301 }
2302
2303 // Finally, store the result using the pointer.
2304 bool isVolatile =
2305 ResultArg->getType()->getPointeeType().isVolatileQualified();
2306 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile);
2307
2308 return RValue::get(Overflow);
2309 }
2310
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002311 case Builtin::BI__builtin_uadd_overflow:
2312 case Builtin::BI__builtin_uaddl_overflow:
2313 case Builtin::BI__builtin_uaddll_overflow:
2314 case Builtin::BI__builtin_usub_overflow:
2315 case Builtin::BI__builtin_usubl_overflow:
2316 case Builtin::BI__builtin_usubll_overflow:
2317 case Builtin::BI__builtin_umul_overflow:
2318 case Builtin::BI__builtin_umull_overflow:
2319 case Builtin::BI__builtin_umulll_overflow:
2320 case Builtin::BI__builtin_sadd_overflow:
2321 case Builtin::BI__builtin_saddl_overflow:
2322 case Builtin::BI__builtin_saddll_overflow:
2323 case Builtin::BI__builtin_ssub_overflow:
2324 case Builtin::BI__builtin_ssubl_overflow:
2325 case Builtin::BI__builtin_ssubll_overflow:
2326 case Builtin::BI__builtin_smul_overflow:
2327 case Builtin::BI__builtin_smull_overflow:
2328 case Builtin::BI__builtin_smulll_overflow: {
2329
2330 // We translate all of these builtins directly to the relevant llvm IR node.
2331
2332 // Scalarize our inputs.
2333 llvm::Value *X = EmitScalarExpr(E->getArg(0));
2334 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00002335 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2));
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002336
2337 // Decide which of the overflow intrinsics we are lowering to:
2338 llvm::Intrinsic::ID IntrinsicId;
2339 switch (BuiltinID) {
John McCall03107a42015-10-29 20:48:01 +00002340 default: llvm_unreachable("Unknown overflow builtin id.");
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002341 case Builtin::BI__builtin_uadd_overflow:
2342 case Builtin::BI__builtin_uaddl_overflow:
2343 case Builtin::BI__builtin_uaddll_overflow:
2344 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2345 break;
2346 case Builtin::BI__builtin_usub_overflow:
2347 case Builtin::BI__builtin_usubl_overflow:
2348 case Builtin::BI__builtin_usubll_overflow:
2349 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2350 break;
2351 case Builtin::BI__builtin_umul_overflow:
2352 case Builtin::BI__builtin_umull_overflow:
2353 case Builtin::BI__builtin_umulll_overflow:
2354 IntrinsicId = llvm::Intrinsic::umul_with_overflow;
2355 break;
2356 case Builtin::BI__builtin_sadd_overflow:
2357 case Builtin::BI__builtin_saddl_overflow:
2358 case Builtin::BI__builtin_saddll_overflow:
2359 IntrinsicId = llvm::Intrinsic::sadd_with_overflow;
2360 break;
2361 case Builtin::BI__builtin_ssub_overflow:
2362 case Builtin::BI__builtin_ssubl_overflow:
2363 case Builtin::BI__builtin_ssubll_overflow:
2364 IntrinsicId = llvm::Intrinsic::ssub_with_overflow;
2365 break;
2366 case Builtin::BI__builtin_smul_overflow:
2367 case Builtin::BI__builtin_smull_overflow:
2368 case Builtin::BI__builtin_smulll_overflow:
2369 IntrinsicId = llvm::Intrinsic::smul_with_overflow;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00002370 break;
2371 }
2372
2373
2374 llvm::Value *Carry;
2375 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry);
2376 Builder.CreateStore(Sum, SumOutPtr);
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002377
2378 return RValue::get(Carry);
2379 }
Richard Smith6cbd65d2013-07-11 02:27:57 +00002380 case Builtin::BI__builtin_addressof:
John McCall7f416cc2015-09-08 08:05:57 +00002381 return RValue::get(EmitLValue(E->getArg(0)).getPointer());
Richard Smith760520b2014-06-03 23:27:44 +00002382 case Builtin::BI__builtin_operator_new:
2383 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2384 E->getArg(0), false);
2385 case Builtin::BI__builtin_operator_delete:
2386 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2387 E->getArg(0), true);
Nico Weber636fc092012-10-13 22:30:41 +00002388 case Builtin::BI__noop:
Reid Klecknered5d4ad2014-07-11 20:22:55 +00002389 // __noop always evaluates to an integer literal zero.
2390 return RValue::get(ConstantInt::get(IntTy, 0));
Peter Collingbournef7706832014-12-12 23:41:25 +00002391 case Builtin::BI__builtin_call_with_static_chain: {
2392 const CallExpr *Call = cast<CallExpr>(E->getArg(0));
2393 const Expr *Chain = E->getArg(1);
2394 return EmitCall(Call->getCallee()->getType(),
John McCallb92ab1a2016-10-26 23:46:34 +00002395 EmitCallee(Call->getCallee()), Call, ReturnValue,
2396 EmitScalarExpr(Chain));
Peter Collingbournef7706832014-12-12 23:41:25 +00002397 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002398 case Builtin::BI_InterlockedExchange8:
2399 case Builtin::BI_InterlockedExchange16:
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002400 case Builtin::BI_InterlockedExchange:
2401 case Builtin::BI_InterlockedExchangePointer:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002402 return RValue::get(
2403 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E));
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002404 case Builtin::BI_InterlockedCompareExchangePointer: {
2405 llvm::Type *RTy;
2406 llvm::IntegerType *IntType =
2407 IntegerType::get(getLLVMContext(),
2408 getContext().getTypeSize(E->getType()));
2409 llvm::Type *IntPtrType = IntType->getPointerTo();
2410
2411 llvm::Value *Destination =
2412 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType);
2413
2414 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
2415 RTy = Exchange->getType();
2416 Exchange = Builder.CreatePtrToInt(Exchange, IntType);
2417
2418 llvm::Value *Comparand =
2419 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
2420
JF Bastien92f4ef12016-04-06 17:26:42 +00002421 auto Result =
2422 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,
2423 AtomicOrdering::SequentiallyConsistent,
2424 AtomicOrdering::SequentiallyConsistent);
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002425 Result->setVolatile(true);
2426
2427 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
2428 0),
2429 RTy));
2430 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002431 case Builtin::BI_InterlockedCompareExchange8:
2432 case Builtin::BI_InterlockedCompareExchange16:
2433 case Builtin::BI_InterlockedCompareExchange:
2434 case Builtin::BI_InterlockedCompareExchange64: {
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002435 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg(
2436 EmitScalarExpr(E->getArg(0)),
2437 EmitScalarExpr(E->getArg(2)),
2438 EmitScalarExpr(E->getArg(1)),
JF Bastien92f4ef12016-04-06 17:26:42 +00002439 AtomicOrdering::SequentiallyConsistent,
2440 AtomicOrdering::SequentiallyConsistent);
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002441 CXI->setVolatile(true);
Tim Northoverb49b04b2014-06-13 14:24:59 +00002442 return RValue::get(Builder.CreateExtractValue(CXI, 0));
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002443 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002444 case Builtin::BI_InterlockedIncrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002445 case Builtin::BI_InterlockedIncrement:
2446 return RValue::get(
2447 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002448 case Builtin::BI_InterlockedDecrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002449 case Builtin::BI_InterlockedDecrement:
2450 return RValue::get(
2451 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002452 case Builtin::BI_InterlockedAnd8:
2453 case Builtin::BI_InterlockedAnd16:
2454 case Builtin::BI_InterlockedAnd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002455 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002456 case Builtin::BI_InterlockedExchangeAdd8:
2457 case Builtin::BI_InterlockedExchangeAdd16:
2458 case Builtin::BI_InterlockedExchangeAdd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002459 return RValue::get(
2460 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002461 case Builtin::BI_InterlockedExchangeSub8:
2462 case Builtin::BI_InterlockedExchangeSub16:
2463 case Builtin::BI_InterlockedExchangeSub:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002464 return RValue::get(
2465 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002466 case Builtin::BI_InterlockedOr8:
2467 case Builtin::BI_InterlockedOr16:
2468 case Builtin::BI_InterlockedOr:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002469 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002470 case Builtin::BI_InterlockedXor8:
2471 case Builtin::BI_InterlockedXor16:
2472 case Builtin::BI_InterlockedXor:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002473 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E));
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002474 case Builtin::BI_interlockedbittestandset:
2475 return RValue::get(
2476 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E));
Reid Kleckner1d59f992015-01-22 01:36:17 +00002477
2478 case Builtin::BI__exception_code:
2479 case Builtin::BI_exception_code:
2480 return RValue::get(EmitSEHExceptionCode());
2481 case Builtin::BI__exception_info:
2482 case Builtin::BI_exception_info:
2483 return RValue::get(EmitSEHExceptionInfo());
Reid Kleckneraca01db2015-02-04 22:37:07 +00002484 case Builtin::BI__abnormal_termination:
2485 case Builtin::BI_abnormal_termination:
2486 return RValue::get(EmitSEHAbnormalTermination());
David Majnemer310e3a82015-01-29 09:29:21 +00002487 case Builtin::BI_setjmpex: {
2488 if (getTarget().getTriple().isOSMSVCRT()) {
2489 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
Reid Klecknerde864822017-03-21 16:57:30 +00002490 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2491 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2492 llvm::Attribute::ReturnsTwice);
David Majnemer310e3a82015-01-29 09:29:21 +00002493 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction(
2494 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002495 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true);
David Majnemerc403a1c2015-03-20 17:03:35 +00002496 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2497 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002498 llvm::Value *FrameAddr =
2499 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2500 ConstantInt::get(Int32Ty, 0));
2501 llvm::Value *Args[] = {Buf, FrameAddr};
2502 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args);
2503 CS.setAttributes(ReturnsTwiceAttr);
2504 return RValue::get(CS.getInstruction());
2505 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002506 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002507 }
2508 case Builtin::BI_setjmp: {
2509 if (getTarget().getTriple().isOSMSVCRT()) {
Reid Klecknerde864822017-03-21 16:57:30 +00002510 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2511 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2512 llvm::Attribute::ReturnsTwice);
David Majnemerc403a1c2015-03-20 17:03:35 +00002513 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2514 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002515 llvm::CallSite CS;
2516 if (getTarget().getTriple().getArch() == llvm::Triple::x86) {
2517 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy};
2518 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction(
2519 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002520 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002521 llvm::Value *Count = ConstantInt::get(IntTy, 0);
2522 llvm::Value *Args[] = {Buf, Count};
2523 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args);
2524 } else {
2525 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
2526 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction(
2527 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002528 "_setjmp", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002529 llvm::Value *FrameAddr =
2530 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2531 ConstantInt::get(Int32Ty, 0));
2532 llvm::Value *Args[] = {Buf, FrameAddr};
2533 CS = EmitRuntimeCallOrInvoke(SetJmp, Args);
2534 }
2535 CS.setAttributes(ReturnsTwiceAttr);
2536 return RValue::get(CS.getInstruction());
2537 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002538 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002539 }
David Majnemerba3e5ec2015-03-13 18:26:17 +00002540
2541 case Builtin::BI__GetExceptionInfo: {
2542 if (llvm::GlobalVariable *GV =
2543 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType()))
2544 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy));
2545 break;
2546 }
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002547
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002548 case Builtin::BI__fastfail:
Reid Kleckner04f9f912017-02-09 18:31:06 +00002549 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E));
Reid Kleckner04f9f912017-02-09 18:31:06 +00002550
Gor Nishanov97e3b6d2016-10-03 22:44:48 +00002551 case Builtin::BI__builtin_coro_size: {
2552 auto & Context = getContext();
2553 auto SizeTy = Context.getSizeType();
2554 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
2555 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T);
2556 return RValue::get(Builder.CreateCall(F));
2557 }
2558
2559 case Builtin::BI__builtin_coro_id:
2560 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id);
2561 case Builtin::BI__builtin_coro_promise:
2562 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise);
2563 case Builtin::BI__builtin_coro_resume:
2564 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume);
2565 case Builtin::BI__builtin_coro_frame:
2566 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame);
2567 case Builtin::BI__builtin_coro_free:
2568 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free);
2569 case Builtin::BI__builtin_coro_destroy:
2570 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy);
2571 case Builtin::BI__builtin_coro_done:
2572 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done);
2573 case Builtin::BI__builtin_coro_alloc:
2574 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc);
2575 case Builtin::BI__builtin_coro_begin:
2576 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin);
2577 case Builtin::BI__builtin_coro_end:
2578 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end);
2579 case Builtin::BI__builtin_coro_suspend:
2580 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend);
2581 case Builtin::BI__builtin_coro_param:
2582 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param);
2583
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002584 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions
2585 case Builtin::BIread_pipe:
2586 case Builtin::BIwrite_pipe: {
2587 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2588 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002589 CGOpenCLRuntime OpenCLRT(CGM);
2590 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2591 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002592
2593 // Type of the generic packet parameter.
2594 unsigned GenericAS =
2595 getContext().getTargetAddressSpace(LangAS::opencl_generic);
2596 llvm::Type *I8PTy = llvm::PointerType::get(
2597 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS);
2598
2599 // Testing which overloaded version we should generate the call for.
2600 if (2U == E->getNumArgs()) {
2601 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2"
2602 : "__write_pipe_2";
2603 // Creating a generic function type to be able to call with any builtin or
2604 // user defined type.
Alexey Bader465c1892016-09-23 14:20:00 +00002605 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002606 llvm::FunctionType *FTy = llvm::FunctionType::get(
2607 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2608 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002609 return RValue::get(
2610 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2611 {Arg0, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002612 } else {
2613 assert(4 == E->getNumArgs() &&
2614 "Illegal number of parameters to pipe function");
2615 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4"
2616 : "__write_pipe_4";
2617
Alexey Bader465c1892016-09-23 14:20:00 +00002618 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy,
2619 Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002620 Value *Arg2 = EmitScalarExpr(E->getArg(2)),
2621 *Arg3 = EmitScalarExpr(E->getArg(3));
2622 llvm::FunctionType *FTy = llvm::FunctionType::get(
2623 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2624 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy);
2625 // We know the third argument is an integer type, but we may need to cast
2626 // it to i32.
2627 if (Arg2->getType() != Int32Ty)
2628 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty);
2629 return RValue::get(Builder.CreateCall(
Alexey Bader465c1892016-09-23 14:20:00 +00002630 CGM.CreateRuntimeFunction(FTy, Name),
2631 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002632 }
2633 }
2634 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write
2635 // functions
2636 case Builtin::BIreserve_read_pipe:
2637 case Builtin::BIreserve_write_pipe:
2638 case Builtin::BIwork_group_reserve_read_pipe:
2639 case Builtin::BIwork_group_reserve_write_pipe:
2640 case Builtin::BIsub_group_reserve_read_pipe:
2641 case Builtin::BIsub_group_reserve_write_pipe: {
2642 // Composing the mangled name for the function.
2643 const char *Name;
2644 if (BuiltinID == Builtin::BIreserve_read_pipe)
2645 Name = "__reserve_read_pipe";
2646 else if (BuiltinID == Builtin::BIreserve_write_pipe)
2647 Name = "__reserve_write_pipe";
2648 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe)
2649 Name = "__work_group_reserve_read_pipe";
2650 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe)
2651 Name = "__work_group_reserve_write_pipe";
2652 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe)
2653 Name = "__sub_group_reserve_read_pipe";
2654 else
2655 Name = "__sub_group_reserve_write_pipe";
2656
2657 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2658 *Arg1 = EmitScalarExpr(E->getArg(1));
2659 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002660 CGOpenCLRuntime OpenCLRT(CGM);
2661 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2662 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002663
2664 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002665 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002666 llvm::FunctionType *FTy = llvm::FunctionType::get(
2667 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2668 // We know the second argument is an integer type, but we may need to cast
2669 // it to i32.
2670 if (Arg1->getType() != Int32Ty)
2671 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty);
2672 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002673 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2674 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002675 }
Anastasia Stulova7f8d6dc2016-07-04 16:07:18 +00002676 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002677 // functions
2678 case Builtin::BIcommit_read_pipe:
2679 case Builtin::BIcommit_write_pipe:
2680 case Builtin::BIwork_group_commit_read_pipe:
2681 case Builtin::BIwork_group_commit_write_pipe:
2682 case Builtin::BIsub_group_commit_read_pipe:
2683 case Builtin::BIsub_group_commit_write_pipe: {
2684 const char *Name;
2685 if (BuiltinID == Builtin::BIcommit_read_pipe)
2686 Name = "__commit_read_pipe";
2687 else if (BuiltinID == Builtin::BIcommit_write_pipe)
2688 Name = "__commit_write_pipe";
2689 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe)
2690 Name = "__work_group_commit_read_pipe";
2691 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe)
2692 Name = "__work_group_commit_write_pipe";
2693 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe)
2694 Name = "__sub_group_commit_read_pipe";
2695 else
2696 Name = "__sub_group_commit_write_pipe";
2697
2698 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2699 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002700 CGOpenCLRuntime OpenCLRT(CGM);
2701 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2702 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002703
2704 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002705 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002706 llvm::FunctionType *FTy =
2707 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
2708 llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2709
2710 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002711 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2712 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002713 }
2714 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions
2715 case Builtin::BIget_pipe_num_packets:
2716 case Builtin::BIget_pipe_max_packets: {
2717 const char *Name;
2718 if (BuiltinID == Builtin::BIget_pipe_num_packets)
2719 Name = "__get_pipe_num_packets";
2720 else
2721 Name = "__get_pipe_max_packets";
2722
2723 // Building the generic function prototype.
2724 Value *Arg0 = EmitScalarExpr(E->getArg(0));
Alexey Bader465c1892016-09-23 14:20:00 +00002725 CGOpenCLRuntime OpenCLRT(CGM);
2726 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2727 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
2728 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002729 llvm::FunctionType *FTy = llvm::FunctionType::get(
2730 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2731
Alexey Bader465c1892016-09-23 14:20:00 +00002732 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2733 {Arg0, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002734 }
2735
Yaxun Liuf7449a12016-05-20 19:54:38 +00002736 // OpenCL v2.0 s6.13.9 - Address space qualifier functions.
2737 case Builtin::BIto_global:
2738 case Builtin::BIto_local:
2739 case Builtin::BIto_private: {
2740 auto Arg0 = EmitScalarExpr(E->getArg(0));
2741 auto NewArgT = llvm::PointerType::get(Int8Ty,
2742 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
2743 auto NewRetT = llvm::PointerType::get(Int8Ty,
2744 CGM.getContext().getTargetAddressSpace(
2745 E->getType()->getPointeeType().getAddressSpace()));
2746 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false);
2747 llvm::Value *NewArg;
2748 if (Arg0->getType()->getPointerAddressSpace() !=
2749 NewArgT->getPointerAddressSpace())
2750 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT);
2751 else
2752 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT);
Alexey Baderd81623262016-08-04 18:06:27 +00002753 auto NewName = std::string("__") + E->getDirectCallee()->getName().str();
2754 auto NewCall =
2755 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg});
Yaxun Liuf7449a12016-05-20 19:54:38 +00002756 return RValue::get(Builder.CreateBitOrPointerCast(NewCall,
2757 ConvertType(E->getType())));
2758 }
2759
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002760 // OpenCL v2.0, s6.13.17 - Enqueue kernel function.
2761 // It contains four different overload formats specified in Table 6.13.17.1.
2762 case Builtin::BIenqueue_kernel: {
2763 StringRef Name; // Generated function call name
2764 unsigned NumArgs = E->getNumArgs();
2765
2766 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002767 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2768 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002769
2770 llvm::Value *Queue = EmitScalarExpr(E->getArg(0));
2771 llvm::Value *Flags = EmitScalarExpr(E->getArg(1));
Anastasia Stulova58984e72017-02-16 12:27:47 +00002772 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2));
2773 llvm::Value *Range = NDRangeL.getAddress().getPointer();
2774 llvm::Type *RangeTy = NDRangeL.getAddress().getType();
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002775
2776 if (NumArgs == 4) {
2777 // The most basic form of the call with parameters:
2778 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void)
2779 Name = "__enqueue_kernel_basic";
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002780 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002781 llvm::FunctionType *FTy = llvm::FunctionType::get(
2782 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys, 4), false);
2783
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002784 llvm::Value *Block = Builder.CreatePointerCast(
2785 EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002786
Anastasia Stulova58984e72017-02-16 12:27:47 +00002787 AttrBuilder B;
2788 B.addAttribute(Attribute::ByVal);
Reid Klecknerde864822017-03-21 16:57:30 +00002789 llvm::AttributeList ByValAttrSet =
2790 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B);
Anastasia Stulova58984e72017-02-16 12:27:47 +00002791
2792 auto RTCall =
2793 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet),
2794 {Queue, Flags, Range, Block});
2795 RTCall->setAttributes(ByValAttrSet);
2796 return RValue::get(RTCall);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002797 }
2798 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature");
2799
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002800 // Create a temporary array to hold the sizes of local pointer arguments
2801 // for the block. \p First is the position of the first size argument.
2802 auto CreateArrayForSizeVar = [=](unsigned First) {
2803 auto *AT = llvm::ArrayType::get(SizeTy, NumArgs - First);
2804 auto *Arr = Builder.CreateAlloca(AT);
2805 llvm::Value *Ptr;
2806 // Each of the following arguments specifies the size of the corresponding
2807 // argument passed to the enqueued block.
2808 auto *Zero = llvm::ConstantInt::get(IntTy, 0);
2809 for (unsigned I = First; I < NumArgs; ++I) {
2810 auto *Index = llvm::ConstantInt::get(IntTy, I - First);
2811 auto *GEP = Builder.CreateGEP(Arr, {Zero, Index});
2812 if (I == First)
2813 Ptr = GEP;
2814 auto *V =
2815 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy);
2816 Builder.CreateAlignedStore(
2817 V, GEP, CGM.getDataLayout().getPrefTypeAlignment(SizeTy));
2818 }
2819 return Ptr;
2820 };
2821
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002822 // Could have events and/or vaargs.
2823 if (E->getArg(3)->getType()->isBlockPointerType()) {
2824 // No events passed, but has variadic arguments.
2825 Name = "__enqueue_kernel_vaargs";
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002826 auto *Block = Builder.CreatePointerCast(EmitScalarExpr(E->getArg(3)),
2827 GenericVoidPtrTy);
2828 auto *PtrToSizeArray = CreateArrayForSizeVar(4);
2829
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002830 // Create a vector of the arguments, as well as a constant value to
2831 // express to the runtime the number of variadic arguments.
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002832 std::vector<llvm::Value *> Args = {Queue,
2833 Flags,
2834 Range,
2835 Block,
2836 ConstantInt::get(IntTy, NumArgs - 4),
2837 PtrToSizeArray};
2838 std::vector<llvm::Type *> ArgTys = {QueueTy, IntTy,
2839 RangeTy, GenericVoidPtrTy,
2840 IntTy, PtrToSizeArray->getType()};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002841
2842 llvm::FunctionType *FTy = llvm::FunctionType::get(
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002843 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002844 return RValue::get(
2845 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2846 llvm::ArrayRef<llvm::Value *>(Args)));
2847 }
2848 // Any calls now have event arguments passed.
2849 if (NumArgs >= 7) {
2850 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy);
Anastasia Stulova2b461202016-11-14 15:34:01 +00002851 llvm::Type *EventPtrTy = EventTy->getPointerTo(
2852 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002853
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002854 llvm::Value *NumEvents =
2855 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002856 llvm::Value *EventList =
2857 E->getArg(4)->getType()->isArrayType()
2858 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer()
2859 : EmitScalarExpr(E->getArg(4));
2860 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5));
Anastasia Stulova2b461202016-11-14 15:34:01 +00002861 // Convert to generic address space.
2862 EventList = Builder.CreatePointerCast(EventList, EventPtrTy);
2863 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002864 llvm::Value *Block = Builder.CreatePointerCast(
2865 EmitScalarExpr(E->getArg(6)), GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002866
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002867 std::vector<llvm::Type *> ArgTys = {
2868 QueueTy, Int32Ty, RangeTy, Int32Ty,
2869 EventPtrTy, EventPtrTy, GenericVoidPtrTy};
Anastasia Stulova2b461202016-11-14 15:34:01 +00002870
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002871 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents,
2872 EventList, ClkEvent, Block};
2873
2874 if (NumArgs == 7) {
2875 // Has events but no variadics.
2876 Name = "__enqueue_kernel_basic_events";
2877 llvm::FunctionType *FTy = llvm::FunctionType::get(
2878 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2879 return RValue::get(
2880 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2881 llvm::ArrayRef<llvm::Value *>(Args)));
2882 }
2883 // Has event info and variadics
2884 // Pass the number of variadics to the runtime function too.
2885 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7));
2886 ArgTys.push_back(Int32Ty);
2887 Name = "__enqueue_kernel_events_vaargs";
2888
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002889 auto *PtrToSizeArray = CreateArrayForSizeVar(7);
2890 Args.push_back(PtrToSizeArray);
2891 ArgTys.push_back(PtrToSizeArray->getType());
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002892
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002893 llvm::FunctionType *FTy = llvm::FunctionType::get(
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002894 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002895 return RValue::get(
2896 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2897 llvm::ArrayRef<llvm::Value *>(Args)));
2898 }
Galina Kistanova0872d6c2017-06-03 06:30:46 +00002899 LLVM_FALLTHROUGH;
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002900 }
2901 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
2902 // parameter.
2903 case Builtin::BIget_kernel_work_group_size: {
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002904 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2905 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002906 Value *Arg = EmitScalarExpr(E->getArg(0));
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002907 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002908 return RValue::get(Builder.CreateCall(
2909 CGM.CreateRuntimeFunction(
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002910 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
2911 "__get_kernel_work_group_size_impl"),
2912 Arg));
2913 }
2914 case Builtin::BIget_kernel_preferred_work_group_size_multiple: {
2915 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2916 getContext().getTargetAddressSpace(LangAS::opencl_generic));
2917 Value *Arg = EmitScalarExpr(E->getArg(0));
2918 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
2919 return RValue::get(Builder.CreateCall(
2920 CGM.CreateRuntimeFunction(
2921 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002922 "__get_kernel_preferred_work_group_multiple_impl"),
2923 Arg));
2924 }
Joey Goulyfa76b492017-08-01 13:27:09 +00002925 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2926 case Builtin::BIget_kernel_sub_group_count_for_ndrange: {
2927 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2928 getContext().getTargetAddressSpace(LangAS::opencl_generic));
2929 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0));
2930 llvm::Value *NDRange = NDRangeL.getAddress().getPointer();
2931 Value *Block = EmitScalarExpr(E->getArg(1));
2932 Block = Builder.CreatePointerCast(Block, GenericVoidPtrTy);
2933 const char *Name =
2934 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange
2935 ? "__get_kernel_max_sub_group_size_for_ndrange_impl"
2936 : "__get_kernel_sub_group_count_for_ndrange_impl";
2937 return RValue::get(Builder.CreateCall(
2938 CGM.CreateRuntimeFunction(
2939 llvm::FunctionType::get(
2940 IntTy, {NDRange->getType(), GenericVoidPtrTy}, false),
2941 Name),
2942 {NDRange, Block}));
2943 }
Jan Vesely31ecb4b2017-09-07 19:39:10 +00002944
2945 case Builtin::BI__builtin_store_half:
2946 case Builtin::BI__builtin_store_halff: {
2947 Value *Val = EmitScalarExpr(E->getArg(0));
2948 Address Address = EmitPointerWithAlignment(E->getArg(1));
2949 Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy());
2950 return RValue::get(Builder.CreateStore(HalfVal, Address));
2951 }
2952 case Builtin::BI__builtin_load_half: {
2953 Address Address = EmitPointerWithAlignment(E->getArg(0));
2954 Value *HalfVal = Builder.CreateLoad(Address);
2955 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy()));
2956 }
2957 case Builtin::BI__builtin_load_halff: {
2958 Address Address = EmitPointerWithAlignment(E->getArg(0));
2959 Value *HalfVal = Builder.CreateLoad(Address);
2960 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy()));
2961 }
Justin Lebar3039a592016-01-23 21:28:14 +00002962 case Builtin::BIprintf:
Arpith Chacko Jacobcdda3daa2017-01-29 20:49:31 +00002963 if (getTarget().getTriple().isNVPTX())
2964 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue);
Matt Arsenault2d933982016-02-27 09:06:18 +00002965 break;
2966 case Builtin::BI__builtin_canonicalize:
2967 case Builtin::BI__builtin_canonicalizef:
2968 case Builtin::BI__builtin_canonicalizel:
2969 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize));
Marcin Koscielnickia46fade2016-06-16 13:41:54 +00002970
2971 case Builtin::BI__builtin_thread_pointer: {
2972 if (!getContext().getTargetInfo().isTLSSupported())
2973 CGM.ErrorUnsupported(E, "__builtin_thread_pointer");
2974 // Fall through - it's already mapped to the intrinsic by GCCBuiltin.
2975 break;
2976 }
Akira Hatanaka6b103bc2017-10-06 07:12:46 +00002977 case Builtin::BI__builtin_os_log_format:
2978 return emitBuiltinOSLogFormat(*E);
Mehdi Amini06d367c2016-10-24 20:39:34 +00002979
2980 case Builtin::BI__builtin_os_log_format_buffer_size: {
2981 analyze_os_log::OSLogBufferLayout Layout;
2982 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);
2983 return RValue::get(ConstantInt::get(ConvertType(E->getType()),
2984 Layout.size().getQuantity()));
2985 }
Dean Michael Berris42af6512017-05-09 00:45:40 +00002986
2987 case Builtin::BI__xray_customevent: {
2988 if (!ShouldXRayInstrumentFunction())
2989 return RValue::getIgnored();
2990 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
2991 if (XRayAttr->neverXRayInstrument())
2992 return RValue::getIgnored();
2993 }
2994 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
2995 auto FTy = F->getFunctionType();
2996 auto Arg0 = E->getArg(0);
2997 auto Arg0Val = EmitScalarExpr(Arg0);
2998 auto Arg0Ty = Arg0->getType();
2999 auto PTy0 = FTy->getParamType(0);
3000 if (PTy0 != Arg0Val->getType()) {
3001 if (Arg0Ty->isArrayType())
3002 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer();
3003 else
3004 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0);
3005 }
3006 auto Arg1 = EmitScalarExpr(E->getArg(1));
3007 auto PTy1 = FTy->getParamType(1);
3008 if (PTy1 != Arg1->getType())
3009 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
3010 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
3011 }
Martin Storsjo022e7822017-07-17 20:49:45 +00003012
3013 case Builtin::BI__builtin_ms_va_start:
3014 case Builtin::BI__builtin_ms_va_end:
3015 return RValue::get(
3016 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(),
3017 BuiltinID == Builtin::BI__builtin_ms_va_start));
3018
3019 case Builtin::BI__builtin_ms_va_copy: {
3020 // Lower this manually. We can't reliably determine whether or not any
3021 // given va_copy() is for a Win64 va_list from the calling convention
3022 // alone, because it's legal to do this from a System V ABI function.
3023 // With opaque pointer types, we won't have enough information in LLVM
3024 // IR to determine this from the argument types, either. Best to do it
3025 // now, while we have enough information.
3026 Address DestAddr = EmitMSVAListRef(E->getArg(0));
3027 Address SrcAddr = EmitMSVAListRef(E->getArg(1));
3028
3029 llvm::Type *BPP = Int8PtrPtrTy;
3030
3031 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"),
3032 DestAddr.getAlignment());
3033 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"),
3034 SrcAddr.getAlignment());
3035
3036 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val");
3037 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr));
3038 }
Nate Begeman6c591322008-05-15 07:38:03 +00003039 }
Mike Stump11289f42009-09-09 15:08:12 +00003040
John McCall30e4efd2011-09-13 23:05:03 +00003041 // If this is an alias for a lib function (e.g. __builtin_sin), emit
3042 // the call using the normal call path, but using the unmangled
3043 // version of the function name.
3044 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
3045 return emitLibraryCall(*this, FD, E,
3046 CGM.getBuiltinLibFunction(FD, BuiltinID));
Jim Grosbachd3608f42012-09-21 00:18:27 +00003047
John McCall30e4efd2011-09-13 23:05:03 +00003048 // If this is a predefined lib function (e.g. malloc), emit the call
3049 // using exactly the normal call path.
3050 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
John McCallb92ab1a2016-10-26 23:46:34 +00003051 return emitLibraryCall(*this, FD, E,
3052 cast<llvm::Constant>(EmitScalarExpr(E->getCallee())));
Mike Stump11289f42009-09-09 15:08:12 +00003053
Eric Christopher15709992015-10-15 23:47:11 +00003054 // Check that a call to a target specific builtin has the correct target
3055 // features.
3056 // This is down here to avoid non-target specific builtins, however, if
3057 // generic builtins start to require generic target features then we
3058 // can move this up to the beginning of the function.
Eric Christopherc7e79db2015-11-12 00:44:04 +00003059 checkTargetFeatures(E, FD);
Eric Christopher15709992015-10-15 23:47:11 +00003060
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003061 // See if we have a target specific intrinsic.
Mehdi Amini7186a432016-10-11 19:04:24 +00003062 const char *Name = getContext().BuiltinInfo.getName(BuiltinID);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003063 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
Mehdi Aminib7fb1242016-10-01 01:16:22 +00003064 StringRef Prefix =
3065 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
3066 if (!Prefix.empty()) {
3067 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00003068 // NOTE we dont need to perform a compatibility flag check here since the
3069 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
3070 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
3071 if (IntrinsicID == Intrinsic::not_intrinsic)
Mehdi Aminib7fb1242016-10-01 01:16:22 +00003072 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00003073 }
Mike Stump11289f42009-09-09 15:08:12 +00003074
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003075 if (IntrinsicID != Intrinsic::not_intrinsic) {
3076 SmallVector<Value*, 16> Args;
Mike Stump11289f42009-09-09 15:08:12 +00003077
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003078 // Find out if any arguments are required to be integer constant
3079 // expressions.
3080 unsigned ICEArguments = 0;
3081 ASTContext::GetBuiltinTypeError Error;
3082 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
3083 assert(Error == ASTContext::GE_None && "Should not codegen an error");
3084
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003085 Function *F = CGM.getIntrinsic(IntrinsicID);
Chris Lattner2192fe52011-07-18 04:24:23 +00003086 llvm::FunctionType *FTy = F->getFunctionType();
Mike Stump11289f42009-09-09 15:08:12 +00003087
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003088 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003089 Value *ArgValue;
3090 // If this is a normal argument, just emit it as a scalar.
3091 if ((ICEArguments & (1 << i)) == 0) {
3092 ArgValue = EmitScalarExpr(E->getArg(i));
3093 } else {
Jim Grosbachd3608f42012-09-21 00:18:27 +00003094 // If this is required to be a constant, constant fold it so that we
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003095 // know that the generated intrinsic gets a ConstantInt.
3096 llvm::APSInt Result;
3097 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext());
3098 assert(IsConst && "Constant arg isn't actually constant?");
3099 (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00003100 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result);
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003101 }
Mike Stump11289f42009-09-09 15:08:12 +00003102
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003103 // If the intrinsic arg type is different from the builtin arg type
3104 // we need to do a bit cast.
Chris Lattner2192fe52011-07-18 04:24:23 +00003105 llvm::Type *PTy = FTy->getParamType(i);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003106 if (PTy != ArgValue->getType()) {
3107 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
3108 "Must be able to losslessly bit cast to param");
3109 ArgValue = Builder.CreateBitCast(ArgValue, PTy);
3110 }
Mike Stump11289f42009-09-09 15:08:12 +00003111
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003112 Args.push_back(ArgValue);
3113 }
Mike Stump11289f42009-09-09 15:08:12 +00003114
Jay Foad5bd375a2011-07-15 08:37:34 +00003115 Value *V = Builder.CreateCall(F, Args);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003116 QualType BuiltinRetType = E->getType();
Mike Stump11289f42009-09-09 15:08:12 +00003117
Chris Lattnerece04092012-02-07 00:39:47 +00003118 llvm::Type *RetTy = VoidTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00003119 if (!BuiltinRetType->isVoidType())
Chris Lattnerece04092012-02-07 00:39:47 +00003120 RetTy = ConvertType(BuiltinRetType);
Mike Stump11289f42009-09-09 15:08:12 +00003121
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003122 if (RetTy != V->getType()) {
3123 assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
3124 "Must be able to losslessly bit cast result type");
3125 V = Builder.CreateBitCast(V, RetTy);
3126 }
Mike Stump11289f42009-09-09 15:08:12 +00003127
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003128 return RValue::get(V);
3129 }
Mike Stump11289f42009-09-09 15:08:12 +00003130
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003131 // See if we have a target specific builtin that needs to be lowered.
Daniel Dunbareca513d2008-10-10 00:24:54 +00003132 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003133 return RValue::get(V);
Mike Stump11289f42009-09-09 15:08:12 +00003134
Daniel Dunbara7c8cf62008-08-16 00:56:44 +00003135 ErrorUnsupported(E, "builtin function");
Mike Stump11289f42009-09-09 15:08:12 +00003136
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003137 // Unknown builtin, for now just dump it out and return undef.
John McCall47fb9502013-03-07 21:37:08 +00003138 return GetUndefRValue(E->getType());
Mike Stump11289f42009-09-09 15:08:12 +00003139}
Anders Carlsson895af082007-12-09 23:17:02 +00003140
Artem Belevichb5bc9232015-09-22 17:23:22 +00003141static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
3142 unsigned BuiltinID, const CallExpr *E,
3143 llvm::Triple::ArchType Arch) {
3144 switch (Arch) {
Chris Lattner5cc15e02010-03-03 19:03:45 +00003145 case llvm::Triple::arm:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003146 case llvm::Triple::armeb:
Chris Lattner5cc15e02010-03-03 19:03:45 +00003147 case llvm::Triple::thumb:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003148 case llvm::Triple::thumbeb:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003149 return CGF->EmitARMBuiltinExpr(BuiltinID, E);
Tim Northover25e8a672014-05-24 12:51:25 +00003150 case llvm::Triple::aarch64:
3151 case llvm::Triple::aarch64_be:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003152 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003153 case llvm::Triple::x86:
3154 case llvm::Triple::x86_64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003155 return CGF->EmitX86BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003156 case llvm::Triple::ppc:
3157 case llvm::Triple::ppc64:
Bill Schmidt778d3872013-07-26 01:36:11 +00003158 case llvm::Triple::ppc64le:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003159 return CGF->EmitPPCBuiltinExpr(BuiltinID, E);
Matt Arsenault56f008d2014-06-24 20:45:01 +00003160 case llvm::Triple::r600:
Tom Stellardd8e38a32015-01-06 20:34:47 +00003161 case llvm::Triple::amdgcn:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003162 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00003163 case llvm::Triple::systemz:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003164 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00003165 case llvm::Triple::nvptx:
3166 case llvm::Triple::nvptx64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003167 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E);
Dan Gohmanc2853072015-09-03 22:51:53 +00003168 case llvm::Triple::wasm32:
3169 case llvm::Triple::wasm64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003170 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003171 default:
Craig Topper8a13c412014-05-21 05:09:00 +00003172 return nullptr;
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003173 }
Daniel Dunbareca513d2008-10-10 00:24:54 +00003174}
3175
Artem Belevichb5bc9232015-09-22 17:23:22 +00003176Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
3177 const CallExpr *E) {
3178 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3179 assert(getContext().getAuxTargetInfo() && "Missing aux target info");
3180 return EmitTargetArchBuiltinExpr(
3181 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E,
3182 getContext().getAuxTargetInfo()->getTriple().getArch());
3183 }
3184
3185 return EmitTargetArchBuiltinExpr(this, BuiltinID, E,
3186 getTarget().getTriple().getArch());
3187}
3188
Chris Lattnerece04092012-02-07 00:39:47 +00003189static llvm::VectorType *GetNeonType(CodeGenFunction *CGF,
Jiangning Liu036f16d2013-09-24 02:48:06 +00003190 NeonTypeFlags TypeFlags,
3191 bool V1Ty=false) {
NAKAMURA Takumidabda6b2011-11-08 03:27:04 +00003192 int IsQuad = TypeFlags.isQuad();
3193 switch (TypeFlags.getEltType()) {
Bob Wilson98bc98c2011-11-08 01:16:11 +00003194 case NeonTypeFlags::Int8:
3195 case NeonTypeFlags::Poly8:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003196 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003197 case NeonTypeFlags::Int16:
3198 case NeonTypeFlags::Poly16:
Abderrazek Zaafranif10ca932017-06-20 18:54:57 +00003199 case NeonTypeFlags::Float16:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003200 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003201 case NeonTypeFlags::Int32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003202 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003203 case NeonTypeFlags::Int64:
Kevin Qincaac85e2013-11-14 03:29:16 +00003204 case NeonTypeFlags::Poly64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003205 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad));
Kevin Qinfb79d7f2013-12-10 06:49:01 +00003206 case NeonTypeFlags::Poly128:
3207 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm.
3208 // There is a lot of i128 and f128 API missing.
3209 // so we use v16i8 to represent poly128 and get pattern matched.
3210 return llvm::VectorType::get(CGF->Int8Ty, 16);
Bob Wilson98bc98c2011-11-08 01:16:11 +00003211 case NeonTypeFlags::Float32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003212 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad));
Tim Northover2fe823a2013-08-01 09:23:19 +00003213 case NeonTypeFlags::Float64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003214 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad));
David Blaikief47fa302012-01-17 02:30:50 +00003215 }
Benjamin Kramer9b1dfe82013-09-26 16:36:08 +00003216 llvm_unreachable("Unknown vector element type!");
Nate Begeman5968eb22010-06-07 16:01:56 +00003217}
3218
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003219static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF,
3220 NeonTypeFlags IntTypeFlags) {
3221 int IsQuad = IntTypeFlags.isQuad();
3222 switch (IntTypeFlags.getEltType()) {
3223 case NeonTypeFlags::Int32:
3224 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad));
3225 case NeonTypeFlags::Int64:
3226 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad));
3227 default:
3228 llvm_unreachable("Type can't be converted to floating-point!");
3229 }
3230}
3231
Bob Wilson210f6dd2010-12-07 22:40:02 +00003232Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) {
Craig Topperf2f1a092016-07-08 02:17:35 +00003233 unsigned nElts = V->getType()->getVectorNumElements();
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003234 Value* SV = llvm::ConstantVector::getSplat(nElts, C);
Nate Begeman4a04b462010-06-10 00:17:56 +00003235 return Builder.CreateShuffleVector(V, V, SV, "lane");
3236}
3237
Nate Begemanae6b1d82010-06-08 06:03:01 +00003238Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops,
Bob Wilson482afae2010-12-08 22:37:56 +00003239 const char *name,
Nate Begeman91e1fea2010-06-14 05:21:25 +00003240 unsigned shift, bool rightshift) {
Nate Begemanae6b1d82010-06-08 06:03:01 +00003241 unsigned j = 0;
3242 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3243 ai != ae; ++ai, ++j)
Nate Begeman91e1fea2010-06-14 05:21:25 +00003244 if (shift > 0 && shift == j)
3245 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift);
3246 else
3247 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003248
Jay Foad5bd375a2011-07-15 08:37:34 +00003249 return Builder.CreateCall(F, Ops, name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003250}
3251
Jim Grosbachd3608f42012-09-21 00:18:27 +00003252Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty,
Nate Begeman8ed060b2010-06-11 22:57:12 +00003253 bool neg) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003254 int SV = cast<ConstantInt>(V)->getSExtValue();
Benjamin Kramerc385a802015-07-28 15:40:11 +00003255 return ConstantInt::get(Ty, neg ? -SV : SV);
Nate Begeman8ed060b2010-06-11 22:57:12 +00003256}
3257
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003258// \brief Right-shift a vector by a constant.
3259Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift,
3260 llvm::Type *Ty, bool usgn,
3261 const char *name) {
3262 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
3263
3264 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue();
3265 int EltSize = VTy->getScalarSizeInBits();
3266
3267 Vec = Builder.CreateBitCast(Vec, Ty);
3268
3269 // lshr/ashr are undefined when the shift amount is equal to the vector
3270 // element size.
3271 if (ShiftAmt == EltSize) {
3272 if (usgn) {
3273 // Right-shifting an unsigned value by its size yields 0.
Benjamin Kramerc385a802015-07-28 15:40:11 +00003274 return llvm::ConstantAggregateZero::get(VTy);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003275 } else {
3276 // Right-shifting a signed value by its size is equivalent
3277 // to a shift of size-1.
3278 --ShiftAmt;
3279 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt);
3280 }
3281 }
3282
3283 Shift = EmitNeonShiftVector(Shift, Ty, false);
3284 if (usgn)
3285 return Builder.CreateLShr(Vec, Shift, name);
3286 else
3287 return Builder.CreateAShr(Vec, Shift, name);
3288}
3289
Tim Northover2d837962014-02-21 11:57:20 +00003290enum {
3291 AddRetType = (1 << 0),
3292 Add1ArgType = (1 << 1),
3293 Add2ArgTypes = (1 << 2),
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003294
Tim Northover2d837962014-02-21 11:57:20 +00003295 VectorizeRetType = (1 << 3),
3296 VectorizeArgTypes = (1 << 4),
3297
3298 InventFloatType = (1 << 5),
Tim Northover8fe03d62014-02-21 11:57:24 +00003299 UnsignedAlts = (1 << 6),
Tim Northover2d837962014-02-21 11:57:20 +00003300
Tim Northovera2ee4332014-03-29 15:09:45 +00003301 Use64BitVectors = (1 << 7),
3302 Use128BitVectors = (1 << 8),
3303
Tim Northover2d837962014-02-21 11:57:20 +00003304 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes,
3305 VectorRet = AddRetType | VectorizeRetType,
3306 VectorRetGetArgs01 =
3307 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes,
3308 FpCmpzModifiers =
Tim Northovera0c95eb2014-02-21 12:16:59 +00003309 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003310};
3311
Benjamin Kramere003ca22015-10-28 13:54:16 +00003312namespace {
3313struct NeonIntrinsicInfo {
Ben Craigcd7e9f12015-12-14 21:54:11 +00003314 const char *NameHint;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003315 unsigned BuiltinID;
3316 unsigned LLVMIntrinsic;
Tim Northover8fe03d62014-02-21 11:57:24 +00003317 unsigned AltLLVMIntrinsic;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003318 unsigned TypeModifier;
3319
3320 bool operator<(unsigned RHSBuiltinID) const {
3321 return BuiltinID < RHSBuiltinID;
3322 }
Eric Christophered60b432015-11-11 02:04:08 +00003323 bool operator<(const NeonIntrinsicInfo &TE) const {
3324 return BuiltinID < TE.BuiltinID;
3325 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003326};
Benjamin Kramere003ca22015-10-28 13:54:16 +00003327} // end anonymous namespace
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003328
Tim Northover8fe03d62014-02-21 11:57:24 +00003329#define NEONMAP0(NameBase) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003330 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003331
Tim Northover8fe03d62014-02-21 11:57:24 +00003332#define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003333 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
3334 Intrinsic::LLVMIntrinsic, 0, TypeModifier }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003335
Tim Northover8fe03d62014-02-21 11:57:24 +00003336#define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003337 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
Tim Northover8fe03d62014-02-21 11:57:24 +00003338 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003339 TypeModifier }
Tim Northover8fe03d62014-02-21 11:57:24 +00003340
Craig Topper273dbc62015-10-18 05:29:26 +00003341static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = {
Tim Northover8fe03d62014-02-21 11:57:24 +00003342 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3343 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3344 NEONMAP1(vabs_v, arm_neon_vabs, 0),
3345 NEONMAP1(vabsq_v, arm_neon_vabs, 0),
3346 NEONMAP0(vaddhn_v),
3347 NEONMAP1(vaesdq_v, arm_neon_aesd, 0),
3348 NEONMAP1(vaeseq_v, arm_neon_aese, 0),
3349 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0),
3350 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0),
3351 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType),
3352 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType),
3353 NEONMAP1(vcage_v, arm_neon_vacge, 0),
3354 NEONMAP1(vcageq_v, arm_neon_vacge, 0),
3355 NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
3356 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
3357 NEONMAP1(vcale_v, arm_neon_vacge, 0),
3358 NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
3359 NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
3360 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
3361 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType),
3362 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType),
3363 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3364 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3365 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3366 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003367 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003368 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0),
3369 NEONMAP0(vcvt_f32_v),
3370 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3371 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3372 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3373 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3374 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3375 NEONMAP0(vcvt_s32_v),
3376 NEONMAP0(vcvt_s64_v),
3377 NEONMAP0(vcvt_u32_v),
3378 NEONMAP0(vcvt_u64_v),
3379 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
3380 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
3381 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
3382 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
3383 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
3384 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
3385 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
3386 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
3387 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
3388 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
3389 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
3390 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
3391 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
3392 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
3393 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
3394 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
3395 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
3396 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
3397 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
3398 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
3399 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
3400 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
3401 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
3402 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
3403 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
3404 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
3405 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
3406 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
3407 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
3408 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
3409 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
3410 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
3411 NEONMAP0(vcvtq_f32_v),
3412 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3413 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3414 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3415 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3416 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3417 NEONMAP0(vcvtq_s32_v),
3418 NEONMAP0(vcvtq_s64_v),
3419 NEONMAP0(vcvtq_u32_v),
3420 NEONMAP0(vcvtq_u64_v),
3421 NEONMAP0(vext_v),
3422 NEONMAP0(vextq_v),
3423 NEONMAP0(vfma_v),
3424 NEONMAP0(vfmaq_v),
3425 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3426 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3427 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3428 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3429 NEONMAP0(vld1_dup_v),
3430 NEONMAP1(vld1_v, arm_neon_vld1, 0),
3431 NEONMAP0(vld1q_dup_v),
3432 NEONMAP1(vld1q_v, arm_neon_vld1, 0),
3433 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
3434 NEONMAP1(vld2_v, arm_neon_vld2, 0),
3435 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
3436 NEONMAP1(vld2q_v, arm_neon_vld2, 0),
3437 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
3438 NEONMAP1(vld3_v, arm_neon_vld3, 0),
3439 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
3440 NEONMAP1(vld3q_v, arm_neon_vld3, 0),
3441 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
3442 NEONMAP1(vld4_v, arm_neon_vld4, 0),
3443 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
3444 NEONMAP1(vld4q_v, arm_neon_vld4, 0),
3445 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003446 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType),
3447 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003448 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
3449 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003450 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType),
3451 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003452 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
3453 NEONMAP0(vmovl_v),
3454 NEONMAP0(vmovn_v),
3455 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType),
3456 NEONMAP0(vmull_v),
3457 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType),
3458 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3459 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3460 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType),
3461 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3462 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3463 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType),
3464 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts),
3465 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts),
3466 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType),
3467 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType),
3468 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3469 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3470 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0),
3471 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0),
3472 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType),
3473 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType),
3474 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType),
3475 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts),
3476 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType),
3477 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType),
3478 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType),
3479 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType),
3480 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType),
3481 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3482 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3483 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3484 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
3485 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3486 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003487 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0),
3488 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003489 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3490 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3491 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType),
3492 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3493 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3494 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType),
3495 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType),
3496 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
3497 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003498 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType),
3499 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType),
3500 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType),
3501 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType),
3502 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType),
3503 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType),
3504 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType),
3505 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType),
3506 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType),
3507 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType),
3508 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType),
3509 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003510 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
3511 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003512 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
3513 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
Tim Northover8fe03d62014-02-21 11:57:24 +00003514 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3515 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3516 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType),
3517 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType),
3518 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType),
3519 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0),
3520 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0),
3521 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0),
3522 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0),
3523 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0),
3524 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0),
3525 NEONMAP0(vshl_n_v),
3526 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3527 NEONMAP0(vshll_n_v),
3528 NEONMAP0(vshlq_n_v),
3529 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3530 NEONMAP0(vshr_n_v),
3531 NEONMAP0(vshrn_n_v),
3532 NEONMAP0(vshrq_n_v),
3533 NEONMAP1(vst1_v, arm_neon_vst1, 0),
3534 NEONMAP1(vst1q_v, arm_neon_vst1, 0),
3535 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
3536 NEONMAP1(vst2_v, arm_neon_vst2, 0),
3537 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
3538 NEONMAP1(vst2q_v, arm_neon_vst2, 0),
3539 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
3540 NEONMAP1(vst3_v, arm_neon_vst3, 0),
3541 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
3542 NEONMAP1(vst3q_v, arm_neon_vst3, 0),
3543 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
3544 NEONMAP1(vst4_v, arm_neon_vst4, 0),
3545 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
3546 NEONMAP1(vst4q_v, arm_neon_vst4, 0),
3547 NEONMAP0(vsubhn_v),
3548 NEONMAP0(vtrn_v),
3549 NEONMAP0(vtrnq_v),
3550 NEONMAP0(vtst_v),
3551 NEONMAP0(vtstq_v),
3552 NEONMAP0(vuzp_v),
3553 NEONMAP0(vuzpq_v),
3554 NEONMAP0(vzip_v),
Tim Northovera0c95eb2014-02-21 12:16:59 +00003555 NEONMAP0(vzipq_v)
Tim Northover8fe03d62014-02-21 11:57:24 +00003556};
3557
Craig Topper273dbc62015-10-18 05:29:26 +00003558static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003559 NEONMAP1(vabs_v, aarch64_neon_abs, 0),
3560 NEONMAP1(vabsq_v, aarch64_neon_abs, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003561 NEONMAP0(vaddhn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003562 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0),
3563 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0),
3564 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0),
3565 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0),
3566 NEONMAP1(vcage_v, aarch64_neon_facge, 0),
3567 NEONMAP1(vcageq_v, aarch64_neon_facge, 0),
3568 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0),
3569 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0),
3570 NEONMAP1(vcale_v, aarch64_neon_facge, 0),
3571 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0),
3572 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0),
3573 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0),
3574 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType),
3575 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003576 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3577 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3578 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3579 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003580 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003581 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003582 NEONMAP0(vcvt_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003583 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3584 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3585 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3586 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3587 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3588 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003589 NEONMAP0(vcvtq_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003590 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3591 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3592 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3593 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3594 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3595 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
3596 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003597 NEONMAP0(vext_v),
3598 NEONMAP0(vextq_v),
3599 NEONMAP0(vfma_v),
3600 NEONMAP0(vfmaq_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003601 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3602 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3603 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
3604 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003605 NEONMAP0(vmovl_v),
3606 NEONMAP0(vmovn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003607 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType),
3608 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType),
3609 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType),
3610 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3611 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3612 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType),
3613 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType),
3614 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType),
3615 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3616 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3617 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0),
3618 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0),
3619 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType),
3620 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType),
3621 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType),
3622 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts),
3623 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType),
3624 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType),
3625 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType),
3626 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType),
3627 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType),
3628 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3629 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3630 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts),
3631 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
3632 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts),
3633 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003634 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0),
3635 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003636 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3637 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3638 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType),
3639 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3640 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3641 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType),
3642 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType),
3643 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3644 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3645 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
3646 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003647 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
3648 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
Tim Northover573cbee2014-05-24 12:52:07 +00003649 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3650 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3651 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType),
3652 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType),
3653 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType),
3654 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0),
3655 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0),
3656 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0),
3657 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0),
3658 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0),
3659 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003660 NEONMAP0(vshl_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003661 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003662 NEONMAP0(vshll_n_v),
3663 NEONMAP0(vshlq_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003664 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003665 NEONMAP0(vshr_n_v),
3666 NEONMAP0(vshrn_n_v),
3667 NEONMAP0(vshrq_n_v),
3668 NEONMAP0(vsubhn_v),
3669 NEONMAP0(vtst_v),
3670 NEONMAP0(vtstq_v),
3671};
3672
Craig Topper273dbc62015-10-18 05:29:26 +00003673static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003674 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType),
3675 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType),
3676 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType),
3677 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3678 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3679 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3680 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3681 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3682 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3683 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3684 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3685 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType),
3686 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3687 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType),
3688 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3689 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3690 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3691 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3692 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3693 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3694 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3695 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3696 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3697 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3698 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3699 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3700 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3701 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3702 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3703 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3704 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3705 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3706 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3707 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3708 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3709 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3710 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3711 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3712 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3713 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3714 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3715 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3716 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3717 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3718 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3719 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3720 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3721 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3722 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0),
3723 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3724 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3725 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3726 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3727 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3728 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3729 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3730 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3731 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3732 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3733 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3734 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3735 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3736 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3737 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3738 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3739 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3740 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3741 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3742 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3743 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0),
3744 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType),
3745 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType),
3746 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3747 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3748 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3749 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3750 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3751 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3752 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3753 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3754 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3755 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3756 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3757 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType),
3758 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3759 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType),
3760 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3761 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3762 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType),
3763 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType),
3764 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3765 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3766 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType),
3767 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType),
3768 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors),
3769 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType),
3770 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors),
3771 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0),
3772 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType),
3773 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType),
3774 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3775 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3776 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3777 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3778 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType),
3779 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3780 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3781 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3782 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType),
3783 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3784 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType),
3785 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors),
3786 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType),
3787 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3788 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3789 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType),
3790 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType),
3791 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3792 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3793 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType),
3794 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType),
3795 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType),
3796 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType),
3797 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3798 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3799 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3800 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3801 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType),
3802 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3803 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3804 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3805 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3806 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3807 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3808 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType),
3809 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType),
3810 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3811 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3812 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3813 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3814 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType),
3815 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType),
3816 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType),
3817 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType),
3818 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3819 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3820 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType),
3821 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType),
3822 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType),
3823 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3824 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3825 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3826 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3827 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType),
3828 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3829 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3830 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3831 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3832 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType),
3833 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType),
3834 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3835 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3836 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType),
3837 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType),
3838 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType),
3839 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType),
3840 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType),
3841 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType),
3842 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType),
3843 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType),
3844 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType),
3845 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType),
3846 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType),
3847 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType),
3848 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0),
3849 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0),
3850 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0),
3851 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0),
3852 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType),
3853 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType),
3854 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType),
3855 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType),
3856 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3857 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType),
3858 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3859 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType),
3860 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType),
3861 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType),
3862 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3863 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType),
3864 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3865 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003866};
3867
Tim Northover8fe03d62014-02-21 11:57:24 +00003868#undef NEONMAP0
3869#undef NEONMAP1
3870#undef NEONMAP2
3871
3872static bool NEONSIMDIntrinsicsProvenSorted = false;
Tim Northover8fe03d62014-02-21 11:57:24 +00003873
Tim Northover573cbee2014-05-24 12:52:07 +00003874static bool AArch64SIMDIntrinsicsProvenSorted = false;
3875static bool AArch64SISDIntrinsicsProvenSorted = false;
Tim Northovera2ee4332014-03-29 15:09:45 +00003876
3877
Tim Northover8fe03d62014-02-21 11:57:24 +00003878static const NeonIntrinsicInfo *
Craig Topper00bbdcf2014-06-28 23:22:23 +00003879findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
Tim Northover8fe03d62014-02-21 11:57:24 +00003880 unsigned BuiltinID, bool &MapProvenSorted) {
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003881
3882#ifndef NDEBUG
Tim Northover8fe03d62014-02-21 11:57:24 +00003883 if (!MapProvenSorted) {
Eric Christophered60b432015-11-11 02:04:08 +00003884 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap)));
Tim Northover8fe03d62014-02-21 11:57:24 +00003885 MapProvenSorted = true;
3886 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003887#endif
3888
Tim Northover8fe03d62014-02-21 11:57:24 +00003889 const NeonIntrinsicInfo *Builtin =
3890 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID);
3891
3892 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID)
3893 return Builtin;
3894
Craig Topper8a13c412014-05-21 05:09:00 +00003895 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003896}
3897
3898Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
3899 unsigned Modifier,
3900 llvm::Type *ArgType,
3901 const CallExpr *E) {
Tim Northovera2ee4332014-03-29 15:09:45 +00003902 int VectorSize = 0;
3903 if (Modifier & Use64BitVectors)
3904 VectorSize = 64;
3905 else if (Modifier & Use128BitVectors)
3906 VectorSize = 128;
3907
Tim Northover2d837962014-02-21 11:57:20 +00003908 // Return type.
3909 SmallVector<llvm::Type *, 3> Tys;
3910 if (Modifier & AddRetType) {
David Majnemerced8bdf2015-02-25 17:36:15 +00003911 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northover2d837962014-02-21 11:57:20 +00003912 if (Modifier & VectorizeRetType)
Tim Northovera2ee4332014-03-29 15:09:45 +00003913 Ty = llvm::VectorType::get(
3914 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1);
Tim Northover2d837962014-02-21 11:57:20 +00003915
3916 Tys.push_back(Ty);
3917 }
3918
3919 // Arguments.
Tim Northovera2ee4332014-03-29 15:09:45 +00003920 if (Modifier & VectorizeArgTypes) {
3921 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1;
3922 ArgType = llvm::VectorType::get(ArgType, Elts);
3923 }
Tim Northover2d837962014-02-21 11:57:20 +00003924
3925 if (Modifier & (Add1ArgType | Add2ArgTypes))
3926 Tys.push_back(ArgType);
3927
3928 if (Modifier & Add2ArgTypes)
3929 Tys.push_back(ArgType);
3930
3931 if (Modifier & InventFloatType)
3932 Tys.push_back(FloatTy);
3933
3934 return CGM.getIntrinsic(IntrinsicID, Tys);
3935}
3936
Tim Northovera2ee4332014-03-29 15:09:45 +00003937static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF,
3938 const NeonIntrinsicInfo &SISDInfo,
3939 SmallVectorImpl<Value *> &Ops,
3940 const CallExpr *E) {
Tim Northover0c68faa2014-03-31 15:47:09 +00003941 unsigned BuiltinID = SISDInfo.BuiltinID;
Tim Northovera2ee4332014-03-29 15:09:45 +00003942 unsigned int Int = SISDInfo.LLVMIntrinsic;
3943 unsigned Modifier = SISDInfo.TypeModifier;
3944 const char *s = SISDInfo.NameHint;
3945
Tim Northover0c68faa2014-03-31 15:47:09 +00003946 switch (BuiltinID) {
3947 case NEON::BI__builtin_neon_vcled_s64:
3948 case NEON::BI__builtin_neon_vcled_u64:
3949 case NEON::BI__builtin_neon_vcles_f32:
3950 case NEON::BI__builtin_neon_vcled_f64:
3951 case NEON::BI__builtin_neon_vcltd_s64:
3952 case NEON::BI__builtin_neon_vcltd_u64:
3953 case NEON::BI__builtin_neon_vclts_f32:
3954 case NEON::BI__builtin_neon_vcltd_f64:
3955 case NEON::BI__builtin_neon_vcales_f32:
3956 case NEON::BI__builtin_neon_vcaled_f64:
3957 case NEON::BI__builtin_neon_vcalts_f32:
3958 case NEON::BI__builtin_neon_vcaltd_f64:
3959 // Only one direction of comparisons actually exist, cmle is actually a cmge
3960 // with swapped operands. The table gives us the right intrinsic but we
3961 // still need to do the swap.
3962 std::swap(Ops[0], Ops[1]);
3963 break;
3964 }
3965
Tim Northovera2ee4332014-03-29 15:09:45 +00003966 assert(Int && "Generic code assumes a valid intrinsic");
3967
3968 // Determine the type(s) of this overloaded AArch64 intrinsic.
3969 const Expr *Arg = E->getArg(0);
3970 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType());
3971 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E);
3972
3973 int j = 0;
Michael J. Spencerdd597752014-05-31 00:22:12 +00003974 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00003975 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3976 ai != ae; ++ai, ++j) {
3977 llvm::Type *ArgTy = ai->getType();
3978 if (Ops[j]->getType()->getPrimitiveSizeInBits() ==
3979 ArgTy->getPrimitiveSizeInBits())
3980 continue;
3981
3982 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy());
3983 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate
3984 // it before inserting.
3985 Ops[j] =
3986 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType());
3987 Ops[j] =
3988 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0);
3989 }
3990
3991 Value *Result = CGF.EmitNeonCall(F, Ops, s);
3992 llvm::Type *ResultType = CGF.ConvertType(E->getType());
3993 if (ResultType->getPrimitiveSizeInBits() <
3994 Result->getType()->getPrimitiveSizeInBits())
3995 return CGF.Builder.CreateExtractElement(Result, C0);
3996
3997 return CGF.Builder.CreateBitCast(Result, ResultType, s);
3998}
Tim Northover8fe03d62014-02-21 11:57:24 +00003999
Tim Northover8fe03d62014-02-21 11:57:24 +00004000Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
4001 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic,
4002 const char *NameHint, unsigned Modifier, const CallExpr *E,
John McCall7f416cc2015-09-08 08:05:57 +00004003 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) {
Tim Northover8fe03d62014-02-21 11:57:24 +00004004 // Get the last argument, which specifies the vector type.
4005 llvm::APSInt NeonTypeConst;
4006 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
4007 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00004008 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004009
4010 // Determine the type of this overloaded NEON intrinsic.
4011 NeonTypeFlags Type(NeonTypeConst.getZExtValue());
4012 bool Usgn = Type.isUnsigned();
4013 bool Quad = Type.isQuad();
4014
4015 llvm::VectorType *VTy = GetNeonType(this, Type);
4016 llvm::Type *Ty = VTy;
4017 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00004018 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004019
John McCall7f416cc2015-09-08 08:05:57 +00004020 auto getAlignmentValue32 = [&](Address addr) -> Value* {
4021 return Builder.getInt32(addr.getAlignment().getQuantity());
4022 };
4023
Tim Northover8fe03d62014-02-21 11:57:24 +00004024 unsigned Int = LLVMIntrinsic;
4025 if ((Modifier & UnsignedAlts) && !Usgn)
4026 Int = AltLLVMIntrinsic;
4027
4028 switch (BuiltinID) {
4029 default: break;
4030 case NEON::BI__builtin_neon_vabs_v:
4031 case NEON::BI__builtin_neon_vabsq_v:
4032 if (VTy->getElementType()->isFloatingPointTy())
4033 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs");
4034 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs");
4035 case NEON::BI__builtin_neon_vaddhn_v: {
4036 llvm::VectorType *SrcTy =
4037 llvm::VectorType::getExtendedElementVectorType(VTy);
4038
4039 // %sum = add <4 x i32> %lhs, %rhs
4040 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4041 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
4042 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn");
4043
4044 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00004045 Constant *ShiftAmt =
4046 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00004047 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn");
4048
4049 // %res = trunc <4 x i32> %high to <4 x i16>
4050 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn");
4051 }
4052 case NEON::BI__builtin_neon_vcale_v:
4053 case NEON::BI__builtin_neon_vcaleq_v:
4054 case NEON::BI__builtin_neon_vcalt_v:
4055 case NEON::BI__builtin_neon_vcaltq_v:
4056 std::swap(Ops[0], Ops[1]);
Galina Kistanova0872d6c2017-06-03 06:30:46 +00004057 LLVM_FALLTHROUGH;
Tim Northover8fe03d62014-02-21 11:57:24 +00004058 case NEON::BI__builtin_neon_vcage_v:
4059 case NEON::BI__builtin_neon_vcageq_v:
4060 case NEON::BI__builtin_neon_vcagt_v:
4061 case NEON::BI__builtin_neon_vcagtq_v: {
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00004062 llvm::Type *VecFlt = llvm::VectorType::get(
4063 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy,
4064 VTy->getNumElements());
Tim Northover8fe03d62014-02-21 11:57:24 +00004065 llvm::Type *Tys[] = { VTy, VecFlt };
4066 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
4067 return EmitNeonCall(F, Ops, NameHint);
4068 }
4069 case NEON::BI__builtin_neon_vclz_v:
4070 case NEON::BI__builtin_neon_vclzq_v:
4071 // We generate target-independent intrinsic, which needs a second argument
4072 // for whether or not clz of zero is undefined; on ARM it isn't.
4073 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef()));
4074 break;
4075 case NEON::BI__builtin_neon_vcvt_f32_v:
4076 case NEON::BI__builtin_neon_vcvtq_f32_v:
4077 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4078 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad));
4079 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
4080 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
4081 case NEON::BI__builtin_neon_vcvt_n_f32_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00004082 case NEON::BI__builtin_neon_vcvt_n_f64_v:
4083 case NEON::BI__builtin_neon_vcvtq_n_f32_v:
4084 case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004085 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty };
Tim Northover8fe03d62014-02-21 11:57:24 +00004086 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
4087 Function *F = CGM.getIntrinsic(Int, Tys);
4088 return EmitNeonCall(F, Ops, "vcvt_n");
4089 }
4090 case NEON::BI__builtin_neon_vcvt_n_s32_v:
4091 case NEON::BI__builtin_neon_vcvt_n_u32_v:
4092 case NEON::BI__builtin_neon_vcvt_n_s64_v:
4093 case NEON::BI__builtin_neon_vcvt_n_u64_v:
4094 case NEON::BI__builtin_neon_vcvtq_n_s32_v:
4095 case NEON::BI__builtin_neon_vcvtq_n_u32_v:
4096 case NEON::BI__builtin_neon_vcvtq_n_s64_v:
4097 case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004098 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00004099 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
4100 return EmitNeonCall(F, Ops, "vcvt_n");
4101 }
4102 case NEON::BI__builtin_neon_vcvt_s32_v:
4103 case NEON::BI__builtin_neon_vcvt_u32_v:
4104 case NEON::BI__builtin_neon_vcvt_s64_v:
4105 case NEON::BI__builtin_neon_vcvt_u64_v:
4106 case NEON::BI__builtin_neon_vcvtq_s32_v:
4107 case NEON::BI__builtin_neon_vcvtq_u32_v:
4108 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00004109 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004110 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northover8fe03d62014-02-21 11:57:24 +00004111 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt")
4112 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
4113 }
4114 case NEON::BI__builtin_neon_vcvta_s32_v:
4115 case NEON::BI__builtin_neon_vcvta_s64_v:
4116 case NEON::BI__builtin_neon_vcvta_u32_v:
4117 case NEON::BI__builtin_neon_vcvta_u64_v:
4118 case NEON::BI__builtin_neon_vcvtaq_s32_v:
4119 case NEON::BI__builtin_neon_vcvtaq_s64_v:
4120 case NEON::BI__builtin_neon_vcvtaq_u32_v:
4121 case NEON::BI__builtin_neon_vcvtaq_u64_v:
4122 case NEON::BI__builtin_neon_vcvtn_s32_v:
4123 case NEON::BI__builtin_neon_vcvtn_s64_v:
4124 case NEON::BI__builtin_neon_vcvtn_u32_v:
4125 case NEON::BI__builtin_neon_vcvtn_u64_v:
4126 case NEON::BI__builtin_neon_vcvtnq_s32_v:
4127 case NEON::BI__builtin_neon_vcvtnq_s64_v:
4128 case NEON::BI__builtin_neon_vcvtnq_u32_v:
4129 case NEON::BI__builtin_neon_vcvtnq_u64_v:
4130 case NEON::BI__builtin_neon_vcvtp_s32_v:
4131 case NEON::BI__builtin_neon_vcvtp_s64_v:
4132 case NEON::BI__builtin_neon_vcvtp_u32_v:
4133 case NEON::BI__builtin_neon_vcvtp_u64_v:
4134 case NEON::BI__builtin_neon_vcvtpq_s32_v:
4135 case NEON::BI__builtin_neon_vcvtpq_s64_v:
4136 case NEON::BI__builtin_neon_vcvtpq_u32_v:
4137 case NEON::BI__builtin_neon_vcvtpq_u64_v:
4138 case NEON::BI__builtin_neon_vcvtm_s32_v:
4139 case NEON::BI__builtin_neon_vcvtm_s64_v:
4140 case NEON::BI__builtin_neon_vcvtm_u32_v:
4141 case NEON::BI__builtin_neon_vcvtm_u64_v:
4142 case NEON::BI__builtin_neon_vcvtmq_s32_v:
4143 case NEON::BI__builtin_neon_vcvtmq_s64_v:
4144 case NEON::BI__builtin_neon_vcvtmq_u32_v:
4145 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004146 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00004147 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
4148 }
4149 case NEON::BI__builtin_neon_vext_v:
4150 case NEON::BI__builtin_neon_vextq_v: {
4151 int CV = cast<ConstantInt>(Ops[2])->getSExtValue();
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004152 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004153 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00004154 Indices.push_back(i+CV);
Tim Northover8fe03d62014-02-21 11:57:24 +00004155
4156 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4157 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Craig Topper832caf02016-05-29 02:39:30 +00004158 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext");
Tim Northover8fe03d62014-02-21 11:57:24 +00004159 }
4160 case NEON::BI__builtin_neon_vfma_v:
4161 case NEON::BI__builtin_neon_vfmaq_v: {
4162 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
4163 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4164 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4165 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
4166
4167 // NEON intrinsic puts accumulator first, unlike the LLVM fma.
David Blaikie43f9bb72015-05-18 22:14:03 +00004168 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northover8fe03d62014-02-21 11:57:24 +00004169 }
4170 case NEON::BI__builtin_neon_vld1_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004171 case NEON::BI__builtin_neon_vld1q_v: {
4172 llvm::Type *Tys[] = {Ty, Int8PtrTy};
John McCall7f416cc2015-09-08 08:05:57 +00004173 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004174 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1");
4175 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004176 case NEON::BI__builtin_neon_vld2_v:
4177 case NEON::BI__builtin_neon_vld2q_v:
4178 case NEON::BI__builtin_neon_vld3_v:
4179 case NEON::BI__builtin_neon_vld3q_v:
4180 case NEON::BI__builtin_neon_vld4_v:
4181 case NEON::BI__builtin_neon_vld4q_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004182 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4183 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00004184 Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00004185 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004186 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4187 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004188 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004189 }
4190 case NEON::BI__builtin_neon_vld1_dup_v:
4191 case NEON::BI__builtin_neon_vld1q_dup_v: {
4192 Value *V = UndefValue::get(Ty);
4193 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00004194 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty);
4195 LoadInst *Ld = Builder.CreateLoad(PtrOp0);
Michael J. Spencerdd597752014-05-31 00:22:12 +00004196 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northover8fe03d62014-02-21 11:57:24 +00004197 Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
4198 return EmitNeonSplat(Ops[0], CI);
4199 }
4200 case NEON::BI__builtin_neon_vld2_lane_v:
4201 case NEON::BI__builtin_neon_vld2q_lane_v:
4202 case NEON::BI__builtin_neon_vld3_lane_v:
4203 case NEON::BI__builtin_neon_vld3q_lane_v:
4204 case NEON::BI__builtin_neon_vld4_lane_v:
4205 case NEON::BI__builtin_neon_vld4q_lane_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004206 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4207 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
Tim Northover8fe03d62014-02-21 11:57:24 +00004208 for (unsigned I = 2; I < Ops.size() - 1; ++I)
4209 Ops[I] = Builder.CreateBitCast(Ops[I], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004210 Ops.push_back(getAlignmentValue32(PtrOp1));
Tim Northover8fe03d62014-02-21 11:57:24 +00004211 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint);
4212 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4213 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004214 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004215 }
4216 case NEON::BI__builtin_neon_vmovl_v: {
4217 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy);
4218 Ops[0] = Builder.CreateBitCast(Ops[0], DTy);
4219 if (Usgn)
4220 return Builder.CreateZExt(Ops[0], Ty, "vmovl");
4221 return Builder.CreateSExt(Ops[0], Ty, "vmovl");
4222 }
4223 case NEON::BI__builtin_neon_vmovn_v: {
4224 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4225 Ops[0] = Builder.CreateBitCast(Ops[0], QTy);
4226 return Builder.CreateTrunc(Ops[0], Ty, "vmovn");
4227 }
4228 case NEON::BI__builtin_neon_vmull_v:
4229 // FIXME: the integer vmull operations could be emitted in terms of pure
4230 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of
4231 // hoisting the exts outside loops. Until global ISel comes along that can
4232 // see through such movement this leads to bad CodeGen. So we need an
4233 // intrinsic for now.
4234 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
4235 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
4236 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
4237 case NEON::BI__builtin_neon_vpadal_v:
4238 case NEON::BI__builtin_neon_vpadalq_v: {
4239 // The source operand type has twice as many elements of half the size.
4240 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4241 llvm::Type *EltTy =
4242 llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4243 llvm::Type *NarrowTy =
4244 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4245 llvm::Type *Tys[2] = { Ty, NarrowTy };
4246 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint);
4247 }
4248 case NEON::BI__builtin_neon_vpaddl_v:
4249 case NEON::BI__builtin_neon_vpaddlq_v: {
4250 // The source operand type has twice as many elements of half the size.
4251 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4252 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4253 llvm::Type *NarrowTy =
4254 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4255 llvm::Type *Tys[2] = { Ty, NarrowTy };
4256 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl");
4257 }
4258 case NEON::BI__builtin_neon_vqdmlal_v:
4259 case NEON::BI__builtin_neon_vqdmlsl_v: {
4260 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end());
Benjamin Kramerc385a802015-07-28 15:40:11 +00004261 Ops[1] =
4262 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal");
4263 Ops.resize(2);
4264 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004265 }
4266 case NEON::BI__builtin_neon_vqshl_n_v:
4267 case NEON::BI__builtin_neon_vqshlq_n_v:
4268 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n",
4269 1, false);
Yi Kong1083eb52014-07-29 09:25:17 +00004270 case NEON::BI__builtin_neon_vqshlu_n_v:
4271 case NEON::BI__builtin_neon_vqshluq_n_v:
4272 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n",
4273 1, false);
Tim Northover8fe03d62014-02-21 11:57:24 +00004274 case NEON::BI__builtin_neon_vrecpe_v:
4275 case NEON::BI__builtin_neon_vrecpeq_v:
4276 case NEON::BI__builtin_neon_vrsqrte_v:
4277 case NEON::BI__builtin_neon_vrsqrteq_v:
4278 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
4279 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint);
4280
Yi Kong1083eb52014-07-29 09:25:17 +00004281 case NEON::BI__builtin_neon_vrshr_n_v:
4282 case NEON::BI__builtin_neon_vrshrq_n_v:
4283 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n",
4284 1, true);
Tim Northover8fe03d62014-02-21 11:57:24 +00004285 case NEON::BI__builtin_neon_vshl_n_v:
4286 case NEON::BI__builtin_neon_vshlq_n_v:
4287 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
4288 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1],
4289 "vshl_n");
4290 case NEON::BI__builtin_neon_vshll_n_v: {
4291 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy);
4292 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4293 if (Usgn)
4294 Ops[0] = Builder.CreateZExt(Ops[0], VTy);
4295 else
4296 Ops[0] = Builder.CreateSExt(Ops[0], VTy);
4297 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false);
4298 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n");
4299 }
4300 case NEON::BI__builtin_neon_vshrn_n_v: {
4301 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4302 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4303 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false);
4304 if (Usgn)
4305 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]);
4306 else
4307 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]);
4308 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n");
4309 }
4310 case NEON::BI__builtin_neon_vshr_n_v:
4311 case NEON::BI__builtin_neon_vshrq_n_v:
4312 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n");
4313 case NEON::BI__builtin_neon_vst1_v:
4314 case NEON::BI__builtin_neon_vst1q_v:
4315 case NEON::BI__builtin_neon_vst2_v:
4316 case NEON::BI__builtin_neon_vst2q_v:
4317 case NEON::BI__builtin_neon_vst3_v:
4318 case NEON::BI__builtin_neon_vst3q_v:
4319 case NEON::BI__builtin_neon_vst4_v:
4320 case NEON::BI__builtin_neon_vst4q_v:
4321 case NEON::BI__builtin_neon_vst2_lane_v:
4322 case NEON::BI__builtin_neon_vst2q_lane_v:
4323 case NEON::BI__builtin_neon_vst3_lane_v:
4324 case NEON::BI__builtin_neon_vst3q_lane_v:
4325 case NEON::BI__builtin_neon_vst4_lane_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004326 case NEON::BI__builtin_neon_vst4q_lane_v: {
4327 llvm::Type *Tys[] = {Int8PtrTy, Ty};
John McCall7f416cc2015-09-08 08:05:57 +00004328 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004329 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
4330 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004331 case NEON::BI__builtin_neon_vsubhn_v: {
4332 llvm::VectorType *SrcTy =
4333 llvm::VectorType::getExtendedElementVectorType(VTy);
4334
4335 // %sum = add <4 x i32> %lhs, %rhs
4336 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4337 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
4338 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn");
4339
4340 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00004341 Constant *ShiftAmt =
4342 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00004343 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn");
4344
4345 // %res = trunc <4 x i32> %high to <4 x i16>
4346 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn");
4347 }
4348 case NEON::BI__builtin_neon_vtrn_v:
4349 case NEON::BI__builtin_neon_vtrnq_v: {
4350 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4351 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4352 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004353 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004354
4355 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004356 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004357 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004358 Indices.push_back(i+vi);
4359 Indices.push_back(i+e+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004360 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004361 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004362 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00004363 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004364 }
4365 return SV;
4366 }
4367 case NEON::BI__builtin_neon_vtst_v:
4368 case NEON::BI__builtin_neon_vtstq_v: {
4369 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4370 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4371 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
4372 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
4373 ConstantAggregateZero::get(Ty));
4374 return Builder.CreateSExt(Ops[0], Ty, "vtst");
4375 }
4376 case NEON::BI__builtin_neon_vuzp_v:
4377 case NEON::BI__builtin_neon_vuzpq_v: {
4378 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4379 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4380 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004381 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004382
4383 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004384 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004385 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00004386 Indices.push_back(2*i+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004387
David Blaikiefb901c7a2015-04-04 15:12:29 +00004388 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004389 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00004390 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004391 }
4392 return SV;
4393 }
4394 case NEON::BI__builtin_neon_vzip_v:
4395 case NEON::BI__builtin_neon_vzipq_v: {
4396 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4397 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4398 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004399 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004400
4401 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004402 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004403 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004404 Indices.push_back((i + vi*e) >> 1);
4405 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northover8fe03d62014-02-21 11:57:24 +00004406 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004407 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004408 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00004409 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004410 }
4411 return SV;
4412 }
4413 }
4414
4415 assert(Int && "Expected valid intrinsic number");
4416
4417 // Determine the type(s) of this overloaded AArch64 intrinsic.
4418 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E);
4419
4420 Value *Result = EmitNeonCall(F, Ops, NameHint);
4421 llvm::Type *ResultType = ConvertType(E->getType());
4422 // AArch64 intrinsic one-element vector type cast to
4423 // scalar type expected by the builtin
4424 return Builder.CreateBitCast(Result, ResultType, NameHint);
4425}
4426
Kevin Qin1718af62013-11-14 02:45:18 +00004427Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr(
4428 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp,
4429 const CmpInst::Predicate Ip, const Twine &Name) {
Tim Northovera2ee4332014-03-29 15:09:45 +00004430 llvm::Type *OTy = Op->getType();
4431
4432 // FIXME: this is utterly horrific. We should not be looking at previous
4433 // codegen context to find out what needs doing. Unfortunately TableGen
4434 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32
4435 // (etc).
4436 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op))
4437 OTy = BI->getOperand(0)->getType();
4438
Kevin Qin1718af62013-11-14 02:45:18 +00004439 Op = Builder.CreateBitCast(Op, OTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00004440 if (OTy->getScalarType()->isFloatingPointTy()) {
4441 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004442 } else {
Tim Northovera2ee4332014-03-29 15:09:45 +00004443 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004444 }
Hao Liuf96fd372013-12-23 02:44:00 +00004445 return Builder.CreateSExt(Op, Ty, Name);
Kevin Qin1718af62013-11-14 02:45:18 +00004446}
4447
Jiangning Liu18b707c2013-11-14 01:57:55 +00004448static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops,
4449 Value *ExtOp, Value *IndexOp,
4450 llvm::Type *ResTy, unsigned IntID,
4451 const char *Name) {
4452 SmallVector<Value *, 2> TblOps;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004453 if (ExtOp)
4454 TblOps.push_back(ExtOp);
4455
4456 // Build a vector containing sequential number like (0, 1, 2, ..., 15)
4457 SmallVector<uint32_t, 16> Indices;
4458 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType());
4459 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) {
Craig Topper832caf02016-05-29 02:39:30 +00004460 Indices.push_back(2*i);
4461 Indices.push_back(2*i+1);
Jiangning Liu18b707c2013-11-14 01:57:55 +00004462 }
Jiangning Liu18b707c2013-11-14 01:57:55 +00004463
4464 int PairPos = 0, End = Ops.size() - 1;
4465 while (PairPos < End) {
4466 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004467 Ops[PairPos+1], Indices,
4468 Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004469 PairPos += 2;
4470 }
4471
4472 // If there's an odd number of 64-bit lookup table, fill the high 64-bit
4473 // of the 128-bit lookup table with zero.
4474 if (PairPos == End) {
4475 Value *ZeroTbl = ConstantAggregateZero::get(TblTy);
4476 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004477 ZeroTbl, Indices, Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004478 }
4479
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004480 Function *TblF;
4481 TblOps.push_back(IndexOp);
4482 TblF = CGF.CGM.getIntrinsic(IntID, ResTy);
4483
4484 return CGF.EmitNeonCall(TblF, TblOps, Name);
4485}
4486
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004487Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) {
Benjamin Kramerc385a802015-07-28 15:40:11 +00004488 unsigned Value;
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004489 switch (BuiltinID) {
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004490 default:
4491 return nullptr;
Yi Kong4d5e23f2014-07-14 15:20:09 +00004492 case ARM::BI__builtin_arm_nop:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004493 Value = 0;
4494 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004495 case ARM::BI__builtin_arm_yield:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004496 case ARM::BI__yield:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004497 Value = 1;
4498 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004499 case ARM::BI__builtin_arm_wfe:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004500 case ARM::BI__wfe:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004501 Value = 2;
4502 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004503 case ARM::BI__builtin_arm_wfi:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004504 case ARM::BI__wfi:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004505 Value = 3;
4506 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004507 case ARM::BI__builtin_arm_sev:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004508 case ARM::BI__sev:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004509 Value = 4;
4510 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004511 case ARM::BI__builtin_arm_sevl:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004512 case ARM::BI__sevl:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004513 Value = 5;
4514 break;
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004515 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00004516
4517 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint),
4518 llvm::ConstantInt::get(Int32Ty, Value));
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004519}
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004520
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004521// Generates the IR for the read/write special register builtin,
4522// ValueType is the type of the value that is to be written or read,
4523// RegisterType is the type of the register being written to or read from.
4524static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF,
4525 const CallExpr *E,
4526 llvm::Type *RegisterType,
Matt Arsenault64665bc2016-06-28 00:13:17 +00004527 llvm::Type *ValueType,
4528 bool IsRead,
4529 StringRef SysReg = "") {
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004530 // write and register intrinsics only support 32 and 64 bit operations.
4531 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64))
4532 && "Unsupported size for register.");
4533
4534 CodeGen::CGBuilderTy &Builder = CGF.Builder;
4535 CodeGen::CodeGenModule &CGM = CGF.CGM;
4536 LLVMContext &Context = CGM.getLLVMContext();
4537
Matt Arsenault64665bc2016-06-28 00:13:17 +00004538 if (SysReg.empty()) {
4539 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts();
Zachary Turner26dab122016-12-13 17:10:16 +00004540 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString();
Matt Arsenault64665bc2016-06-28 00:13:17 +00004541 }
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004542
4543 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) };
4544 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4545 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4546
4547 llvm::Type *Types[] = { RegisterType };
4548
4549 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32);
4550 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64))
4551 && "Can't fit 64-bit value in 32-bit register");
4552
4553 if (IsRead) {
4554 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
4555 llvm::Value *Call = Builder.CreateCall(F, Metadata);
4556
4557 if (MixedTypes)
4558 // Read into 64 bit register and then truncate result to 32 bit.
4559 return Builder.CreateTrunc(Call, ValueType);
4560
4561 if (ValueType->isPointerTy())
4562 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*).
4563 return Builder.CreateIntToPtr(Call, ValueType);
4564
4565 return Call;
4566 }
4567
4568 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
4569 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1));
4570 if (MixedTypes) {
4571 // Extend 32 bit write value to 64 bit to pass to write.
4572 ArgValue = Builder.CreateZExt(ArgValue, RegisterType);
4573 return Builder.CreateCall(F, { Metadata, ArgValue });
4574 }
4575
4576 if (ValueType->isPointerTy()) {
4577 // Have VoidPtrTy ArgValue but want to return an i32/i64.
4578 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType);
4579 return Builder.CreateCall(F, { Metadata, ArgValue });
4580 }
4581
4582 return Builder.CreateCall(F, { Metadata, ArgValue });
4583}
4584
Bob Wilson63c93142015-06-24 06:05:20 +00004585/// Return true if BuiltinID is an overloaded Neon intrinsic with an extra
4586/// argument that specifies the vector type.
4587static bool HasExtraNeonArgument(unsigned BuiltinID) {
4588 switch (BuiltinID) {
4589 default: break;
4590 case NEON::BI__builtin_neon_vget_lane_i8:
4591 case NEON::BI__builtin_neon_vget_lane_i16:
4592 case NEON::BI__builtin_neon_vget_lane_i32:
4593 case NEON::BI__builtin_neon_vget_lane_i64:
4594 case NEON::BI__builtin_neon_vget_lane_f32:
4595 case NEON::BI__builtin_neon_vgetq_lane_i8:
4596 case NEON::BI__builtin_neon_vgetq_lane_i16:
4597 case NEON::BI__builtin_neon_vgetq_lane_i32:
4598 case NEON::BI__builtin_neon_vgetq_lane_i64:
4599 case NEON::BI__builtin_neon_vgetq_lane_f32:
4600 case NEON::BI__builtin_neon_vset_lane_i8:
4601 case NEON::BI__builtin_neon_vset_lane_i16:
4602 case NEON::BI__builtin_neon_vset_lane_i32:
4603 case NEON::BI__builtin_neon_vset_lane_i64:
4604 case NEON::BI__builtin_neon_vset_lane_f32:
4605 case NEON::BI__builtin_neon_vsetq_lane_i8:
4606 case NEON::BI__builtin_neon_vsetq_lane_i16:
4607 case NEON::BI__builtin_neon_vsetq_lane_i32:
4608 case NEON::BI__builtin_neon_vsetq_lane_i64:
4609 case NEON::BI__builtin_neon_vsetq_lane_f32:
4610 case NEON::BI__builtin_neon_vsha1h_u32:
4611 case NEON::BI__builtin_neon_vsha1cq_u32:
4612 case NEON::BI__builtin_neon_vsha1pq_u32:
4613 case NEON::BI__builtin_neon_vsha1mq_u32:
4614 case ARM::BI_MoveToCoprocessor:
4615 case ARM::BI_MoveToCoprocessor2:
4616 return false;
4617 }
4618 return true;
4619}
4620
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004621Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
4622 const CallExpr *E) {
4623 if (auto Hint = GetValueForARMHint(BuiltinID))
4624 return Hint;
Saleem Abdulrasool38ed6de2014-05-02 06:53:57 +00004625
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004626 if (BuiltinID == ARM::BI__emit) {
4627 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb;
4628 llvm::FunctionType *FTy =
4629 llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
4630
4631 APSInt Value;
4632 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
4633 llvm_unreachable("Sema will ensure that the parameter is constant");
4634
4635 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
4636
4637 llvm::InlineAsm *Emit =
4638 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "",
4639 /*SideEffects=*/true)
4640 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "",
4641 /*SideEffects=*/true);
4642
David Blaikie4ba525b2015-07-14 17:27:39 +00004643 return Builder.CreateCall(Emit);
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004644 }
4645
Yi Kong1d268af2014-08-26 12:48:06 +00004646 if (BuiltinID == ARM::BI__builtin_arm_dbg) {
4647 Value *Option = EmitScalarExpr(E->getArg(0));
4648 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
4649 }
4650
Yi Kong26d104a2014-08-13 19:18:14 +00004651 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
4652 Value *Address = EmitScalarExpr(E->getArg(0));
4653 Value *RW = EmitScalarExpr(E->getArg(1));
4654 Value *IsData = EmitScalarExpr(E->getArg(2));
4655
4656 // Locality is not supported on ARM target
4657 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3);
4658
4659 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00004660 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Kong26d104a2014-08-13 19:18:14 +00004661 }
4662
Jim Grosbach171ec342014-06-16 21:55:58 +00004663 if (BuiltinID == ARM::BI__builtin_arm_rbit) {
Chad Rosierc22abb32017-01-10 18:55:11 +00004664 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
4665 return Builder.CreateCall(
4666 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach171ec342014-06-16 21:55:58 +00004667 }
4668
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004669 if (BuiltinID == ARM::BI__clear_cache) {
Rafael Espindola2219fc52013-05-14 12:45:47 +00004670 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
Rafael Espindolaa54062e2010-06-07 17:26:50 +00004671 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00004672 Value *Ops[2];
Rafael Espindola2219fc52013-05-14 12:45:47 +00004673 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00004674 Ops[i] = EmitScalarExpr(E->getArg(i));
Chris Lattner2192fe52011-07-18 04:24:23 +00004675 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
4676 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004677 StringRef Name = FD->getName();
John McCall882987f2013-02-28 19:01:20 +00004678 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
Chris Lattner5cc15e02010-03-03 19:03:45 +00004679 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004680
Ranjeet Singhca2b3e7b2016-06-17 00:59:41 +00004681 if (BuiltinID == ARM::BI__builtin_arm_mcrr ||
4682 BuiltinID == ARM::BI__builtin_arm_mcrr2) {
4683 Function *F;
4684
4685 switch (BuiltinID) {
4686 default: llvm_unreachable("unexpected builtin");
4687 case ARM::BI__builtin_arm_mcrr:
4688 F = CGM.getIntrinsic(Intrinsic::arm_mcrr);
4689 break;
4690 case ARM::BI__builtin_arm_mcrr2:
4691 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2);
4692 break;
4693 }
4694
4695 // MCRR{2} instruction has 5 operands but
4696 // the intrinsic has 4 because Rt and Rt2
4697 // are represented as a single unsigned 64
4698 // bit integer in the intrinsic definition
4699 // but internally it's represented as 2 32
4700 // bit integers.
4701
4702 Value *Coproc = EmitScalarExpr(E->getArg(0));
4703 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4704 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2));
4705 Value *CRm = EmitScalarExpr(E->getArg(3));
4706
4707 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4708 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty);
4709 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1);
4710 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty);
4711
4712 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm});
4713 }
4714
4715 if (BuiltinID == ARM::BI__builtin_arm_mrrc ||
4716 BuiltinID == ARM::BI__builtin_arm_mrrc2) {
4717 Function *F;
4718
4719 switch (BuiltinID) {
4720 default: llvm_unreachable("unexpected builtin");
4721 case ARM::BI__builtin_arm_mrrc:
4722 F = CGM.getIntrinsic(Intrinsic::arm_mrrc);
4723 break;
4724 case ARM::BI__builtin_arm_mrrc2:
4725 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2);
4726 break;
4727 }
4728
4729 Value *Coproc = EmitScalarExpr(E->getArg(0));
4730 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4731 Value *CRm = EmitScalarExpr(E->getArg(2));
4732 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm});
4733
4734 // Returns an unsigned 64 bit integer, represented
4735 // as two 32 bit integers.
4736
4737 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1);
4738 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0);
4739 Rt = Builder.CreateZExt(Rt, Int64Ty);
4740 Rt1 = Builder.CreateZExt(Rt1, Int64Ty);
4741
4742 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32);
4743 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true);
4744 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1);
4745
4746 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType()));
4747 }
4748
Tim Northover6aacd492013-07-16 09:47:53 +00004749 if (BuiltinID == ARM::BI__builtin_arm_ldrexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004750 ((BuiltinID == ARM::BI__builtin_arm_ldrex ||
4751 BuiltinID == ARM::BI__builtin_arm_ldaex) &&
Saleem Abdulrasoole700cab2014-07-05 20:10:05 +00004752 getContext().getTypeSize(E->getType()) == 64) ||
4753 BuiltinID == ARM::BI__ldrexd) {
4754 Function *F;
4755
4756 switch (BuiltinID) {
4757 default: llvm_unreachable("unexpected builtin");
4758 case ARM::BI__builtin_arm_ldaex:
4759 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd);
4760 break;
4761 case ARM::BI__builtin_arm_ldrexd:
4762 case ARM::BI__builtin_arm_ldrex:
4763 case ARM::BI__ldrexd:
4764 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
4765 break;
4766 }
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004767
4768 Value *LdPtr = EmitScalarExpr(E->getArg(0));
Tim Northover6aacd492013-07-16 09:47:53 +00004769 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
4770 "ldrexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004771
4772 Value *Val0 = Builder.CreateExtractValue(Val, 1);
4773 Value *Val1 = Builder.CreateExtractValue(Val, 0);
4774 Val0 = Builder.CreateZExt(Val0, Int64Ty);
4775 Val1 = Builder.CreateZExt(Val1, Int64Ty);
4776
4777 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32);
4778 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
Tim Northover6aacd492013-07-16 09:47:53 +00004779 Val = Builder.CreateOr(Val, Val1);
4780 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004781 }
4782
Tim Northover3acd6bd2014-07-02 12:56:02 +00004783 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
4784 BuiltinID == ARM::BI__builtin_arm_ldaex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004785 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
4786
4787 QualType Ty = E->getType();
4788 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004789 llvm::Type *PtrTy = llvm::IntegerType::get(
4790 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
4791 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004792
Tim Northover3acd6bd2014-07-02 12:56:02 +00004793 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
4794 ? Intrinsic::arm_ldaex
4795 : Intrinsic::arm_ldrex,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004796 PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004797 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
4798
4799 if (RealResTy->isPointerTy())
4800 return Builder.CreateIntToPtr(Val, RealResTy);
4801 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004802 llvm::Type *IntResTy = llvm::IntegerType::get(
4803 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northover6aacd492013-07-16 09:47:53 +00004804 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
4805 return Builder.CreateBitCast(Val, RealResTy);
4806 }
4807 }
4808
4809 if (BuiltinID == ARM::BI__builtin_arm_strexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004810 ((BuiltinID == ARM::BI__builtin_arm_stlex ||
4811 BuiltinID == ARM::BI__builtin_arm_strex) &&
Tim Northover6aacd492013-07-16 09:47:53 +00004812 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00004813 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4814 ? Intrinsic::arm_stlexd
4815 : Intrinsic::arm_strexd);
Serge Guelton1d993272017-05-09 19:31:30 +00004816 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty);
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004817
John McCall7f416cc2015-09-08 08:05:57 +00004818 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004819 Value *Val = EmitScalarExpr(E->getArg(0));
4820 Builder.CreateStore(Val, Tmp);
4821
John McCall7f416cc2015-09-08 08:05:57 +00004822 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004823 Val = Builder.CreateLoad(LdPtr);
4824
4825 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
4826 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
Tim Northover6aacd492013-07-16 09:47:53 +00004827 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00004828 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004829 }
4830
Tim Northover3acd6bd2014-07-02 12:56:02 +00004831 if (BuiltinID == ARM::BI__builtin_arm_strex ||
4832 BuiltinID == ARM::BI__builtin_arm_stlex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004833 Value *StoreVal = EmitScalarExpr(E->getArg(0));
4834 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
4835
4836 QualType Ty = E->getArg(0)->getType();
4837 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
4838 getContext().getTypeSize(Ty));
4839 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
4840
4841 if (StoreVal->getType()->isPointerTy())
4842 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty);
4843 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004844 llvm::Type *IntTy = llvm::IntegerType::get(
4845 getLLVMContext(),
4846 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
4847 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004848 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
4849 }
4850
Tim Northover3acd6bd2014-07-02 12:56:02 +00004851 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4852 ? Intrinsic::arm_stlex
4853 : Intrinsic::arm_strex,
4854 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00004855 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex");
Tim Northover6aacd492013-07-16 09:47:53 +00004856 }
4857
Martin Storsjoed95a082016-09-30 19:13:46 +00004858 switch (BuiltinID) {
4859 case ARM::BI__iso_volatile_load8:
4860 case ARM::BI__iso_volatile_load16:
4861 case ARM::BI__iso_volatile_load32:
4862 case ARM::BI__iso_volatile_load64: {
4863 Value *Ptr = EmitScalarExpr(E->getArg(0));
4864 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4865 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy);
4866 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4867 LoadSize.getQuantity() * 8);
4868 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4869 llvm::LoadInst *Load =
4870 Builder.CreateAlignedLoad(Ptr, LoadSize);
4871 Load->setVolatile(true);
4872 return Load;
4873 }
4874 case ARM::BI__iso_volatile_store8:
4875 case ARM::BI__iso_volatile_store16:
4876 case ARM::BI__iso_volatile_store32:
4877 case ARM::BI__iso_volatile_store64: {
4878 Value *Ptr = EmitScalarExpr(E->getArg(0));
4879 Value *Value = EmitScalarExpr(E->getArg(1));
4880 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4881 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
4882 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4883 StoreSize.getQuantity() * 8);
4884 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4885 llvm::StoreInst *Store =
4886 Builder.CreateAlignedStore(Value, Ptr,
4887 StoreSize);
4888 Store->setVolatile(true);
4889 return Store;
4890 }
4891 }
4892
Tim Northover6aacd492013-07-16 09:47:53 +00004893 if (BuiltinID == ARM::BI__builtin_arm_clrex) {
4894 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00004895 return Builder.CreateCall(F);
Tim Northover6aacd492013-07-16 09:47:53 +00004896 }
4897
Joey Gouly1e8637b2013-09-18 10:07:09 +00004898 // CRC32
4899 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
4900 switch (BuiltinID) {
4901 case ARM::BI__builtin_arm_crc32b:
4902 CRCIntrinsicID = Intrinsic::arm_crc32b; break;
4903 case ARM::BI__builtin_arm_crc32cb:
4904 CRCIntrinsicID = Intrinsic::arm_crc32cb; break;
4905 case ARM::BI__builtin_arm_crc32h:
4906 CRCIntrinsicID = Intrinsic::arm_crc32h; break;
4907 case ARM::BI__builtin_arm_crc32ch:
4908 CRCIntrinsicID = Intrinsic::arm_crc32ch; break;
4909 case ARM::BI__builtin_arm_crc32w:
4910 case ARM::BI__builtin_arm_crc32d:
4911 CRCIntrinsicID = Intrinsic::arm_crc32w; break;
4912 case ARM::BI__builtin_arm_crc32cw:
4913 case ARM::BI__builtin_arm_crc32cd:
4914 CRCIntrinsicID = Intrinsic::arm_crc32cw; break;
4915 }
4916
4917 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
4918 Value *Arg0 = EmitScalarExpr(E->getArg(0));
4919 Value *Arg1 = EmitScalarExpr(E->getArg(1));
4920
4921 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w
4922 // intrinsics, hence we need different codegen for these cases.
4923 if (BuiltinID == ARM::BI__builtin_arm_crc32d ||
4924 BuiltinID == ARM::BI__builtin_arm_crc32cd) {
4925 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4926 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty);
4927 Value *Arg1b = Builder.CreateLShr(Arg1, C1);
4928 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty);
4929
4930 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004931 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a});
4932 return Builder.CreateCall(F, {Res, Arg1b});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004933 } else {
4934 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty);
4935
4936 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004937 return Builder.CreateCall(F, {Arg0, Arg1});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004938 }
4939 }
4940
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004941 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
4942 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4943 BuiltinID == ARM::BI__builtin_arm_rsrp ||
4944 BuiltinID == ARM::BI__builtin_arm_wsr ||
4945 BuiltinID == ARM::BI__builtin_arm_wsr64 ||
4946 BuiltinID == ARM::BI__builtin_arm_wsrp) {
4947
4948 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr ||
4949 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4950 BuiltinID == ARM::BI__builtin_arm_rsrp;
4951
4952 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp ||
4953 BuiltinID == ARM::BI__builtin_arm_wsrp;
4954
4955 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4956 BuiltinID == ARM::BI__builtin_arm_wsr64;
4957
4958 llvm::Type *ValueType;
4959 llvm::Type *RegisterType;
4960 if (IsPointerBuiltin) {
4961 ValueType = VoidPtrTy;
4962 RegisterType = Int32Ty;
4963 } else if (Is64Bit) {
4964 ValueType = RegisterType = Int64Ty;
4965 } else {
4966 ValueType = RegisterType = Int32Ty;
4967 }
4968
4969 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
4970 }
4971
Ahmed Bougacha94df7302015-06-04 01:43:41 +00004972 // Find out if any arguments are required to be integer constant
4973 // expressions.
4974 unsigned ICEArguments = 0;
4975 ASTContext::GetBuiltinTypeError Error;
4976 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
4977 assert(Error == ASTContext::GE_None && "Should not codegen an error");
4978
John McCall7f416cc2015-09-08 08:05:57 +00004979 auto getAlignmentValue32 = [&](Address addr) -> Value* {
4980 return Builder.getInt32(addr.getAlignment().getQuantity());
4981 };
4982
4983 Address PtrOp0 = Address::invalid();
4984 Address PtrOp1 = Address::invalid();
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004985 SmallVector<Value*, 4> Ops;
Bob Wilson63c93142015-06-24 06:05:20 +00004986 bool HasExtraArg = HasExtraNeonArgument(BuiltinID);
4987 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0);
4988 for (unsigned i = 0, e = NumArgs; i != e; i++) {
Eli Friedmana5dd5682012-08-23 03:10:17 +00004989 if (i == 0) {
4990 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00004991 case NEON::BI__builtin_neon_vld1_v:
4992 case NEON::BI__builtin_neon_vld1q_v:
4993 case NEON::BI__builtin_neon_vld1q_lane_v:
4994 case NEON::BI__builtin_neon_vld1_lane_v:
4995 case NEON::BI__builtin_neon_vld1_dup_v:
4996 case NEON::BI__builtin_neon_vld1q_dup_v:
4997 case NEON::BI__builtin_neon_vst1_v:
4998 case NEON::BI__builtin_neon_vst1q_v:
4999 case NEON::BI__builtin_neon_vst1q_lane_v:
5000 case NEON::BI__builtin_neon_vst1_lane_v:
5001 case NEON::BI__builtin_neon_vst2_v:
5002 case NEON::BI__builtin_neon_vst2q_v:
5003 case NEON::BI__builtin_neon_vst2_lane_v:
5004 case NEON::BI__builtin_neon_vst2q_lane_v:
5005 case NEON::BI__builtin_neon_vst3_v:
5006 case NEON::BI__builtin_neon_vst3q_v:
5007 case NEON::BI__builtin_neon_vst3_lane_v:
5008 case NEON::BI__builtin_neon_vst3q_lane_v:
5009 case NEON::BI__builtin_neon_vst4_v:
5010 case NEON::BI__builtin_neon_vst4q_v:
5011 case NEON::BI__builtin_neon_vst4_lane_v:
5012 case NEON::BI__builtin_neon_vst4q_lane_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00005013 // Get the alignment for the argument in addition to the value;
5014 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00005015 PtrOp0 = EmitPointerWithAlignment(E->getArg(0));
5016 Ops.push_back(PtrOp0.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00005017 continue;
5018 }
5019 }
5020 if (i == 1) {
5021 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005022 case NEON::BI__builtin_neon_vld2_v:
5023 case NEON::BI__builtin_neon_vld2q_v:
5024 case NEON::BI__builtin_neon_vld3_v:
5025 case NEON::BI__builtin_neon_vld3q_v:
5026 case NEON::BI__builtin_neon_vld4_v:
5027 case NEON::BI__builtin_neon_vld4q_v:
5028 case NEON::BI__builtin_neon_vld2_lane_v:
5029 case NEON::BI__builtin_neon_vld2q_lane_v:
5030 case NEON::BI__builtin_neon_vld3_lane_v:
5031 case NEON::BI__builtin_neon_vld3q_lane_v:
5032 case NEON::BI__builtin_neon_vld4_lane_v:
5033 case NEON::BI__builtin_neon_vld4q_lane_v:
5034 case NEON::BI__builtin_neon_vld2_dup_v:
5035 case NEON::BI__builtin_neon_vld3_dup_v:
5036 case NEON::BI__builtin_neon_vld4_dup_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00005037 // Get the alignment for the argument in addition to the value;
5038 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00005039 PtrOp1 = EmitPointerWithAlignment(E->getArg(1));
5040 Ops.push_back(PtrOp1.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00005041 continue;
5042 }
5043 }
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005044
5045 if ((ICEArguments & (1 << i)) == 0) {
5046 Ops.push_back(EmitScalarExpr(E->getArg(i)));
5047 } else {
5048 // If this is required to be a constant, constant fold it so that we know
5049 // that the generated intrinsic gets a ConstantInt.
5050 llvm::APSInt Result;
5051 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
5052 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
5053 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
5054 }
Eli Friedmana5dd5682012-08-23 03:10:17 +00005055 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005056
Bob Wilson445c24f2011-08-13 05:03:46 +00005057 switch (BuiltinID) {
5058 default: break;
Bob Wilson63c93142015-06-24 06:05:20 +00005059
Tim Northoverc322f832014-01-30 14:47:51 +00005060 case NEON::BI__builtin_neon_vget_lane_i8:
5061 case NEON::BI__builtin_neon_vget_lane_i16:
5062 case NEON::BI__builtin_neon_vget_lane_i32:
5063 case NEON::BI__builtin_neon_vget_lane_i64:
5064 case NEON::BI__builtin_neon_vget_lane_f32:
5065 case NEON::BI__builtin_neon_vgetq_lane_i8:
5066 case NEON::BI__builtin_neon_vgetq_lane_i16:
5067 case NEON::BI__builtin_neon_vgetq_lane_i32:
5068 case NEON::BI__builtin_neon_vgetq_lane_i64:
5069 case NEON::BI__builtin_neon_vgetq_lane_f32:
Bob Wilson63c93142015-06-24 06:05:20 +00005070 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane");
5071
Tim Northoverc322f832014-01-30 14:47:51 +00005072 case NEON::BI__builtin_neon_vset_lane_i8:
5073 case NEON::BI__builtin_neon_vset_lane_i16:
5074 case NEON::BI__builtin_neon_vset_lane_i32:
5075 case NEON::BI__builtin_neon_vset_lane_i64:
5076 case NEON::BI__builtin_neon_vset_lane_f32:
5077 case NEON::BI__builtin_neon_vsetq_lane_i8:
5078 case NEON::BI__builtin_neon_vsetq_lane_i16:
5079 case NEON::BI__builtin_neon_vsetq_lane_i32:
5080 case NEON::BI__builtin_neon_vsetq_lane_i64:
5081 case NEON::BI__builtin_neon_vsetq_lane_f32:
Bob Wilson445c24f2011-08-13 05:03:46 +00005082 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
Tim Northover02e38602014-02-03 17:28:04 +00005083
Tim Northover02e38602014-02-03 17:28:04 +00005084 case NEON::BI__builtin_neon_vsha1h_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005085 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops,
5086 "vsha1h");
5087 case NEON::BI__builtin_neon_vsha1cq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005088 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops,
5089 "vsha1h");
5090 case NEON::BI__builtin_neon_vsha1pq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005091 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops,
5092 "vsha1h");
5093 case NEON::BI__builtin_neon_vsha1mq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005094 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops,
5095 "vsha1h");
Bob Wilson63c93142015-06-24 06:05:20 +00005096
5097 // The ARM _MoveToCoprocessor builtins put the input register value as
Simon Pilgrim532de1c2016-06-13 10:05:19 +00005098 // the first argument, but the LLVM intrinsic expects it as the third one.
5099 case ARM::BI_MoveToCoprocessor:
5100 case ARM::BI_MoveToCoprocessor2: {
5101 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ?
5102 Intrinsic::arm_mcr : Intrinsic::arm_mcr2);
5103 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0],
5104 Ops[3], Ops[4], Ops[5]});
Bob Wilson63c93142015-06-24 06:05:20 +00005105 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00005106 case ARM::BI_BitScanForward:
5107 case ARM::BI_BitScanForward64:
5108 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
5109 case ARM::BI_BitScanReverse:
5110 case ARM::BI_BitScanReverse64:
5111 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00005112
5113 case ARM::BI_InterlockedAnd64:
5114 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
5115 case ARM::BI_InterlockedExchange64:
5116 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
5117 case ARM::BI_InterlockedExchangeAdd64:
5118 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
5119 case ARM::BI_InterlockedExchangeSub64:
5120 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
5121 case ARM::BI_InterlockedOr64:
5122 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
5123 case ARM::BI_InterlockedXor64:
5124 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
5125 case ARM::BI_InterlockedDecrement64:
5126 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
5127 case ARM::BI_InterlockedIncrement64:
5128 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
Bob Wilson445c24f2011-08-13 05:03:46 +00005129 }
5130
5131 // Get the last argument, which specifies the vector type.
Bob Wilson63c93142015-06-24 06:05:20 +00005132 assert(HasExtraArg);
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005133 llvm::APSInt Result;
5134 const Expr *Arg = E->getArg(E->getNumArgs()-1);
5135 if (!Arg->isIntegerConstantExpr(Result, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00005136 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005137
Nate Begemanf568b072010-08-03 21:32:34 +00005138 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f ||
5139 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) {
5140 // Determine the overloaded type of this builtin.
Chris Lattnera5f58b02011-07-09 17:41:47 +00005141 llvm::Type *Ty;
Nate Begemanf568b072010-08-03 21:32:34 +00005142 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f)
Chris Lattnerece04092012-02-07 00:39:47 +00005143 Ty = FloatTy;
Nate Begemanf568b072010-08-03 21:32:34 +00005144 else
Chris Lattnerece04092012-02-07 00:39:47 +00005145 Ty = DoubleTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00005146
Nate Begemanf568b072010-08-03 21:32:34 +00005147 // Determine whether this is an unsigned conversion or not.
5148 bool usgn = Result.getZExtValue() == 1;
5149 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
5150
5151 // Call the appropriate intrinsic.
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005152 Function *F = CGM.getIntrinsic(Int, Ty);
Jay Foad5bd375a2011-07-15 08:37:34 +00005153 return Builder.CreateCall(F, Ops, "vcvtr");
Nate Begemanf568b072010-08-03 21:32:34 +00005154 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00005155
Nate Begemanf568b072010-08-03 21:32:34 +00005156 // Determine the type of this overloaded NEON intrinsic.
Bob Wilson98bc98c2011-11-08 01:16:11 +00005157 NeonTypeFlags Type(Result.getZExtValue());
5158 bool usgn = Type.isUnsigned();
Bob Wilson4fa993f2010-12-03 17:10:22 +00005159 bool rightShift = false;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005160
Chris Lattnerece04092012-02-07 00:39:47 +00005161 llvm::VectorType *VTy = GetNeonType(this, Type);
Chris Lattnera5f58b02011-07-09 17:41:47 +00005162 llvm::Type *Ty = VTy;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005163 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00005164 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005165
Tim Northoverac85c342014-01-30 14:47:57 +00005166 // Many NEON builtins have identical semantics and uses in ARM and
5167 // AArch64. Emit these in a single function.
Craig Topper5fc8fc22014-08-27 06:28:36 +00005168 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap);
Tim Northover8fe03d62014-02-21 11:57:24 +00005169 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
5170 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
5171 if (Builtin)
5172 return EmitCommonNeonBuiltinExpr(
5173 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00005174 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1);
Tim Northoverac85c342014-01-30 14:47:57 +00005175
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005176 unsigned Int;
5177 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00005178 default: return nullptr;
Tim Northoverc322f832014-01-30 14:47:51 +00005179 case NEON::BI__builtin_neon_vld1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005180 // Handle 64-bit integer elements as a special case. Use shuffles of
5181 // one-element vectors to avoid poor code for i64 in the backend.
5182 if (VTy->getElementType()->isIntegerTy(64)) {
5183 // Extract the other lane.
5184 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00005185 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue();
Bob Wilson2605fef2012-08-14 17:27:04 +00005186 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane));
5187 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
5188 // Load the value as a one-element vector.
5189 Ty = llvm::VectorType::get(VTy->getElementType(), 1);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005190 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5191 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005192 Value *Align = getAlignmentValue32(PtrOp0);
David Blaikie43f9bb72015-05-18 22:14:03 +00005193 Value *Ld = Builder.CreateCall(F, {Ops[0], Align});
Bob Wilson2605fef2012-08-14 17:27:04 +00005194 // Combine them.
Benjamin Kramerc385a802015-07-28 15:40:11 +00005195 uint32_t Indices[] = {1 - Lane, Lane};
5196 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices);
Bob Wilson2605fef2012-08-14 17:27:04 +00005197 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane");
5198 }
5199 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005200 case NEON::BI__builtin_neon_vld1_lane_v: {
Nate Begemaned48c852010-06-20 23:05:28 +00005201 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Steven Wu0d22f2d2015-09-09 01:37:18 +00005202 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00005203 Value *Ld = Builder.CreateLoad(PtrOp0);
Bob Wilson49708d42012-02-04 23:58:08 +00005204 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
5205 }
Tim Northoverc322f832014-01-30 14:47:51 +00005206 case NEON::BI__builtin_neon_vld2_dup_v:
5207 case NEON::BI__builtin_neon_vld3_dup_v:
5208 case NEON::BI__builtin_neon_vld4_dup_v: {
Bob Wilson0348af62010-12-10 22:54:58 +00005209 // Handle 64-bit elements as a special-case. There is no "dup" needed.
5210 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) {
5211 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005212 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005213 Int = Intrinsic::arm_neon_vld2;
Bob Wilson0348af62010-12-10 22:54:58 +00005214 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005215 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005216 Int = Intrinsic::arm_neon_vld3;
Bob Wilson0348af62010-12-10 22:54:58 +00005217 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005218 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005219 Int = Intrinsic::arm_neon_vld4;
Bob Wilson0348af62010-12-10 22:54:58 +00005220 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005221 default: llvm_unreachable("unknown vld_dup intrinsic?");
Bob Wilson0348af62010-12-10 22:54:58 +00005222 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005223 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5224 Function *F = CGM.getIntrinsic(Int, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005225 llvm::Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00005226 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup");
Bob Wilson0348af62010-12-10 22:54:58 +00005227 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5228 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005229 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Bob Wilson0348af62010-12-10 22:54:58 +00005230 }
Nate Begemaned48c852010-06-20 23:05:28 +00005231 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005232 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005233 Int = Intrinsic::arm_neon_vld2lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005234 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005235 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005236 Int = Intrinsic::arm_neon_vld3lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005237 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005238 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005239 Int = Intrinsic::arm_neon_vld4lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005240 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005241 default: llvm_unreachable("unknown vld_dup intrinsic?");
Nate Begemaned48c852010-06-20 23:05:28 +00005242 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005243 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5244 Function *F = CGM.getIntrinsic(Int, Tys);
Chris Lattner2192fe52011-07-18 04:24:23 +00005245 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType());
Jim Grosbachd3608f42012-09-21 00:18:27 +00005246
Nate Begemaned48c852010-06-20 23:05:28 +00005247 SmallVector<Value*, 6> Args;
5248 Args.push_back(Ops[1]);
5249 Args.append(STy->getNumElements(), UndefValue::get(Ty));
5250
Chris Lattner5e016ae2010-06-27 07:15:29 +00005251 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Nate Begemaned48c852010-06-20 23:05:28 +00005252 Args.push_back(CI);
John McCall7f416cc2015-09-08 08:05:57 +00005253 Args.push_back(getAlignmentValue32(PtrOp1));
Jim Grosbachd3608f42012-09-21 00:18:27 +00005254
Jay Foad5bd375a2011-07-15 08:37:34 +00005255 Ops[1] = Builder.CreateCall(F, Args, "vld_dup");
Nate Begemaned48c852010-06-20 23:05:28 +00005256 // splat lane 0 to all elts in each vector of the result.
5257 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5258 Value *Val = Builder.CreateExtractValue(Ops[1], i);
5259 Value *Elt = Builder.CreateBitCast(Val, Ty);
5260 Elt = EmitNeonSplat(Elt, CI);
5261 Elt = Builder.CreateBitCast(Elt, Val->getType());
5262 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i);
5263 }
5264 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5265 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005266 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begemaned48c852010-06-20 23:05:28 +00005267 }
Tim Northoverc322f832014-01-30 14:47:51 +00005268 case NEON::BI__builtin_neon_vqrshrn_n_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005269 Int =
5270 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005271 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005272 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005273 case NEON::BI__builtin_neon_vqrshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005274 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005275 Ops, "vqrshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005276 case NEON::BI__builtin_neon_vqshrn_n_v:
Nate Begeman91e1fea2010-06-14 05:21:25 +00005277 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005278 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005279 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005280 case NEON::BI__builtin_neon_vqshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005281 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005282 Ops, "vqshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005283 case NEON::BI__builtin_neon_vrecpe_v:
5284 case NEON::BI__builtin_neon_vrecpeq_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005285 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005286 Ops, "vrecpe");
Tim Northoverc322f832014-01-30 14:47:51 +00005287 case NEON::BI__builtin_neon_vrshrn_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005288 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005289 Ops, "vrshrn_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005290 case NEON::BI__builtin_neon_vrsra_n_v:
5291 case NEON::BI__builtin_neon_vrsraq_n_v:
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005292 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
5293 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5294 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true);
5295 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
David Blaikie43f9bb72015-05-18 22:14:03 +00005296 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]});
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005297 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005298 case NEON::BI__builtin_neon_vsri_n_v:
5299 case NEON::BI__builtin_neon_vsriq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005300 rightShift = true;
Galina Kistanova0872d6c2017-06-03 06:30:46 +00005301 LLVM_FALLTHROUGH;
Tim Northoverc322f832014-01-30 14:47:51 +00005302 case NEON::BI__builtin_neon_vsli_n_v:
5303 case NEON::BI__builtin_neon_vsliq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005304 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005305 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005306 Ops, "vsli_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005307 case NEON::BI__builtin_neon_vsra_n_v:
5308 case NEON::BI__builtin_neon_vsraq_n_v:
Nate Begeman8ed060b2010-06-11 22:57:12 +00005309 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00005310 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
Nate Begeman8ed060b2010-06-11 22:57:12 +00005311 return Builder.CreateAdd(Ops[0], Ops[1]);
Tim Northoverc322f832014-01-30 14:47:51 +00005312 case NEON::BI__builtin_neon_vst1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005313 // Handle 64-bit integer elements as a special case. Use a shuffle to get
5314 // a one-element vector and avoid poor code for i64 in the backend.
5315 if (VTy->getElementType()->isIntegerTy(64)) {
5316 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5317 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2]));
5318 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
John McCall7f416cc2015-09-08 08:05:57 +00005319 Ops[2] = getAlignmentValue32(PtrOp0);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005320 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()};
Bob Wilson2605fef2012-08-14 17:27:04 +00005321 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005322 Tys), Ops);
Bob Wilson2605fef2012-08-14 17:27:04 +00005323 }
5324 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005325 case NEON::BI__builtin_neon_vst1_lane_v: {
Nate Begeman8ed060b2010-06-11 22:57:12 +00005326 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5327 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
5328 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00005329 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty));
Bob Wilson49708d42012-02-04 23:58:08 +00005330 return St;
5331 }
Tim Northoverc322f832014-01-30 14:47:51 +00005332 case NEON::BI__builtin_neon_vtbl1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005333 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),
5334 Ops, "vtbl1");
Tim Northoverc322f832014-01-30 14:47:51 +00005335 case NEON::BI__builtin_neon_vtbl2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005336 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2),
5337 Ops, "vtbl2");
Tim Northoverc322f832014-01-30 14:47:51 +00005338 case NEON::BI__builtin_neon_vtbl3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005339 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3),
5340 Ops, "vtbl3");
Tim Northoverc322f832014-01-30 14:47:51 +00005341 case NEON::BI__builtin_neon_vtbl4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005342 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4),
5343 Ops, "vtbl4");
Tim Northoverc322f832014-01-30 14:47:51 +00005344 case NEON::BI__builtin_neon_vtbx1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005345 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1),
5346 Ops, "vtbx1");
Tim Northoverc322f832014-01-30 14:47:51 +00005347 case NEON::BI__builtin_neon_vtbx2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005348 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2),
5349 Ops, "vtbx2");
Tim Northoverc322f832014-01-30 14:47:51 +00005350 case NEON::BI__builtin_neon_vtbx3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005351 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3),
5352 Ops, "vtbx3");
Tim Northoverc322f832014-01-30 14:47:51 +00005353 case NEON::BI__builtin_neon_vtbx4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005354 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4),
5355 Ops, "vtbx4");
Chris Lattner5cc15e02010-03-03 19:03:45 +00005356 }
5357}
5358
Tim Northover573cbee2014-05-24 12:52:07 +00005359static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID,
Tim Northovera2ee4332014-03-29 15:09:45 +00005360 const CallExpr *E,
5361 SmallVectorImpl<Value *> &Ops) {
5362 unsigned int Int = 0;
Craig Topper8a13c412014-05-21 05:09:00 +00005363 const char *s = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005364
Tim Northovera2ee4332014-03-29 15:09:45 +00005365 switch (BuiltinID) {
5366 default:
Craig Topper8a13c412014-05-21 05:09:00 +00005367 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005368 case NEON::BI__builtin_neon_vtbl1_v:
5369 case NEON::BI__builtin_neon_vqtbl1_v:
5370 case NEON::BI__builtin_neon_vqtbl1q_v:
5371 case NEON::BI__builtin_neon_vtbl2_v:
5372 case NEON::BI__builtin_neon_vqtbl2_v:
5373 case NEON::BI__builtin_neon_vqtbl2q_v:
5374 case NEON::BI__builtin_neon_vtbl3_v:
5375 case NEON::BI__builtin_neon_vqtbl3_v:
5376 case NEON::BI__builtin_neon_vqtbl3q_v:
5377 case NEON::BI__builtin_neon_vtbl4_v:
5378 case NEON::BI__builtin_neon_vqtbl4_v:
5379 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005380 break;
5381 case NEON::BI__builtin_neon_vtbx1_v:
5382 case NEON::BI__builtin_neon_vqtbx1_v:
5383 case NEON::BI__builtin_neon_vqtbx1q_v:
5384 case NEON::BI__builtin_neon_vtbx2_v:
5385 case NEON::BI__builtin_neon_vqtbx2_v:
5386 case NEON::BI__builtin_neon_vqtbx2q_v:
5387 case NEON::BI__builtin_neon_vtbx3_v:
5388 case NEON::BI__builtin_neon_vqtbx3_v:
5389 case NEON::BI__builtin_neon_vqtbx3q_v:
5390 case NEON::BI__builtin_neon_vtbx4_v:
5391 case NEON::BI__builtin_neon_vqtbx4_v:
5392 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005393 break;
5394 }
5395
5396 assert(E->getNumArgs() >= 3);
5397
5398 // Get the last argument, which specifies the vector type.
5399 llvm::APSInt Result;
5400 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
5401 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00005402 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005403
5404 // Determine the type of this overloaded NEON intrinsic.
5405 NeonTypeFlags Type(Result.getZExtValue());
Benjamin Kramerc385a802015-07-28 15:40:11 +00005406 llvm::VectorType *Ty = GetNeonType(&CGF, Type);
Tim Northovera2ee4332014-03-29 15:09:45 +00005407 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00005408 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005409
Tim Northovera2ee4332014-03-29 15:09:45 +00005410 CodeGen::CGBuilderTy &Builder = CGF.Builder;
5411
5412 // AArch64 scalar builtins are not overloaded, they do not have an extra
5413 // argument that specifies the vector type, need to handle each case.
Tim Northovera2ee4332014-03-29 15:09:45 +00005414 switch (BuiltinID) {
5415 case NEON::BI__builtin_neon_vtbl1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005416 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr,
5417 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1,
5418 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005419 }
5420 case NEON::BI__builtin_neon_vtbl2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005421 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr,
5422 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1,
5423 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005424 }
5425 case NEON::BI__builtin_neon_vtbl3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005426 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr,
5427 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2,
5428 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005429 }
5430 case NEON::BI__builtin_neon_vtbl4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005431 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr,
5432 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2,
5433 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005434 }
5435 case NEON::BI__builtin_neon_vtbx1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005436 Value *TblRes =
5437 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2],
5438 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005439
Benjamin Kramerc385a802015-07-28 15:40:11 +00005440 llvm::Constant *EightV = ConstantInt::get(Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00005441 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV);
5442 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5443
5444 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5445 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5446 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5447 }
5448 case NEON::BI__builtin_neon_vtbx2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005449 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0],
5450 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1,
5451 "vtbx1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005452 }
5453 case NEON::BI__builtin_neon_vtbx3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005454 Value *TblRes =
5455 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4],
5456 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005457
Benjamin Kramerc385a802015-07-28 15:40:11 +00005458 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24);
Tim Northovera2ee4332014-03-29 15:09:45 +00005459 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4],
5460 TwentyFourV);
5461 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5462
5463 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5464 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5465 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5466 }
5467 case NEON::BI__builtin_neon_vtbx4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005468 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0],
5469 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2,
5470 "vtbx2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005471 }
5472 case NEON::BI__builtin_neon_vqtbl1_v:
5473 case NEON::BI__builtin_neon_vqtbl1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005474 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005475 case NEON::BI__builtin_neon_vqtbl2_v:
5476 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00005477 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005478 case NEON::BI__builtin_neon_vqtbl3_v:
5479 case NEON::BI__builtin_neon_vqtbl3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005480 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005481 case NEON::BI__builtin_neon_vqtbl4_v:
5482 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005483 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005484 case NEON::BI__builtin_neon_vqtbx1_v:
5485 case NEON::BI__builtin_neon_vqtbx1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005486 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005487 case NEON::BI__builtin_neon_vqtbx2_v:
5488 case NEON::BI__builtin_neon_vqtbx2q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005489 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005490 case NEON::BI__builtin_neon_vqtbx3_v:
5491 case NEON::BI__builtin_neon_vqtbx3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005492 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005493 case NEON::BI__builtin_neon_vqtbx4_v:
5494 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005495 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005496 }
5497 }
5498
5499 if (!Int)
Craig Topper8a13c412014-05-21 05:09:00 +00005500 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005501
5502 Function *F = CGF.CGM.getIntrinsic(Int, Ty);
5503 return CGF.EmitNeonCall(F, Ops, s);
5504}
5505
5506Value *CodeGenFunction::vectorWrapScalar16(Value *Op) {
5507 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
5508 Op = Builder.CreateBitCast(Op, Int16Ty);
5509 Value *V = UndefValue::get(VTy);
Michael J. Spencerdd597752014-05-31 00:22:12 +00005510 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00005511 Op = Builder.CreateInsertElement(V, Op, CI);
5512 return Op;
5513}
5514
Tim Northover573cbee2014-05-24 12:52:07 +00005515Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
5516 const CallExpr *E) {
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005517 unsigned HintID = static_cast<unsigned>(-1);
5518 switch (BuiltinID) {
5519 default: break;
Yi Kong4d5e23f2014-07-14 15:20:09 +00005520 case AArch64::BI__builtin_arm_nop:
5521 HintID = 0;
5522 break;
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005523 case AArch64::BI__builtin_arm_yield:
5524 HintID = 1;
5525 break;
5526 case AArch64::BI__builtin_arm_wfe:
5527 HintID = 2;
5528 break;
5529 case AArch64::BI__builtin_arm_wfi:
5530 HintID = 3;
5531 break;
5532 case AArch64::BI__builtin_arm_sev:
5533 HintID = 4;
5534 break;
5535 case AArch64::BI__builtin_arm_sevl:
5536 HintID = 5;
5537 break;
5538 }
5539
5540 if (HintID != static_cast<unsigned>(-1)) {
5541 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint);
5542 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
5543 }
5544
Yi Konga5548432014-08-13 19:18:20 +00005545 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
5546 Value *Address = EmitScalarExpr(E->getArg(0));
5547 Value *RW = EmitScalarExpr(E->getArg(1));
5548 Value *CacheLevel = EmitScalarExpr(E->getArg(2));
5549 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3));
5550 Value *IsData = EmitScalarExpr(E->getArg(4));
5551
5552 Value *Locality = nullptr;
5553 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) {
5554 // Temporal fetch, needs to convert cache level to locality.
5555 Locality = llvm::ConstantInt::get(Int32Ty,
5556 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3);
5557 } else {
5558 // Streaming fetch.
5559 Locality = llvm::ConstantInt::get(Int32Ty, 0);
5560 }
5561
5562 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify
5563 // PLDL3STRM or PLDL2STRM.
5564 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00005565 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Konga5548432014-08-13 19:18:20 +00005566 }
5567
Jim Grosbach79140822014-06-16 21:56:02 +00005568 if (BuiltinID == AArch64::BI__builtin_arm_rbit) {
5569 assert((getContext().getTypeSize(E->getType()) == 32) &&
5570 "rbit of unusual size!");
5571 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5572 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005573 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005574 }
5575 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) {
5576 assert((getContext().getTypeSize(E->getType()) == 64) &&
5577 "rbit of unusual size!");
5578 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5579 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005580 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005581 }
5582
Tim Northover573cbee2014-05-24 12:52:07 +00005583 if (BuiltinID == AArch64::BI__clear_cache) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005584 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
5585 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00005586 Value *Ops[2];
Tim Northovera2ee4332014-03-29 15:09:45 +00005587 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00005588 Ops[i] = EmitScalarExpr(E->getArg(i));
Tim Northovera2ee4332014-03-29 15:09:45 +00005589 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
5590 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
5591 StringRef Name = FD->getName();
5592 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
5593 }
5594
Tim Northover3acd6bd2014-07-02 12:56:02 +00005595 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5596 BuiltinID == AArch64::BI__builtin_arm_ldaex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005597 getContext().getTypeSize(E->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005598 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5599 ? Intrinsic::aarch64_ldaxp
5600 : Intrinsic::aarch64_ldxp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005601
5602 Value *LdPtr = EmitScalarExpr(E->getArg(0));
5603 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
5604 "ldxp");
5605
5606 Value *Val0 = Builder.CreateExtractValue(Val, 1);
5607 Value *Val1 = Builder.CreateExtractValue(Val, 0);
5608 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
5609 Val0 = Builder.CreateZExt(Val0, Int128Ty);
5610 Val1 = Builder.CreateZExt(Val1, Int128Ty);
5611
5612 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
5613 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
5614 Val = Builder.CreateOr(Val, Val1);
5615 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Tim Northover3acd6bd2014-07-02 12:56:02 +00005616 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5617 BuiltinID == AArch64::BI__builtin_arm_ldaex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005618 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
5619
5620 QualType Ty = E->getType();
5621 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005622 llvm::Type *PtrTy = llvm::IntegerType::get(
5623 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
5624 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005625
Tim Northover3acd6bd2014-07-02 12:56:02 +00005626 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5627 ? Intrinsic::aarch64_ldaxr
5628 : Intrinsic::aarch64_ldxr,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005629 PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005630 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
5631
5632 if (RealResTy->isPointerTy())
5633 return Builder.CreateIntToPtr(Val, RealResTy);
5634
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005635 llvm::Type *IntResTy = llvm::IntegerType::get(
5636 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northovera2ee4332014-03-29 15:09:45 +00005637 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
5638 return Builder.CreateBitCast(Val, RealResTy);
5639 }
5640
Tim Northover3acd6bd2014-07-02 12:56:02 +00005641 if ((BuiltinID == AArch64::BI__builtin_arm_strex ||
5642 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005643 getContext().getTypeSize(E->getArg(0)->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005644 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5645 ? Intrinsic::aarch64_stlxp
5646 : Intrinsic::aarch64_stxp);
Serge Guelton1d993272017-05-09 19:31:30 +00005647 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005648
John McCall7f416cc2015-09-08 08:05:57 +00005649 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
5650 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true);
Tim Northovera2ee4332014-03-29 15:09:45 +00005651
John McCall7f416cc2015-09-08 08:05:57 +00005652 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy));
5653 llvm::Value *Val = Builder.CreateLoad(Tmp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005654
5655 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
5656 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
5657 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)),
5658 Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00005659 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp");
5660 }
5661
5662 if (BuiltinID == AArch64::BI__builtin_arm_strex ||
5663 BuiltinID == AArch64::BI__builtin_arm_stlex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005664 Value *StoreVal = EmitScalarExpr(E->getArg(0));
5665 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
5666
5667 QualType Ty = E->getArg(0)->getType();
5668 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
5669 getContext().getTypeSize(Ty));
5670 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
5671
5672 if (StoreVal->getType()->isPointerTy())
5673 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty);
5674 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005675 llvm::Type *IntTy = llvm::IntegerType::get(
5676 getLLVMContext(),
5677 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
5678 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005679 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
5680 }
5681
Tim Northover3acd6bd2014-07-02 12:56:02 +00005682 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5683 ? Intrinsic::aarch64_stlxr
5684 : Intrinsic::aarch64_stxr,
5685 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00005686 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
Tim Northovera2ee4332014-03-29 15:09:45 +00005687 }
5688
Tim Northover573cbee2014-05-24 12:52:07 +00005689 if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
5690 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00005691 return Builder.CreateCall(F);
Tim Northovera2ee4332014-03-29 15:09:45 +00005692 }
5693
5694 // CRC32
5695 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
5696 switch (BuiltinID) {
Tim Northover573cbee2014-05-24 12:52:07 +00005697 case AArch64::BI__builtin_arm_crc32b:
5698 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break;
5699 case AArch64::BI__builtin_arm_crc32cb:
5700 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break;
5701 case AArch64::BI__builtin_arm_crc32h:
5702 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break;
5703 case AArch64::BI__builtin_arm_crc32ch:
5704 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break;
5705 case AArch64::BI__builtin_arm_crc32w:
5706 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break;
5707 case AArch64::BI__builtin_arm_crc32cw:
5708 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break;
5709 case AArch64::BI__builtin_arm_crc32d:
5710 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break;
5711 case AArch64::BI__builtin_arm_crc32cd:
5712 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005713 }
5714
5715 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
5716 Value *Arg0 = EmitScalarExpr(E->getArg(0));
5717 Value *Arg1 = EmitScalarExpr(E->getArg(1));
5718 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
5719
5720 llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
5721 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy);
5722
David Blaikie43f9bb72015-05-18 22:14:03 +00005723 return Builder.CreateCall(F, {Arg0, Arg1});
Tim Northovera2ee4332014-03-29 15:09:45 +00005724 }
5725
Luke Cheeseman59b2d832015-06-15 17:51:01 +00005726 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
5727 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5728 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5729 BuiltinID == AArch64::BI__builtin_arm_wsr ||
5730 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
5731 BuiltinID == AArch64::BI__builtin_arm_wsrp) {
5732
5733 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr ||
5734 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5735 BuiltinID == AArch64::BI__builtin_arm_rsrp;
5736
5737 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5738 BuiltinID == AArch64::BI__builtin_arm_wsrp;
5739
5740 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr &&
5741 BuiltinID != AArch64::BI__builtin_arm_wsr;
5742
5743 llvm::Type *ValueType;
5744 llvm::Type *RegisterType = Int64Ty;
5745 if (IsPointerBuiltin) {
5746 ValueType = VoidPtrTy;
5747 } else if (Is64Bit) {
5748 ValueType = Int64Ty;
5749 } else {
5750 ValueType = Int32Ty;
5751 }
5752
5753 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
5754 }
5755
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005756 // Find out if any arguments are required to be integer constant
5757 // expressions.
5758 unsigned ICEArguments = 0;
5759 ASTContext::GetBuiltinTypeError Error;
5760 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
5761 assert(Error == ASTContext::GE_None && "Should not codegen an error");
5762
Tim Northovera2ee4332014-03-29 15:09:45 +00005763 llvm::SmallVector<Value*, 4> Ops;
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005764 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
5765 if ((ICEArguments & (1 << i)) == 0) {
5766 Ops.push_back(EmitScalarExpr(E->getArg(i)));
5767 } else {
5768 // If this is required to be a constant, constant fold it so that we know
5769 // that the generated intrinsic gets a ConstantInt.
5770 llvm::APSInt Result;
5771 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
5772 assert(IsConst && "Constant arg isn't actually constant?");
5773 (void)IsConst;
5774 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
5775 }
5776 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005777
Craig Topper5fc8fc22014-08-27 06:28:36 +00005778 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
Tim Northovera2ee4332014-03-29 15:09:45 +00005779 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
Tim Northover573cbee2014-05-24 12:52:07 +00005780 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00005781
5782 if (Builtin) {
5783 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1)));
5784 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E);
5785 assert(Result && "SISD intrinsic should have been handled");
5786 return Result;
5787 }
5788
5789 llvm::APSInt Result;
5790 const Expr *Arg = E->getArg(E->getNumArgs()-1);
5791 NeonTypeFlags Type(0);
5792 if (Arg->isIntegerConstantExpr(Result, getContext()))
5793 // Determine the type of this overloaded NEON intrinsic.
5794 Type = NeonTypeFlags(Result.getZExtValue());
5795
5796 bool usgn = Type.isUnsigned();
5797 bool quad = Type.isQuad();
5798
5799 // Handle non-overloaded intrinsics first.
5800 switch (BuiltinID) {
5801 default: break;
Tim Northoverb17f9a42014-04-01 12:23:08 +00005802 case NEON::BI__builtin_neon_vldrq_p128: {
Peter Collingbourneb367c562016-11-28 22:30:21 +00005803 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128);
5804 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005805 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy);
Peter Collingbourneb367c562016-11-28 22:30:21 +00005806 return Builder.CreateAlignedLoad(Int128Ty, Ptr,
5807 CharUnits::fromQuantity(16));
Tim Northoverb17f9a42014-04-01 12:23:08 +00005808 }
5809 case NEON::BI__builtin_neon_vstrq_p128: {
5810 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128);
5811 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy);
John McCall7f416cc2015-09-08 08:05:57 +00005812 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005813 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005814 case NEON::BI__builtin_neon_vcvts_u32_f32:
5815 case NEON::BI__builtin_neon_vcvtd_u64_f64:
5816 usgn = true;
5817 // FALL THROUGH
5818 case NEON::BI__builtin_neon_vcvts_s32_f32:
5819 case NEON::BI__builtin_neon_vcvtd_s64_f64: {
5820 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5821 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5822 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5823 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5824 Ops[0] = Builder.CreateBitCast(Ops[0], FTy);
5825 if (usgn)
5826 return Builder.CreateFPToUI(Ops[0], InTy);
5827 return Builder.CreateFPToSI(Ops[0], InTy);
5828 }
5829 case NEON::BI__builtin_neon_vcvts_f32_u32:
5830 case NEON::BI__builtin_neon_vcvtd_f64_u64:
5831 usgn = true;
5832 // FALL THROUGH
5833 case NEON::BI__builtin_neon_vcvts_f32_s32:
5834 case NEON::BI__builtin_neon_vcvtd_f64_s64: {
5835 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5836 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5837 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5838 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5839 Ops[0] = Builder.CreateBitCast(Ops[0], InTy);
5840 if (usgn)
5841 return Builder.CreateUIToFP(Ops[0], FTy);
5842 return Builder.CreateSIToFP(Ops[0], FTy);
5843 }
5844 case NEON::BI__builtin_neon_vpaddd_s64: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005845 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005846 Value *Vec = EmitScalarExpr(E->getArg(0));
5847 // The vector is v2f64, so make sure it's bitcast to that.
5848 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005849 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5850 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005851 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5852 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5853 // Pairwise addition of a v2f64 into a scalar f64.
5854 return Builder.CreateAdd(Op0, Op1, "vpaddd");
5855 }
5856 case NEON::BI__builtin_neon_vpaddd_f64: {
5857 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005858 llvm::VectorType::get(DoubleTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005859 Value *Vec = EmitScalarExpr(E->getArg(0));
5860 // The vector is v2f64, so make sure it's bitcast to that.
5861 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005862 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5863 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005864 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5865 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5866 // Pairwise addition of a v2f64 into a scalar f64.
5867 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5868 }
5869 case NEON::BI__builtin_neon_vpadds_f32: {
5870 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005871 llvm::VectorType::get(FloatTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005872 Value *Vec = EmitScalarExpr(E->getArg(0));
5873 // The vector is v2f32, so make sure it's bitcast to that.
5874 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005875 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5876 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005877 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5878 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5879 // Pairwise addition of a v2f32 into a scalar f32.
5880 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5881 }
5882 case NEON::BI__builtin_neon_vceqzd_s64:
5883 case NEON::BI__builtin_neon_vceqzd_f64:
5884 case NEON::BI__builtin_neon_vceqzs_f32:
5885 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5886 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005887 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5888 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005889 case NEON::BI__builtin_neon_vcgezd_s64:
5890 case NEON::BI__builtin_neon_vcgezd_f64:
5891 case NEON::BI__builtin_neon_vcgezs_f32:
5892 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5893 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005894 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5895 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005896 case NEON::BI__builtin_neon_vclezd_s64:
5897 case NEON::BI__builtin_neon_vclezd_f64:
5898 case NEON::BI__builtin_neon_vclezs_f32:
5899 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5900 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005901 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5902 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005903 case NEON::BI__builtin_neon_vcgtzd_s64:
5904 case NEON::BI__builtin_neon_vcgtzd_f64:
5905 case NEON::BI__builtin_neon_vcgtzs_f32:
5906 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5907 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005908 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5909 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005910 case NEON::BI__builtin_neon_vcltzd_s64:
5911 case NEON::BI__builtin_neon_vcltzd_f64:
5912 case NEON::BI__builtin_neon_vcltzs_f32:
5913 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5914 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005915 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5916 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005917
5918 case NEON::BI__builtin_neon_vceqzd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00005919 Ops.push_back(EmitScalarExpr(E->getArg(0)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00005920 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5921 Ops[0] =
5922 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty));
5923 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005924 }
5925 case NEON::BI__builtin_neon_vceqd_f64:
5926 case NEON::BI__builtin_neon_vcled_f64:
5927 case NEON::BI__builtin_neon_vcltd_f64:
5928 case NEON::BI__builtin_neon_vcged_f64:
5929 case NEON::BI__builtin_neon_vcgtd_f64: {
5930 llvm::CmpInst::Predicate P;
5931 switch (BuiltinID) {
5932 default: llvm_unreachable("missing builtin ID in switch!");
5933 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break;
5934 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break;
5935 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break;
5936 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break;
5937 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break;
5938 }
5939 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5940 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
5941 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
5942 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5943 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd");
5944 }
5945 case NEON::BI__builtin_neon_vceqs_f32:
5946 case NEON::BI__builtin_neon_vcles_f32:
5947 case NEON::BI__builtin_neon_vclts_f32:
5948 case NEON::BI__builtin_neon_vcges_f32:
5949 case NEON::BI__builtin_neon_vcgts_f32: {
5950 llvm::CmpInst::Predicate P;
5951 switch (BuiltinID) {
5952 default: llvm_unreachable("missing builtin ID in switch!");
5953 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break;
5954 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break;
5955 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break;
5956 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break;
5957 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break;
5958 }
5959 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5960 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
5961 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy);
5962 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5963 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd");
5964 }
5965 case NEON::BI__builtin_neon_vceqd_s64:
5966 case NEON::BI__builtin_neon_vceqd_u64:
5967 case NEON::BI__builtin_neon_vcgtd_s64:
5968 case NEON::BI__builtin_neon_vcgtd_u64:
5969 case NEON::BI__builtin_neon_vcltd_s64:
5970 case NEON::BI__builtin_neon_vcltd_u64:
5971 case NEON::BI__builtin_neon_vcged_u64:
5972 case NEON::BI__builtin_neon_vcged_s64:
5973 case NEON::BI__builtin_neon_vcled_u64:
5974 case NEON::BI__builtin_neon_vcled_s64: {
5975 llvm::CmpInst::Predicate P;
5976 switch (BuiltinID) {
5977 default: llvm_unreachable("missing builtin ID in switch!");
5978 case NEON::BI__builtin_neon_vceqd_s64:
5979 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break;
5980 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break;
5981 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break;
5982 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break;
5983 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break;
5984 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break;
5985 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break;
5986 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break;
5987 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break;
5988 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005989 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Tim Northover0c68faa2014-03-31 15:47:09 +00005990 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5991 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005992 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]);
Tim Northover0c68faa2014-03-31 15:47:09 +00005993 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005994 }
5995 case NEON::BI__builtin_neon_vtstd_s64:
5996 case NEON::BI__builtin_neon_vtstd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00005997 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00005998 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5999 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006000 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
6001 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
Benjamin Kramerc385a802015-07-28 15:40:11 +00006002 llvm::Constant::getNullValue(Int64Ty));
6003 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd");
Tim Northovera2ee4332014-03-29 15:09:45 +00006004 }
6005 case NEON::BI__builtin_neon_vset_lane_i8:
6006 case NEON::BI__builtin_neon_vset_lane_i16:
6007 case NEON::BI__builtin_neon_vset_lane_i32:
6008 case NEON::BI__builtin_neon_vset_lane_i64:
6009 case NEON::BI__builtin_neon_vset_lane_f32:
6010 case NEON::BI__builtin_neon_vsetq_lane_i8:
6011 case NEON::BI__builtin_neon_vsetq_lane_i16:
6012 case NEON::BI__builtin_neon_vsetq_lane_i32:
6013 case NEON::BI__builtin_neon_vsetq_lane_i64:
6014 case NEON::BI__builtin_neon_vsetq_lane_f32:
6015 Ops.push_back(EmitScalarExpr(E->getArg(2)));
6016 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
6017 case NEON::BI__builtin_neon_vset_lane_f64:
6018 // The vector type needs a cast for the v1f64 variant.
6019 Ops[1] = Builder.CreateBitCast(Ops[1],
6020 llvm::VectorType::get(DoubleTy, 1));
6021 Ops.push_back(EmitScalarExpr(E->getArg(2)));
6022 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
6023 case NEON::BI__builtin_neon_vsetq_lane_f64:
6024 // The vector type needs a cast for the v2f64 variant.
6025 Ops[1] = Builder.CreateBitCast(Ops[1],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006026 llvm::VectorType::get(DoubleTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006027 Ops.push_back(EmitScalarExpr(E->getArg(2)));
6028 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
6029
6030 case NEON::BI__builtin_neon_vget_lane_i8:
6031 case NEON::BI__builtin_neon_vdupb_lane_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006032 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00006033 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6034 "vget_lane");
6035 case NEON::BI__builtin_neon_vgetq_lane_i8:
6036 case NEON::BI__builtin_neon_vdupb_laneq_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006037 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16));
Tim Northovera2ee4332014-03-29 15:09:45 +00006038 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6039 "vgetq_lane");
6040 case NEON::BI__builtin_neon_vget_lane_i16:
6041 case NEON::BI__builtin_neon_vduph_lane_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006042 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00006043 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6044 "vget_lane");
6045 case NEON::BI__builtin_neon_vgetq_lane_i16:
6046 case NEON::BI__builtin_neon_vduph_laneq_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006047 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00006048 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6049 "vgetq_lane");
6050 case NEON::BI__builtin_neon_vget_lane_i32:
6051 case NEON::BI__builtin_neon_vdups_lane_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006052 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006053 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6054 "vget_lane");
6055 case NEON::BI__builtin_neon_vdups_lane_f32:
6056 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006057 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006058 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6059 "vdups_lane");
6060 case NEON::BI__builtin_neon_vgetq_lane_i32:
6061 case NEON::BI__builtin_neon_vdups_laneq_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006062 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00006063 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6064 "vgetq_lane");
6065 case NEON::BI__builtin_neon_vget_lane_i64:
6066 case NEON::BI__builtin_neon_vdupd_lane_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006067 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00006068 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6069 "vget_lane");
6070 case NEON::BI__builtin_neon_vdupd_lane_f64:
6071 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006072 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00006073 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6074 "vdupd_lane");
6075 case NEON::BI__builtin_neon_vgetq_lane_i64:
6076 case NEON::BI__builtin_neon_vdupd_laneq_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006077 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006078 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6079 "vgetq_lane");
6080 case NEON::BI__builtin_neon_vget_lane_f32:
6081 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006082 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006083 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6084 "vget_lane");
6085 case NEON::BI__builtin_neon_vget_lane_f64:
6086 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006087 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00006088 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6089 "vget_lane");
6090 case NEON::BI__builtin_neon_vgetq_lane_f32:
6091 case NEON::BI__builtin_neon_vdups_laneq_f32:
6092 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006093 llvm::VectorType::get(FloatTy, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00006094 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6095 "vgetq_lane");
6096 case NEON::BI__builtin_neon_vgetq_lane_f64:
6097 case NEON::BI__builtin_neon_vdupd_laneq_f64:
6098 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006099 llvm::VectorType::get(DoubleTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006100 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6101 "vgetq_lane");
6102 case NEON::BI__builtin_neon_vaddd_s64:
6103 case NEON::BI__builtin_neon_vaddd_u64:
6104 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd");
6105 case NEON::BI__builtin_neon_vsubd_s64:
6106 case NEON::BI__builtin_neon_vsubd_u64:
6107 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd");
6108 case NEON::BI__builtin_neon_vqdmlalh_s16:
6109 case NEON::BI__builtin_neon_vqdmlslh_s16: {
6110 SmallVector<Value *, 2> ProductOps;
6111 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
6112 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2))));
6113 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00006114 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006115 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00006116 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006117 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
6118
6119 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
Tim Northover573cbee2014-05-24 12:52:07 +00006120 ? Intrinsic::aarch64_neon_sqadd
6121 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006122 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl");
6123 }
6124 case NEON::BI__builtin_neon_vqshlud_n_s64: {
6125 Ops.push_back(EmitScalarExpr(E->getArg(1)));
6126 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Tim Northover573cbee2014-05-24 12:52:07 +00006127 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty),
Hao Liua19a2e22014-04-28 07:36:12 +00006128 Ops, "vqshlu_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006129 }
6130 case NEON::BI__builtin_neon_vqshld_n_u64:
6131 case NEON::BI__builtin_neon_vqshld_n_s64: {
6132 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006133 ? Intrinsic::aarch64_neon_uqshl
6134 : Intrinsic::aarch64_neon_sqshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006135 Ops.push_back(EmitScalarExpr(E->getArg(1)));
6136 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Hao Liua19a2e22014-04-28 07:36:12 +00006137 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006138 }
6139 case NEON::BI__builtin_neon_vrshrd_n_u64:
6140 case NEON::BI__builtin_neon_vrshrd_n_s64: {
6141 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006142 ? Intrinsic::aarch64_neon_urshl
6143 : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006144 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Hao Liua19a2e22014-04-28 07:36:12 +00006145 int SV = cast<ConstantInt>(Ops[1])->getSExtValue();
6146 Ops[1] = ConstantInt::get(Int64Ty, -SV);
6147 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006148 }
6149 case NEON::BI__builtin_neon_vrsrad_n_u64:
6150 case NEON::BI__builtin_neon_vrsrad_n_s64: {
6151 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006152 ? Intrinsic::aarch64_neon_urshl
6153 : Intrinsic::aarch64_neon_srshl;
Tim Northover0c68faa2014-03-31 15:47:09 +00006154 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
6155 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2))));
David Blaikie43f9bb72015-05-18 22:14:03 +00006156 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty),
6157 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)});
Tim Northover0c68faa2014-03-31 15:47:09 +00006158 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00006159 }
6160 case NEON::BI__builtin_neon_vshld_n_s64:
6161 case NEON::BI__builtin_neon_vshld_n_u64: {
6162 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
6163 return Builder.CreateShl(
Hao Liu9f9492b2014-05-14 08:59:30 +00006164 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006165 }
6166 case NEON::BI__builtin_neon_vshrd_n_s64: {
6167 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
6168 return Builder.CreateAShr(
6169 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
6170 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00006171 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006172 }
6173 case NEON::BI__builtin_neon_vshrd_n_u64: {
6174 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006175 uint64_t ShiftAmt = Amt->getZExtValue();
6176 // Right-shifting an unsigned value by its size yields 0.
6177 if (ShiftAmt == 64)
6178 return ConstantInt::get(Int64Ty, 0);
6179 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt),
6180 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006181 }
6182 case NEON::BI__builtin_neon_vsrad_n_s64: {
6183 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
6184 Ops[1] = Builder.CreateAShr(
6185 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
6186 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00006187 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006188 return Builder.CreateAdd(Ops[0], Ops[1]);
6189 }
6190 case NEON::BI__builtin_neon_vsrad_n_u64: {
6191 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006192 uint64_t ShiftAmt = Amt->getZExtValue();
6193 // Right-shifting an unsigned value by its size yields 0.
6194 // As Op + 0 = Op, return Ops[0] directly.
6195 if (ShiftAmt == 64)
6196 return Ops[0];
6197 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt),
6198 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006199 return Builder.CreateAdd(Ops[0], Ops[1]);
6200 }
6201 case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
6202 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
6203 case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
6204 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
6205 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6206 "lane");
6207 SmallVector<Value *, 2> ProductOps;
6208 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
6209 ProductOps.push_back(vectorWrapScalar16(Ops[2]));
6210 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00006211 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006212 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00006213 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006214 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
6215 Ops.pop_back();
6216
6217 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
6218 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
Tim Northover573cbee2014-05-24 12:52:07 +00006219 ? Intrinsic::aarch64_neon_sqadd
6220 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006221 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl");
6222 }
6223 case NEON::BI__builtin_neon_vqdmlals_s32:
6224 case NEON::BI__builtin_neon_vqdmlsls_s32: {
6225 SmallVector<Value *, 2> ProductOps;
6226 ProductOps.push_back(Ops[1]);
6227 ProductOps.push_back(EmitScalarExpr(E->getArg(2)));
6228 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006229 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006230 ProductOps, "vqdmlXl");
6231
6232 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
Tim Northover573cbee2014-05-24 12:52:07 +00006233 ? Intrinsic::aarch64_neon_sqadd
6234 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006235 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl");
6236 }
6237 case NEON::BI__builtin_neon_vqdmlals_lane_s32:
6238 case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
6239 case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
6240 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
6241 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6242 "lane");
6243 SmallVector<Value *, 2> ProductOps;
6244 ProductOps.push_back(Ops[1]);
6245 ProductOps.push_back(Ops[2]);
6246 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006247 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006248 ProductOps, "vqdmlXl");
6249 Ops.pop_back();
6250
6251 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
6252 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
Tim Northover573cbee2014-05-24 12:52:07 +00006253 ? Intrinsic::aarch64_neon_sqadd
6254 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006255 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl");
6256 }
6257 }
6258
6259 llvm::VectorType *VTy = GetNeonType(this, Type);
6260 llvm::Type *Ty = VTy;
6261 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00006262 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006263
Tim Northover573cbee2014-05-24 12:52:07 +00006264 // Not all intrinsics handled by the common case work for AArch64 yet, so only
Tim Northovera2ee4332014-03-29 15:09:45 +00006265 // defer to common code if it's been added to our special map.
Tim Northover573cbee2014-05-24 12:52:07 +00006266 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID,
6267 AArch64SIMDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00006268
6269 if (Builtin)
6270 return EmitCommonNeonBuiltinExpr(
6271 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00006272 Builtin->NameHint, Builtin->TypeModifier, E, Ops,
6273 /*never use addresses*/ Address::invalid(), Address::invalid());
Tim Northovera2ee4332014-03-29 15:09:45 +00006274
Tim Northover573cbee2014-05-24 12:52:07 +00006275 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops))
Tim Northovera2ee4332014-03-29 15:09:45 +00006276 return V;
6277
6278 unsigned Int;
6279 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00006280 default: return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006281 case NEON::BI__builtin_neon_vbsl_v:
6282 case NEON::BI__builtin_neon_vbslq_v: {
6283 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
6284 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl");
6285 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl");
6286 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl");
6287
6288 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl");
6289 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl");
6290 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl");
6291 return Builder.CreateBitCast(Ops[0], Ty);
6292 }
6293 case NEON::BI__builtin_neon_vfma_lane_v:
6294 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types
6295 // The ARM builtins (and instructions) have the addend as the first
6296 // operand, but the 'fma' intrinsics have it last. Swap it around here.
6297 Value *Addend = Ops[0];
6298 Value *Multiplicand = Ops[1];
6299 Value *LaneSource = Ops[2];
6300 Ops[0] = Multiplicand;
6301 Ops[1] = LaneSource;
6302 Ops[2] = Addend;
6303
6304 // Now adjust things to handle the lane access.
6305 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ?
6306 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) :
6307 VTy;
6308 llvm::Constant *cst = cast<Constant>(Ops[3]);
6309 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst);
6310 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy);
6311 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane");
6312
6313 Ops.pop_back();
6314 Int = Intrinsic::fma;
6315 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla");
6316 }
6317 case NEON::BI__builtin_neon_vfma_laneq_v: {
6318 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
6319 // v1f64 fma should be mapped to Neon scalar f64 fma
6320 if (VTy && VTy->getElementType() == DoubleTy) {
6321 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6322 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
6323 llvm::Type *VTy = GetNeonType(this,
6324 NeonTypeFlags(NeonTypeFlags::Float64, false, true));
6325 Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
6326 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
6327 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00006328 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006329 return Builder.CreateBitCast(Result, Ty);
6330 }
6331 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6332 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6333 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6334
6335 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(),
6336 VTy->getNumElements() * 2);
6337 Ops[2] = Builder.CreateBitCast(Ops[2], STy);
6338 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(),
6339 cast<ConstantInt>(Ops[3]));
6340 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane");
6341
David Blaikie43f9bb72015-05-18 22:14:03 +00006342 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006343 }
6344 case NEON::BI__builtin_neon_vfmaq_laneq_v: {
6345 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6346 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6347 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6348
6349 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
6350 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3]));
David Blaikie43f9bb72015-05-18 22:14:03 +00006351 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006352 }
6353 case NEON::BI__builtin_neon_vfmas_lane_f32:
6354 case NEON::BI__builtin_neon_vfmas_laneq_f32:
6355 case NEON::BI__builtin_neon_vfmad_lane_f64:
6356 case NEON::BI__builtin_neon_vfmad_laneq_f64: {
6357 Ops.push_back(EmitScalarExpr(E->getArg(3)));
David Majnemerced8bdf2015-02-25 17:36:15 +00006358 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northovera2ee4332014-03-29 15:09:45 +00006359 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6360 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
David Blaikie43f9bb72015-05-18 22:14:03 +00006361 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006362 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006363 case NEON::BI__builtin_neon_vmull_v:
6364 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006365 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
6366 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull;
Tim Northovera2ee4332014-03-29 15:09:45 +00006367 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
6368 case NEON::BI__builtin_neon_vmax_v:
6369 case NEON::BI__builtin_neon_vmaxq_v:
6370 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006371 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax;
6372 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax;
Tim Northovera2ee4332014-03-29 15:09:45 +00006373 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax");
6374 case NEON::BI__builtin_neon_vmin_v:
6375 case NEON::BI__builtin_neon_vminq_v:
6376 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006377 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin;
6378 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin;
Tim Northovera2ee4332014-03-29 15:09:45 +00006379 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin");
6380 case NEON::BI__builtin_neon_vabd_v:
6381 case NEON::BI__builtin_neon_vabdq_v:
6382 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006383 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
6384 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd;
Tim Northovera2ee4332014-03-29 15:09:45 +00006385 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd");
6386 case NEON::BI__builtin_neon_vpadal_v:
6387 case NEON::BI__builtin_neon_vpadalq_v: {
6388 unsigned ArgElts = VTy->getNumElements();
6389 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType());
6390 unsigned BitWidth = EltTy->getBitWidth();
6391 llvm::Type *ArgTy = llvm::VectorType::get(
6392 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts);
6393 llvm::Type* Tys[2] = { VTy, ArgTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006394 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006395 SmallVector<llvm::Value*, 1> TmpOps;
6396 TmpOps.push_back(Ops[1]);
6397 Function *F = CGM.getIntrinsic(Int, Tys);
6398 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal");
6399 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType());
6400 return Builder.CreateAdd(tmp, addend);
6401 }
6402 case NEON::BI__builtin_neon_vpmin_v:
6403 case NEON::BI__builtin_neon_vpminq_v:
6404 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006405 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
6406 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006407 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin");
6408 case NEON::BI__builtin_neon_vpmax_v:
6409 case NEON::BI__builtin_neon_vpmaxq_v:
6410 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006411 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
6412 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006413 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax");
6414 case NEON::BI__builtin_neon_vminnm_v:
6415 case NEON::BI__builtin_neon_vminnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006416 Int = Intrinsic::aarch64_neon_fminnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006417 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm");
6418 case NEON::BI__builtin_neon_vmaxnm_v:
6419 case NEON::BI__builtin_neon_vmaxnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006420 Int = Intrinsic::aarch64_neon_fmaxnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006421 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm");
6422 case NEON::BI__builtin_neon_vrecpss_f32: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006423 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006424 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006425 Ops, "vrecps");
6426 }
6427 case NEON::BI__builtin_neon_vrecpsd_f64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006428 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006429 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006430 Ops, "vrecps");
6431 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006432 case NEON::BI__builtin_neon_vqshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006433 Int = Intrinsic::aarch64_neon_sqshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006434 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n");
6435 case NEON::BI__builtin_neon_vqrshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006436 Int = Intrinsic::aarch64_neon_sqrshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006437 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n");
6438 case NEON::BI__builtin_neon_vqshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006439 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006440 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n");
6441 case NEON::BI__builtin_neon_vrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006442 Int = Intrinsic::aarch64_neon_rshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006443 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n");
6444 case NEON::BI__builtin_neon_vqrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006445 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006446 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n");
6447 case NEON::BI__builtin_neon_vrnda_v:
6448 case NEON::BI__builtin_neon_vrndaq_v: {
6449 Int = Intrinsic::round;
6450 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda");
6451 }
6452 case NEON::BI__builtin_neon_vrndi_v:
6453 case NEON::BI__builtin_neon_vrndiq_v: {
6454 Int = Intrinsic::nearbyint;
6455 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi");
6456 }
6457 case NEON::BI__builtin_neon_vrndm_v:
6458 case NEON::BI__builtin_neon_vrndmq_v: {
6459 Int = Intrinsic::floor;
6460 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm");
6461 }
6462 case NEON::BI__builtin_neon_vrndn_v:
6463 case NEON::BI__builtin_neon_vrndnq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006464 Int = Intrinsic::aarch64_neon_frintn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006465 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn");
6466 }
6467 case NEON::BI__builtin_neon_vrndp_v:
6468 case NEON::BI__builtin_neon_vrndpq_v: {
6469 Int = Intrinsic::ceil;
6470 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp");
6471 }
6472 case NEON::BI__builtin_neon_vrndx_v:
6473 case NEON::BI__builtin_neon_vrndxq_v: {
6474 Int = Intrinsic::rint;
6475 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx");
6476 }
6477 case NEON::BI__builtin_neon_vrnd_v:
6478 case NEON::BI__builtin_neon_vrndq_v: {
6479 Int = Intrinsic::trunc;
6480 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz");
6481 }
6482 case NEON::BI__builtin_neon_vceqz_v:
6483 case NEON::BI__builtin_neon_vceqzq_v:
6484 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ,
6485 ICmpInst::ICMP_EQ, "vceqz");
6486 case NEON::BI__builtin_neon_vcgez_v:
6487 case NEON::BI__builtin_neon_vcgezq_v:
6488 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE,
6489 ICmpInst::ICMP_SGE, "vcgez");
6490 case NEON::BI__builtin_neon_vclez_v:
6491 case NEON::BI__builtin_neon_vclezq_v:
6492 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE,
6493 ICmpInst::ICMP_SLE, "vclez");
6494 case NEON::BI__builtin_neon_vcgtz_v:
6495 case NEON::BI__builtin_neon_vcgtzq_v:
6496 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT,
6497 ICmpInst::ICMP_SGT, "vcgtz");
6498 case NEON::BI__builtin_neon_vcltz_v:
6499 case NEON::BI__builtin_neon_vcltzq_v:
6500 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT,
6501 ICmpInst::ICMP_SLT, "vcltz");
6502 case NEON::BI__builtin_neon_vcvt_f64_v:
6503 case NEON::BI__builtin_neon_vcvtq_f64_v:
6504 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6505 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad));
6506 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
6507 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
6508 case NEON::BI__builtin_neon_vcvt_f64_f32: {
6509 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad &&
6510 "unexpected vcvt_f64_f32 builtin");
6511 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false);
6512 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6513
6514 return Builder.CreateFPExt(Ops[0], Ty, "vcvt");
6515 }
6516 case NEON::BI__builtin_neon_vcvt_f32_f64: {
6517 assert(Type.getEltType() == NeonTypeFlags::Float32 &&
6518 "unexpected vcvt_f32_f64 builtin");
6519 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true);
6520 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6521
6522 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt");
6523 }
6524 case NEON::BI__builtin_neon_vcvt_s32_v:
6525 case NEON::BI__builtin_neon_vcvt_u32_v:
6526 case NEON::BI__builtin_neon_vcvt_s64_v:
6527 case NEON::BI__builtin_neon_vcvt_u64_v:
6528 case NEON::BI__builtin_neon_vcvtq_s32_v:
6529 case NEON::BI__builtin_neon_vcvtq_u32_v:
6530 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00006531 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006532 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northovera2ee4332014-03-29 15:09:45 +00006533 if (usgn)
6534 return Builder.CreateFPToUI(Ops[0], Ty);
6535 return Builder.CreateFPToSI(Ops[0], Ty);
6536 }
6537 case NEON::BI__builtin_neon_vcvta_s32_v:
6538 case NEON::BI__builtin_neon_vcvtaq_s32_v:
6539 case NEON::BI__builtin_neon_vcvta_u32_v:
6540 case NEON::BI__builtin_neon_vcvtaq_u32_v:
6541 case NEON::BI__builtin_neon_vcvta_s64_v:
6542 case NEON::BI__builtin_neon_vcvtaq_s64_v:
6543 case NEON::BI__builtin_neon_vcvta_u64_v:
6544 case NEON::BI__builtin_neon_vcvtaq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006545 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006546 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006547 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta");
6548 }
6549 case NEON::BI__builtin_neon_vcvtm_s32_v:
6550 case NEON::BI__builtin_neon_vcvtmq_s32_v:
6551 case NEON::BI__builtin_neon_vcvtm_u32_v:
6552 case NEON::BI__builtin_neon_vcvtmq_u32_v:
6553 case NEON::BI__builtin_neon_vcvtm_s64_v:
6554 case NEON::BI__builtin_neon_vcvtmq_s64_v:
6555 case NEON::BI__builtin_neon_vcvtm_u64_v:
6556 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006557 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006558 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006559 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm");
6560 }
6561 case NEON::BI__builtin_neon_vcvtn_s32_v:
6562 case NEON::BI__builtin_neon_vcvtnq_s32_v:
6563 case NEON::BI__builtin_neon_vcvtn_u32_v:
6564 case NEON::BI__builtin_neon_vcvtnq_u32_v:
6565 case NEON::BI__builtin_neon_vcvtn_s64_v:
6566 case NEON::BI__builtin_neon_vcvtnq_s64_v:
6567 case NEON::BI__builtin_neon_vcvtn_u64_v:
6568 case NEON::BI__builtin_neon_vcvtnq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006569 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006570 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006571 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn");
6572 }
6573 case NEON::BI__builtin_neon_vcvtp_s32_v:
6574 case NEON::BI__builtin_neon_vcvtpq_s32_v:
6575 case NEON::BI__builtin_neon_vcvtp_u32_v:
6576 case NEON::BI__builtin_neon_vcvtpq_u32_v:
6577 case NEON::BI__builtin_neon_vcvtp_s64_v:
6578 case NEON::BI__builtin_neon_vcvtpq_s64_v:
6579 case NEON::BI__builtin_neon_vcvtp_u64_v:
6580 case NEON::BI__builtin_neon_vcvtpq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006581 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006582 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006583 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp");
6584 }
6585 case NEON::BI__builtin_neon_vmulx_v:
6586 case NEON::BI__builtin_neon_vmulxq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006587 Int = Intrinsic::aarch64_neon_fmulx;
Tim Northovera2ee4332014-03-29 15:09:45 +00006588 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx");
6589 }
6590 case NEON::BI__builtin_neon_vmul_lane_v:
6591 case NEON::BI__builtin_neon_vmul_laneq_v: {
6592 // v1f64 vmul_lane should be mapped to Neon scalar mul lane
6593 bool Quad = false;
6594 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
6595 Quad = true;
6596 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6597 llvm::Type *VTy = GetNeonType(this,
6598 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad));
6599 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
6600 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract");
6601 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]);
6602 return Builder.CreateBitCast(Result, Ty);
6603 }
Tim Northover0c68faa2014-03-31 15:47:09 +00006604 case NEON::BI__builtin_neon_vnegd_s64:
6605 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd");
Tim Northovera2ee4332014-03-29 15:09:45 +00006606 case NEON::BI__builtin_neon_vpmaxnm_v:
6607 case NEON::BI__builtin_neon_vpmaxnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006608 Int = Intrinsic::aarch64_neon_fmaxnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006609 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm");
6610 }
6611 case NEON::BI__builtin_neon_vpminnm_v:
6612 case NEON::BI__builtin_neon_vpminnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006613 Int = Intrinsic::aarch64_neon_fminnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006614 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm");
6615 }
6616 case NEON::BI__builtin_neon_vsqrt_v:
6617 case NEON::BI__builtin_neon_vsqrtq_v: {
6618 Int = Intrinsic::sqrt;
6619 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6620 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt");
6621 }
6622 case NEON::BI__builtin_neon_vrbit_v:
6623 case NEON::BI__builtin_neon_vrbitq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006624 Int = Intrinsic::aarch64_neon_rbit;
Tim Northovera2ee4332014-03-29 15:09:45 +00006625 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit");
6626 }
6627 case NEON::BI__builtin_neon_vaddv_u8:
6628 // FIXME: These are handled by the AArch64 scalar code.
6629 usgn = true;
6630 // FALLTHROUGH
6631 case NEON::BI__builtin_neon_vaddv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006632 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006633 Ty = Int32Ty;
6634 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006635 llvm::Type *Tys[2] = { Ty, VTy };
6636 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6637 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006638 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006639 }
6640 case NEON::BI__builtin_neon_vaddv_u16:
6641 usgn = true;
6642 // FALLTHROUGH
6643 case NEON::BI__builtin_neon_vaddv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006644 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006645 Ty = Int32Ty;
6646 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006647 llvm::Type *Tys[2] = { Ty, VTy };
6648 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6649 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006650 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006651 }
6652 case NEON::BI__builtin_neon_vaddvq_u8:
6653 usgn = true;
6654 // FALLTHROUGH
6655 case NEON::BI__builtin_neon_vaddvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006656 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006657 Ty = Int32Ty;
6658 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006659 llvm::Type *Tys[2] = { Ty, VTy };
6660 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6661 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006662 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006663 }
6664 case NEON::BI__builtin_neon_vaddvq_u16:
6665 usgn = true;
6666 // FALLTHROUGH
6667 case NEON::BI__builtin_neon_vaddvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006668 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006669 Ty = Int32Ty;
6670 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006671 llvm::Type *Tys[2] = { Ty, VTy };
6672 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6673 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006674 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006675 }
6676 case NEON::BI__builtin_neon_vmaxv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006677 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006678 Ty = Int32Ty;
6679 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006680 llvm::Type *Tys[2] = { Ty, VTy };
6681 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6682 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006683 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006684 }
6685 case NEON::BI__builtin_neon_vmaxv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006686 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006687 Ty = Int32Ty;
6688 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006689 llvm::Type *Tys[2] = { Ty, VTy };
6690 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6691 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006692 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006693 }
6694 case NEON::BI__builtin_neon_vmaxvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006695 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006696 Ty = Int32Ty;
6697 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006698 llvm::Type *Tys[2] = { Ty, VTy };
6699 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6700 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006701 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006702 }
6703 case NEON::BI__builtin_neon_vmaxvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006704 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006705 Ty = Int32Ty;
6706 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006707 llvm::Type *Tys[2] = { Ty, VTy };
6708 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6709 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006710 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006711 }
6712 case NEON::BI__builtin_neon_vmaxv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006713 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006714 Ty = Int32Ty;
6715 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006716 llvm::Type *Tys[2] = { Ty, VTy };
6717 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6718 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006719 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006720 }
6721 case NEON::BI__builtin_neon_vmaxv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006722 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006723 Ty = Int32Ty;
6724 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006725 llvm::Type *Tys[2] = { Ty, VTy };
6726 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6727 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006728 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006729 }
6730 case NEON::BI__builtin_neon_vmaxvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006731 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006732 Ty = Int32Ty;
6733 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006734 llvm::Type *Tys[2] = { Ty, VTy };
6735 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6736 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006737 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006738 }
6739 case NEON::BI__builtin_neon_vmaxvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006740 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006741 Ty = Int32Ty;
6742 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006743 llvm::Type *Tys[2] = { Ty, VTy };
6744 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6745 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006746 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006747 }
6748 case NEON::BI__builtin_neon_vminv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006749 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006750 Ty = Int32Ty;
6751 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006752 llvm::Type *Tys[2] = { Ty, VTy };
6753 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6754 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006755 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006756 }
6757 case NEON::BI__builtin_neon_vminv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006758 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006759 Ty = Int32Ty;
6760 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006761 llvm::Type *Tys[2] = { Ty, VTy };
6762 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6763 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006764 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006765 }
6766 case NEON::BI__builtin_neon_vminvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006767 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006768 Ty = Int32Ty;
6769 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006770 llvm::Type *Tys[2] = { Ty, VTy };
6771 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6772 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006773 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006774 }
6775 case NEON::BI__builtin_neon_vminvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006776 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006777 Ty = Int32Ty;
6778 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006779 llvm::Type *Tys[2] = { Ty, VTy };
6780 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6781 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006782 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006783 }
6784 case NEON::BI__builtin_neon_vminv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006785 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006786 Ty = Int32Ty;
6787 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006788 llvm::Type *Tys[2] = { Ty, VTy };
6789 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6790 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006791 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006792 }
6793 case NEON::BI__builtin_neon_vminv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006794 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006795 Ty = Int32Ty;
6796 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006797 llvm::Type *Tys[2] = { Ty, VTy };
6798 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6799 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006800 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006801 }
6802 case NEON::BI__builtin_neon_vminvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006803 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006804 Ty = Int32Ty;
6805 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006806 llvm::Type *Tys[2] = { Ty, VTy };
6807 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6808 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006809 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006810 }
6811 case NEON::BI__builtin_neon_vminvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006812 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006813 Ty = Int32Ty;
6814 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006815 llvm::Type *Tys[2] = { Ty, VTy };
6816 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6817 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006818 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006819 }
6820 case NEON::BI__builtin_neon_vmul_n_f64: {
6821 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6822 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy);
6823 return Builder.CreateFMul(Ops[0], RHS);
6824 }
6825 case NEON::BI__builtin_neon_vaddlv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006826 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006827 Ty = Int32Ty;
6828 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006829 llvm::Type *Tys[2] = { Ty, VTy };
6830 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6831 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006832 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006833 }
6834 case NEON::BI__builtin_neon_vaddlv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006835 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006836 Ty = Int32Ty;
6837 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006838 llvm::Type *Tys[2] = { Ty, VTy };
6839 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6840 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6841 }
6842 case NEON::BI__builtin_neon_vaddlvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006843 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006844 Ty = Int32Ty;
6845 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006846 llvm::Type *Tys[2] = { Ty, VTy };
6847 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6848 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006849 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006850 }
6851 case NEON::BI__builtin_neon_vaddlvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006852 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006853 Ty = Int32Ty;
6854 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006855 llvm::Type *Tys[2] = { Ty, VTy };
6856 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6857 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6858 }
6859 case NEON::BI__builtin_neon_vaddlv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006860 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006861 Ty = Int32Ty;
6862 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006863 llvm::Type *Tys[2] = { Ty, VTy };
6864 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6865 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006866 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006867 }
6868 case NEON::BI__builtin_neon_vaddlv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006869 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006870 Ty = Int32Ty;
6871 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006872 llvm::Type *Tys[2] = { Ty, VTy };
6873 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6874 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6875 }
6876 case NEON::BI__builtin_neon_vaddlvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006877 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006878 Ty = Int32Ty;
6879 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006880 llvm::Type *Tys[2] = { Ty, VTy };
6881 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6882 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006883 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006884 }
6885 case NEON::BI__builtin_neon_vaddlvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006886 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006887 Ty = Int32Ty;
6888 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006889 llvm::Type *Tys[2] = { Ty, VTy };
6890 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6891 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6892 }
6893 case NEON::BI__builtin_neon_vsri_n_v:
6894 case NEON::BI__builtin_neon_vsriq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006895 Int = Intrinsic::aarch64_neon_vsri;
Tim Northovera2ee4332014-03-29 15:09:45 +00006896 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6897 return EmitNeonCall(Intrin, Ops, "vsri_n");
6898 }
6899 case NEON::BI__builtin_neon_vsli_n_v:
6900 case NEON::BI__builtin_neon_vsliq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006901 Int = Intrinsic::aarch64_neon_vsli;
Tim Northovera2ee4332014-03-29 15:09:45 +00006902 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6903 return EmitNeonCall(Intrin, Ops, "vsli_n");
6904 }
6905 case NEON::BI__builtin_neon_vsra_n_v:
6906 case NEON::BI__builtin_neon_vsraq_n_v:
6907 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6908 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
6909 return Builder.CreateAdd(Ops[0], Ops[1]);
6910 case NEON::BI__builtin_neon_vrsra_n_v:
6911 case NEON::BI__builtin_neon_vrsraq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006912 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006913 SmallVector<llvm::Value*,2> TmpOps;
6914 TmpOps.push_back(Ops[1]);
6915 TmpOps.push_back(Ops[2]);
6916 Function* F = CGM.getIntrinsic(Int, Ty);
6917 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true);
6918 Ops[0] = Builder.CreateBitCast(Ops[0], VTy);
6919 return Builder.CreateAdd(Ops[0], tmp);
6920 }
6921 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence
6922 // of an Align parameter here.
6923 case NEON::BI__builtin_neon_vld1_x2_v:
6924 case NEON::BI__builtin_neon_vld1q_x2_v:
6925 case NEON::BI__builtin_neon_vld1_x3_v:
6926 case NEON::BI__builtin_neon_vld1q_x3_v:
6927 case NEON::BI__builtin_neon_vld1_x4_v:
6928 case NEON::BI__builtin_neon_vld1q_x4_v: {
6929 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6930 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6931 llvm::Type *Tys[2] = { VTy, PTy };
6932 unsigned Int;
6933 switch (BuiltinID) {
6934 case NEON::BI__builtin_neon_vld1_x2_v:
6935 case NEON::BI__builtin_neon_vld1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006936 Int = Intrinsic::aarch64_neon_ld1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006937 break;
6938 case NEON::BI__builtin_neon_vld1_x3_v:
6939 case NEON::BI__builtin_neon_vld1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006940 Int = Intrinsic::aarch64_neon_ld1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006941 break;
6942 case NEON::BI__builtin_neon_vld1_x4_v:
6943 case NEON::BI__builtin_neon_vld1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006944 Int = Intrinsic::aarch64_neon_ld1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006945 break;
6946 }
6947 Function *F = CGM.getIntrinsic(Int, Tys);
6948 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN");
6949 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6950 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006951 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006952 }
6953 case NEON::BI__builtin_neon_vst1_x2_v:
6954 case NEON::BI__builtin_neon_vst1q_x2_v:
6955 case NEON::BI__builtin_neon_vst1_x3_v:
6956 case NEON::BI__builtin_neon_vst1q_x3_v:
6957 case NEON::BI__builtin_neon_vst1_x4_v:
6958 case NEON::BI__builtin_neon_vst1q_x4_v: {
6959 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6960 llvm::Type *Tys[2] = { VTy, PTy };
6961 unsigned Int;
6962 switch (BuiltinID) {
6963 case NEON::BI__builtin_neon_vst1_x2_v:
6964 case NEON::BI__builtin_neon_vst1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006965 Int = Intrinsic::aarch64_neon_st1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006966 break;
6967 case NEON::BI__builtin_neon_vst1_x3_v:
6968 case NEON::BI__builtin_neon_vst1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006969 Int = Intrinsic::aarch64_neon_st1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006970 break;
6971 case NEON::BI__builtin_neon_vst1_x4_v:
6972 case NEON::BI__builtin_neon_vst1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006973 Int = Intrinsic::aarch64_neon_st1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006974 break;
6975 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00006976 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6977 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
Tim Northovera2ee4332014-03-29 15:09:45 +00006978 }
6979 case NEON::BI__builtin_neon_vld1_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00006980 case NEON::BI__builtin_neon_vld1q_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006981 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
Peter Collingbourneb367c562016-11-28 22:30:21 +00006982 auto Alignment = CharUnits::fromQuantity(
6983 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16);
6984 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment);
6985 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006986 case NEON::BI__builtin_neon_vst1_v:
6987 case NEON::BI__builtin_neon_vst1q_v:
6988 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
6989 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
John McCall7f416cc2015-09-08 08:05:57 +00006990 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006991 case NEON::BI__builtin_neon_vld1_lane_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00006992 case NEON::BI__builtin_neon_vld1q_lane_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006993 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6994 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
6995 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00006996 auto Alignment = CharUnits::fromQuantity(
6997 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16);
6998 Ops[0] =
6999 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Tim Northovera2ee4332014-03-29 15:09:45 +00007000 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane");
Peter Collingbourneb367c562016-11-28 22:30:21 +00007001 }
Tim Northovera2ee4332014-03-29 15:09:45 +00007002 case NEON::BI__builtin_neon_vld1_dup_v:
7003 case NEON::BI__builtin_neon_vld1q_dup_v: {
7004 Value *V = UndefValue::get(Ty);
7005 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
7006 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00007007 auto Alignment = CharUnits::fromQuantity(
7008 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16);
7009 Ops[0] =
7010 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Michael J. Spencer5ce26682014-06-02 19:48:59 +00007011 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00007012 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI);
7013 return EmitNeonSplat(Ops[0], CI);
7014 }
7015 case NEON::BI__builtin_neon_vst1_lane_v:
7016 case NEON::BI__builtin_neon_vst1q_lane_v:
7017 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7018 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
7019 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00007020 return Builder.CreateDefaultAlignedStore(Ops[1],
7021 Builder.CreateBitCast(Ops[0], Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00007022 case NEON::BI__builtin_neon_vld2_v:
7023 case NEON::BI__builtin_neon_vld2q_v: {
7024 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
7025 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7026 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007027 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007028 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
7029 Ops[0] = Builder.CreateBitCast(Ops[0],
7030 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007031 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007032 }
7033 case NEON::BI__builtin_neon_vld3_v:
7034 case NEON::BI__builtin_neon_vld3q_v: {
7035 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
7036 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7037 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007038 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007039 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
7040 Ops[0] = Builder.CreateBitCast(Ops[0],
7041 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007042 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007043 }
7044 case NEON::BI__builtin_neon_vld4_v:
7045 case NEON::BI__builtin_neon_vld4q_v: {
7046 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
7047 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7048 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007049 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007050 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
7051 Ops[0] = Builder.CreateBitCast(Ops[0],
7052 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007053 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007054 }
Tim Northover74b2def2014-04-01 10:37:47 +00007055 case NEON::BI__builtin_neon_vld2_dup_v:
7056 case NEON::BI__builtin_neon_vld2q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007057 llvm::Type *PTy =
7058 llvm::PointerType::getUnqual(VTy->getElementType());
7059 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7060 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007061 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007062 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
7063 Ops[0] = Builder.CreateBitCast(Ops[0],
7064 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007065 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007066 }
Tim Northover74b2def2014-04-01 10:37:47 +00007067 case NEON::BI__builtin_neon_vld3_dup_v:
7068 case NEON::BI__builtin_neon_vld3q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007069 llvm::Type *PTy =
7070 llvm::PointerType::getUnqual(VTy->getElementType());
7071 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7072 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007073 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007074 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
7075 Ops[0] = Builder.CreateBitCast(Ops[0],
7076 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007077 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007078 }
Tim Northover74b2def2014-04-01 10:37:47 +00007079 case NEON::BI__builtin_neon_vld4_dup_v:
7080 case NEON::BI__builtin_neon_vld4q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007081 llvm::Type *PTy =
7082 llvm::PointerType::getUnqual(VTy->getElementType());
7083 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7084 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007085 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007086 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
7087 Ops[0] = Builder.CreateBitCast(Ops[0],
7088 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007089 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007090 }
7091 case NEON::BI__builtin_neon_vld2_lane_v:
7092 case NEON::BI__builtin_neon_vld2q_lane_v: {
7093 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007094 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007095 Ops.push_back(Ops[1]);
7096 Ops.erase(Ops.begin()+1);
7097 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7098 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007099 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007100 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007101 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7102 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007103 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007104 }
7105 case NEON::BI__builtin_neon_vld3_lane_v:
7106 case NEON::BI__builtin_neon_vld3q_lane_v: {
7107 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007108 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007109 Ops.push_back(Ops[1]);
7110 Ops.erase(Ops.begin()+1);
7111 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7112 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
7113 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007114 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007115 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007116 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7117 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007118 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007119 }
7120 case NEON::BI__builtin_neon_vld4_lane_v:
7121 case NEON::BI__builtin_neon_vld4q_lane_v: {
7122 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007123 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007124 Ops.push_back(Ops[1]);
7125 Ops.erase(Ops.begin()+1);
7126 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7127 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
7128 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
7129 Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007130 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007131 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007132 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7133 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007134 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007135 }
7136 case NEON::BI__builtin_neon_vst2_v:
7137 case NEON::BI__builtin_neon_vst2q_v: {
7138 Ops.push_back(Ops[0]);
7139 Ops.erase(Ops.begin());
7140 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007141 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007142 Ops, "");
7143 }
7144 case NEON::BI__builtin_neon_vst2_lane_v:
7145 case NEON::BI__builtin_neon_vst2q_lane_v: {
7146 Ops.push_back(Ops[0]);
7147 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007148 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007149 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007150 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007151 Ops, "");
7152 }
7153 case NEON::BI__builtin_neon_vst3_v:
7154 case NEON::BI__builtin_neon_vst3q_v: {
7155 Ops.push_back(Ops[0]);
7156 Ops.erase(Ops.begin());
7157 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007158 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007159 Ops, "");
7160 }
7161 case NEON::BI__builtin_neon_vst3_lane_v:
7162 case NEON::BI__builtin_neon_vst3q_lane_v: {
7163 Ops.push_back(Ops[0]);
7164 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007165 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007166 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007167 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007168 Ops, "");
7169 }
7170 case NEON::BI__builtin_neon_vst4_v:
7171 case NEON::BI__builtin_neon_vst4q_v: {
7172 Ops.push_back(Ops[0]);
7173 Ops.erase(Ops.begin());
7174 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007175 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007176 Ops, "");
7177 }
7178 case NEON::BI__builtin_neon_vst4_lane_v:
7179 case NEON::BI__builtin_neon_vst4q_lane_v: {
7180 Ops.push_back(Ops[0]);
7181 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007182 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007183 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007184 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007185 Ops, "");
7186 }
7187 case NEON::BI__builtin_neon_vtrn_v:
7188 case NEON::BI__builtin_neon_vtrnq_v: {
7189 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7190 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7191 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007192 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007193
7194 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007195 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007196 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007197 Indices.push_back(i+vi);
7198 Indices.push_back(i+e+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007199 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007200 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007201 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00007202 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007203 }
7204 return SV;
7205 }
7206 case NEON::BI__builtin_neon_vuzp_v:
7207 case NEON::BI__builtin_neon_vuzpq_v: {
7208 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7209 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7210 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007211 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007212
7213 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007214 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007215 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00007216 Indices.push_back(2*i+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007217
David Blaikiefb901c7a2015-04-04 15:12:29 +00007218 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007219 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00007220 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007221 }
7222 return SV;
7223 }
7224 case NEON::BI__builtin_neon_vzip_v:
7225 case NEON::BI__builtin_neon_vzipq_v: {
7226 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7227 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7228 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007229 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007230
7231 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007232 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007233 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007234 Indices.push_back((i + vi*e) >> 1);
7235 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northovera2ee4332014-03-29 15:09:45 +00007236 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007237 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007238 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00007239 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007240 }
7241 return SV;
7242 }
7243 case NEON::BI__builtin_neon_vqtbl1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007244 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007245 Ops, "vtbl1");
7246 }
7247 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007248 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007249 Ops, "vtbl2");
7250 }
7251 case NEON::BI__builtin_neon_vqtbl3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007252 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007253 Ops, "vtbl3");
7254 }
7255 case NEON::BI__builtin_neon_vqtbl4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007256 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007257 Ops, "vtbl4");
7258 }
7259 case NEON::BI__builtin_neon_vqtbx1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007260 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007261 Ops, "vtbx1");
7262 }
7263 case NEON::BI__builtin_neon_vqtbx2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007264 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007265 Ops, "vtbx2");
7266 }
7267 case NEON::BI__builtin_neon_vqtbx3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007268 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007269 Ops, "vtbx3");
7270 }
7271 case NEON::BI__builtin_neon_vqtbx4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007272 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007273 Ops, "vtbx4");
7274 }
7275 case NEON::BI__builtin_neon_vsqadd_v:
7276 case NEON::BI__builtin_neon_vsqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007277 Int = Intrinsic::aarch64_neon_usqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007278 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd");
7279 }
7280 case NEON::BI__builtin_neon_vuqadd_v:
7281 case NEON::BI__builtin_neon_vuqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007282 Int = Intrinsic::aarch64_neon_suqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007283 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
7284 }
7285 }
7286}
7287
Bill Wendling65b2a962010-10-09 08:47:25 +00007288llvm::Value *CodeGenFunction::
Bill Wendlingf1a3fca2012-02-22 09:30:11 +00007289BuildVector(ArrayRef<llvm::Value*> Ops) {
Bill Wendling65b2a962010-10-09 08:47:25 +00007290 assert((Ops.size() & (Ops.size() - 1)) == 0 &&
7291 "Not a power-of-two sized vector!");
7292 bool AllConstants = true;
7293 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i)
7294 AllConstants &= isa<Constant>(Ops[i]);
7295
7296 // If this is a constant vector, create a ConstantVector.
7297 if (AllConstants) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007298 SmallVector<llvm::Constant*, 16> CstOps;
Bill Wendling65b2a962010-10-09 08:47:25 +00007299 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
7300 CstOps.push_back(cast<Constant>(Ops[i]));
7301 return llvm::ConstantVector::get(CstOps);
7302 }
7303
7304 // Otherwise, insertelement the values to build the vector.
7305 Value *Result =
7306 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size()));
7307
7308 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007309 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i));
Bill Wendling65b2a962010-10-09 08:47:25 +00007310
7311 return Result;
7312}
7313
Igor Bregeraadb8762016-06-08 13:59:20 +00007314// Convert the mask from an integer type to a vector of i1.
7315static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask,
7316 unsigned NumElts) {
7317
7318 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(),
7319 cast<IntegerType>(Mask->getType())->getBitWidth());
7320 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy);
7321
7322 // If we have less than 8 elements, then the starting mask was an i8 and
7323 // we need to extract down to the right number of elements.
7324 if (NumElts < 8) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007325 uint32_t Indices[4];
Igor Bregeraadb8762016-06-08 13:59:20 +00007326 for (unsigned i = 0; i != NumElts; ++i)
7327 Indices[i] = i;
7328 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec,
7329 makeArrayRef(Indices, NumElts),
7330 "extract");
7331 }
7332 return MaskVec;
7333}
7334
Craig Topper6e891fb2016-05-31 01:50:10 +00007335static Value *EmitX86MaskedStore(CodeGenFunction &CGF,
7336 SmallVectorImpl<Value *> &Ops,
7337 unsigned Align) {
7338 // Cast the pointer to right type.
7339 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7340 llvm::PointerType::getUnqual(Ops[1]->getType()));
7341
7342 // If the mask is all ones just emit a regular store.
7343 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7344 if (C->isAllOnesValue())
7345 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align);
7346
Igor Bregeraadb8762016-06-08 13:59:20 +00007347 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7348 Ops[1]->getType()->getVectorNumElements());
Craig Topper6e891fb2016-05-31 01:50:10 +00007349
Igor Bregeraadb8762016-06-08 13:59:20 +00007350 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec);
Craig Topper6e891fb2016-05-31 01:50:10 +00007351}
7352
Craig Topper4b060e32016-05-31 06:58:07 +00007353static Value *EmitX86MaskedLoad(CodeGenFunction &CGF,
7354 SmallVectorImpl<Value *> &Ops, unsigned Align) {
7355 // Cast the pointer to right type.
7356 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7357 llvm::PointerType::getUnqual(Ops[1]->getType()));
7358
7359 // If the mask is all ones just emit a regular store.
7360 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7361 if (C->isAllOnesValue())
7362 return CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7363
Igor Bregeraadb8762016-06-08 13:59:20 +00007364 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7365 Ops[1]->getType()->getVectorNumElements());
Craig Topper4b060e32016-05-31 06:58:07 +00007366
Igor Bregeraadb8762016-06-08 13:59:20 +00007367 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]);
7368}
Craig Topper4b060e32016-05-31 06:58:07 +00007369
Simon Pilgrim2d851732016-07-22 13:58:56 +00007370static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF,
7371 SmallVectorImpl<Value *> &Ops,
7372 llvm::Type *DstTy,
7373 unsigned SrcSizeInBits,
7374 unsigned Align) {
7375 // Load the subvector.
7376 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7377
7378 // Create broadcast mask.
7379 unsigned NumDstElts = DstTy->getVectorNumElements();
7380 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits();
7381
7382 SmallVector<uint32_t, 8> Mask;
7383 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts)
7384 for (unsigned j = 0; j != NumSrcElts; ++j)
7385 Mask.push_back(j);
7386
7387 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst");
7388}
7389
Igor Bregeraadb8762016-06-08 13:59:20 +00007390static Value *EmitX86Select(CodeGenFunction &CGF,
Craig Topperc1442972016-06-09 05:15:00 +00007391 Value *Mask, Value *Op0, Value *Op1) {
Igor Bregeraadb8762016-06-08 13:59:20 +00007392
7393 // If the mask is all ones just return first argument.
Craig Topperc1442972016-06-09 05:15:00 +00007394 if (const auto *C = dyn_cast<Constant>(Mask))
Igor Bregeraadb8762016-06-08 13:59:20 +00007395 if (C->isAllOnesValue())
Craig Topperc1442972016-06-09 05:15:00 +00007396 return Op0;
Igor Bregeraadb8762016-06-08 13:59:20 +00007397
Craig Topperc1442972016-06-09 05:15:00 +00007398 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements());
Igor Bregeraadb8762016-06-08 13:59:20 +00007399
Craig Topperc1442972016-06-09 05:15:00 +00007400 return CGF.Builder.CreateSelect(Mask, Op0, Op1);
Craig Topper4b060e32016-05-31 06:58:07 +00007401}
7402
Craig Topperd1691c72016-06-22 04:47:58 +00007403static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC,
7404 bool Signed, SmallVectorImpl<Value *> &Ops) {
Craig Toppera54c21e2016-06-15 14:06:34 +00007405 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topperd1691c72016-06-22 04:47:58 +00007406 Value *Cmp;
Craig Toppera54c21e2016-06-15 14:06:34 +00007407
Craig Topperd1691c72016-06-22 04:47:58 +00007408 if (CC == 3) {
7409 Cmp = Constant::getNullValue(
7410 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7411 } else if (CC == 7) {
7412 Cmp = Constant::getAllOnesValue(
7413 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7414 } else {
7415 ICmpInst::Predicate Pred;
7416 switch (CC) {
7417 default: llvm_unreachable("Unknown condition code");
7418 case 0: Pred = ICmpInst::ICMP_EQ; break;
7419 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
7420 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
7421 case 4: Pred = ICmpInst::ICMP_NE; break;
7422 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
7423 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
7424 }
7425 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7426 }
7427
7428 const auto *C = dyn_cast<Constant>(Ops.back());
Craig Toppera54c21e2016-06-15 14:06:34 +00007429 if (!C || !C->isAllOnesValue())
Craig Topperd1691c72016-06-22 04:47:58 +00007430 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts));
Craig Toppera54c21e2016-06-15 14:06:34 +00007431
7432 if (NumElts < 8) {
7433 uint32_t Indices[8];
7434 for (unsigned i = 0; i != NumElts; ++i)
7435 Indices[i] = i;
7436 for (unsigned i = NumElts; i != 8; ++i)
Craig Topperac1823f2016-07-04 07:09:46 +00007437 Indices[i] = i % NumElts + NumElts;
Igor Breger2c880cf2016-06-29 08:14:17 +00007438 Cmp = CGF.Builder.CreateShuffleVector(
7439 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices);
Craig Toppera54c21e2016-06-15 14:06:34 +00007440 }
7441 return CGF.Builder.CreateBitCast(Cmp,
7442 IntegerType::get(CGF.getLLVMContext(),
7443 std::max(NumElts, 8U)));
7444}
7445
Uriel Korach3fba3c32017-09-13 09:02:02 +00007446static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef<Value *> Ops) {
7447
7448 llvm::Type *Ty = Ops[0]->getType();
7449 Value *Zero = llvm::Constant::getNullValue(Ty);
7450 Value *Sub = CGF.Builder.CreateSub(Zero, Ops[0]);
7451 Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Zero);
7452 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Sub);
7453 if (Ops.size() == 1)
7454 return Res;
7455 return EmitX86Select(CGF, Ops[2], Res, Ops[1]);
7456}
7457
Craig Topper531ce282016-10-24 04:04:24 +00007458static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred,
7459 ArrayRef<Value *> Ops) {
7460 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7461 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]);
7462
7463 if (Ops.size() == 2)
7464 return Res;
7465
7466 assert(Ops.size() == 4);
7467 return EmitX86Select(CGF, Ops[3], Res, Ops[2]);
7468}
7469
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007470static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op,
7471 llvm::Type *DstTy) {
7472 unsigned NumberOfElements = DstTy->getVectorNumElements();
7473 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements);
7474 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2");
7475}
7476
Erich Keane9937b132017-09-01 19:42:45 +00007477Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007478 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
7479 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
Erich Keane9937b132017-09-01 19:42:45 +00007480 return EmitX86CpuIs(CPUStr);
7481}
7482
7483Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007484
7485 // This enum contains the vendor, type, and subtype enums from the
7486 // runtime library concatenated together. The _START labels mark
7487 // the start and are used to adjust the value into the correct
7488 // encoding space.
7489 enum X86CPUs {
7490 INTEL = 1,
7491 AMD,
7492 CPU_TYPE_START,
7493 INTEL_BONNELL,
7494 INTEL_CORE2,
7495 INTEL_COREI7,
7496 AMDFAM10H,
7497 AMDFAM15H,
7498 INTEL_SILVERMONT,
7499 INTEL_KNL,
7500 AMD_BTVER1,
7501 AMD_BTVER2,
7502 CPU_SUBTYPE_START,
7503 INTEL_COREI7_NEHALEM,
7504 INTEL_COREI7_WESTMERE,
7505 INTEL_COREI7_SANDYBRIDGE,
7506 AMDFAM10H_BARCELONA,
7507 AMDFAM10H_SHANGHAI,
7508 AMDFAM10H_ISTANBUL,
7509 AMDFAM15H_BDVER1,
7510 AMDFAM15H_BDVER2,
7511 AMDFAM15H_BDVER3,
7512 AMDFAM15H_BDVER4,
7513 AMDFAM17H_ZNVER1,
7514 INTEL_COREI7_IVYBRIDGE,
7515 INTEL_COREI7_HASWELL,
7516 INTEL_COREI7_BROADWELL,
7517 INTEL_COREI7_SKYLAKE,
7518 INTEL_COREI7_SKYLAKE_AVX512,
7519 };
7520
7521 X86CPUs CPU =
7522 StringSwitch<X86CPUs>(CPUStr)
7523 .Case("amd", AMD)
7524 .Case("amdfam10h", AMDFAM10H)
Erich Keane9937b132017-09-01 19:42:45 +00007525 .Case("amdfam10", AMDFAM10H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007526 .Case("amdfam15h", AMDFAM15H)
Erich Keane9937b132017-09-01 19:42:45 +00007527 .Case("amdfam15", AMDFAM15H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007528 .Case("atom", INTEL_BONNELL)
7529 .Case("barcelona", AMDFAM10H_BARCELONA)
7530 .Case("bdver1", AMDFAM15H_BDVER1)
7531 .Case("bdver2", AMDFAM15H_BDVER2)
7532 .Case("bdver3", AMDFAM15H_BDVER3)
7533 .Case("bdver4", AMDFAM15H_BDVER4)
7534 .Case("bonnell", INTEL_BONNELL)
7535 .Case("broadwell", INTEL_COREI7_BROADWELL)
7536 .Case("btver1", AMD_BTVER1)
7537 .Case("btver2", AMD_BTVER2)
7538 .Case("core2", INTEL_CORE2)
7539 .Case("corei7", INTEL_COREI7)
7540 .Case("haswell", INTEL_COREI7_HASWELL)
7541 .Case("intel", INTEL)
7542 .Case("istanbul", AMDFAM10H_ISTANBUL)
7543 .Case("ivybridge", INTEL_COREI7_IVYBRIDGE)
7544 .Case("knl", INTEL_KNL)
7545 .Case("nehalem", INTEL_COREI7_NEHALEM)
7546 .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE)
7547 .Case("shanghai", AMDFAM10H_SHANGHAI)
7548 .Case("silvermont", INTEL_SILVERMONT)
7549 .Case("skylake", INTEL_COREI7_SKYLAKE)
7550 .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512)
7551 .Case("slm", INTEL_SILVERMONT)
7552 .Case("westmere", INTEL_COREI7_WESTMERE)
7553 .Case("znver1", AMDFAM17H_ZNVER1);
7554
Erich Keane9937b132017-09-01 19:42:45 +00007555 llvm::Type *Int32Ty = Builder.getInt32Ty();
Craig Topper699ae0c2017-08-10 20:28:30 +00007556
7557 // Matching the struct layout from the compiler-rt/libgcc structure that is
7558 // filled in:
7559 // unsigned int __cpu_vendor;
7560 // unsigned int __cpu_type;
7561 // unsigned int __cpu_subtype;
7562 // unsigned int __cpu_features[1];
7563 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7564 llvm::ArrayType::get(Int32Ty, 1));
7565
7566 // Grab the global __cpu_model.
Erich Keane9937b132017-09-01 19:42:45 +00007567 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
Craig Topper699ae0c2017-08-10 20:28:30 +00007568
7569 // Calculate the index needed to access the correct field based on the
7570 // range. Also adjust the expected value.
7571 unsigned Index;
7572 unsigned Value;
7573 if (CPU > CPU_SUBTYPE_START) {
7574 Index = 2;
7575 Value = CPU - CPU_SUBTYPE_START;
7576 } else if (CPU > CPU_TYPE_START) {
7577 Index = 1;
7578 Value = CPU - CPU_TYPE_START;
7579 } else {
7580 Index = 0;
7581 Value = CPU;
7582 }
7583
7584 // Grab the appropriate field from __cpu_model.
7585 llvm::Value *Idxs[] = {
7586 ConstantInt::get(Int32Ty, 0),
7587 ConstantInt::get(Int32Ty, Index)
7588 };
Erich Keane9937b132017-09-01 19:42:45 +00007589 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs);
7590 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4));
Craig Topper699ae0c2017-08-10 20:28:30 +00007591
7592 // Check the value of the field against the requested value.
Erich Keane9937b132017-09-01 19:42:45 +00007593 return Builder.CreateICmpEQ(CpuValue,
Craig Topper699ae0c2017-08-10 20:28:30 +00007594 llvm::ConstantInt::get(Int32Ty, Value));
7595}
7596
Erich Keane9937b132017-09-01 19:42:45 +00007597Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) {
7598 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts();
7599 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString();
7600 return EmitX86CpuSupports(FeatureStr);
7601}
7602
7603Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) {
7604 // TODO: When/if this becomes more than x86 specific then use a TargetInfo
7605 // based mapping.
7606 // Processor features and mapping to processor feature value.
7607 enum X86Features {
7608 CMOV = 0,
7609 MMX,
7610 POPCNT,
7611 SSE,
7612 SSE2,
7613 SSE3,
7614 SSSE3,
7615 SSE4_1,
7616 SSE4_2,
7617 AVX,
7618 AVX2,
7619 SSE4_A,
7620 FMA4,
7621 XOP,
7622 FMA,
7623 AVX512F,
7624 BMI,
7625 BMI2,
7626 AES,
7627 PCLMUL,
7628 AVX512VL,
7629 AVX512BW,
7630 AVX512DQ,
7631 AVX512CD,
7632 AVX512ER,
7633 AVX512PF,
7634 AVX512VBMI,
7635 AVX512IFMA,
7636 AVX5124VNNIW,
7637 AVX5124FMAPS,
7638 AVX512VPOPCNTDQ,
7639 MAX
7640 };
7641
7642 uint32_t FeaturesMask = 0;
7643
7644 for (const StringRef &FeatureStr : FeatureStrs) {
7645 X86Features Feature =
7646 StringSwitch<X86Features>(FeatureStr)
7647 .Case("cmov", X86Features::CMOV)
7648 .Case("mmx", X86Features::MMX)
7649 .Case("popcnt", X86Features::POPCNT)
7650 .Case("sse", X86Features::SSE)
7651 .Case("sse2", X86Features::SSE2)
7652 .Case("sse3", X86Features::SSE3)
7653 .Case("ssse3", X86Features::SSSE3)
7654 .Case("sse4.1", X86Features::SSE4_1)
7655 .Case("sse4.2", X86Features::SSE4_2)
7656 .Case("avx", X86Features::AVX)
7657 .Case("avx2", X86Features::AVX2)
7658 .Case("sse4a", X86Features::SSE4_A)
7659 .Case("fma4", X86Features::FMA4)
7660 .Case("xop", X86Features::XOP)
7661 .Case("fma", X86Features::FMA)
7662 .Case("avx512f", X86Features::AVX512F)
7663 .Case("bmi", X86Features::BMI)
7664 .Case("bmi2", X86Features::BMI2)
7665 .Case("aes", X86Features::AES)
7666 .Case("pclmul", X86Features::PCLMUL)
7667 .Case("avx512vl", X86Features::AVX512VL)
7668 .Case("avx512bw", X86Features::AVX512BW)
7669 .Case("avx512dq", X86Features::AVX512DQ)
7670 .Case("avx512cd", X86Features::AVX512CD)
7671 .Case("avx512er", X86Features::AVX512ER)
7672 .Case("avx512pf", X86Features::AVX512PF)
7673 .Case("avx512vbmi", X86Features::AVX512VBMI)
7674 .Case("avx512ifma", X86Features::AVX512IFMA)
7675 .Case("avx5124vnniw", X86Features::AVX5124VNNIW)
7676 .Case("avx5124fmaps", X86Features::AVX5124FMAPS)
7677 .Case("avx512vpopcntdq", X86Features::AVX512VPOPCNTDQ)
7678 .Default(X86Features::MAX);
7679 assert(Feature != X86Features::MAX && "Invalid feature!");
7680 FeaturesMask |= (1U << Feature);
7681 }
7682
7683 // Matching the struct layout from the compiler-rt/libgcc structure that is
7684 // filled in:
7685 // unsigned int __cpu_vendor;
7686 // unsigned int __cpu_type;
7687 // unsigned int __cpu_subtype;
7688 // unsigned int __cpu_features[1];
7689 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7690 llvm::ArrayType::get(Int32Ty, 1));
7691
7692 // Grab the global __cpu_model.
7693 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
7694
7695 // Grab the first (0th) element from the field __cpu_features off of the
7696 // global in the struct STy.
7697 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3),
7698 ConstantInt::get(Int32Ty, 0)};
7699 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs);
7700 Value *Features =
7701 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4));
7702
7703 // Check the value of the bit corresponding to the feature requested.
7704 Value *Bitset = Builder.CreateAnd(
7705 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask));
7706 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0));
7707}
7708
Mike Stump11289f42009-09-09 15:08:12 +00007709Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00007710 const CallExpr *E) {
Erich Keane9937b132017-09-01 19:42:45 +00007711 if (BuiltinID == X86::BI__builtin_cpu_is)
7712 return EmitX86CpuIs(E);
7713 if (BuiltinID == X86::BI__builtin_cpu_supports)
7714 return EmitX86CpuSupports(E);
7715
Chris Lattner0e62c1c2011-07-23 10:55:15 +00007716 SmallVector<Value*, 4> Ops;
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007717
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007718 // Find out if any arguments are required to be integer constant expressions.
7719 unsigned ICEArguments = 0;
7720 ASTContext::GetBuiltinTypeError Error;
7721 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
7722 assert(Error == ASTContext::GE_None && "Should not codegen an error");
7723
7724 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
7725 // If this is a normal argument, just emit it as a scalar.
7726 if ((ICEArguments & (1 << i)) == 0) {
7727 Ops.push_back(EmitScalarExpr(E->getArg(i)));
7728 continue;
7729 }
7730
7731 // If this is required to be a constant, constant fold it so that we know
7732 // that the generated intrinsic gets a ConstantInt.
7733 llvm::APSInt Result;
7734 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
7735 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00007736 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007737 }
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007738
Sanjay Patel280cfd12016-06-15 21:20:04 +00007739 // These exist so that the builtin that takes an immediate can be bounds
7740 // checked by clang to avoid passing bad immediates to the backend. Since
7741 // AVX has a larger immediate than SSE we would need separate builtins to
7742 // do the different bounds checking. Rather than create a clang specific
7743 // SSE only builtin, this implements eight separate builtins to match gcc
7744 // implementation.
7745 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) {
7746 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm));
7747 llvm::Function *F = CGM.getIntrinsic(ID);
7748 return Builder.CreateCall(F, Ops);
7749 };
7750
7751 // For the vector forms of FP comparisons, translate the builtins directly to
7752 // IR.
7753 // TODO: The builtins could be removed if the SSE header files used vector
7754 // extension comparisons directly (vector ordered/unordered may need
7755 // additional support via __builtin_isnan()).
Craig Topper01600632016-07-08 01:57:24 +00007756 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) {
Sanjay Patel280cfd12016-06-15 21:20:04 +00007757 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]);
Craig Topper01600632016-07-08 01:57:24 +00007758 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType());
Sanjay Patel280cfd12016-06-15 21:20:04 +00007759 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy);
7760 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy);
7761 return Builder.CreateBitCast(Sext, FPVecTy);
7762 };
7763
Anders Carlsson895af082007-12-09 23:17:02 +00007764 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00007765 default: return nullptr;
Craig Topper2c03e532017-08-28 05:43:23 +00007766 case X86::BI__builtin_cpu_init: {
7767 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
7768 /*Variadic*/false);
7769 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy,
7770 "__cpu_indicator_init");
7771 return Builder.CreateCall(Func);
7772 }
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007773 case X86::BI_mm_prefetch: {
John McCall7f416cc2015-09-08 08:05:57 +00007774 Value *Address = Ops[0];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007775 Value *RW = ConstantInt::get(Int32Ty, 0);
John McCall7f416cc2015-09-08 08:05:57 +00007776 Value *Locality = Ops[1];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007777 Value *Data = ConstantInt::get(Int32Ty, 1);
7778 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00007779 return Builder.CreateCall(F, {Address, RW, Locality, Data});
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007780 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007781 case X86::BI_mm_clflush: {
7782 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush),
7783 Ops[0]);
7784 }
7785 case X86::BI_mm_lfence: {
7786 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence));
7787 }
7788 case X86::BI_mm_mfence: {
7789 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence));
7790 }
7791 case X86::BI_mm_sfence: {
7792 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence));
7793 }
7794 case X86::BI_mm_pause: {
7795 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause));
7796 }
7797 case X86::BI__rdtsc: {
7798 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc));
7799 }
Simon Pilgrim5aba9922015-08-26 21:17:12 +00007800 case X86::BI__builtin_ia32_undef128:
7801 case X86::BI__builtin_ia32_undef256:
7802 case X86::BI__builtin_ia32_undef512:
Sanjay Patele795daa2017-03-12 19:15:10 +00007803 // The x86 definition of "undef" is not the same as the LLVM definition
7804 // (PR32176). We leave optimizing away an unnecessary zero constant to the
7805 // IR optimizer and backend.
7806 // TODO: If we had a "freeze" IR instruction to generate a fixed undef
7807 // value, we should use that here instead of a zero.
7808 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Bill Wendling65b2a962010-10-09 08:47:25 +00007809 case X86::BI__builtin_ia32_vec_init_v8qi:
7810 case X86::BI__builtin_ia32_vec_init_v4hi:
7811 case X86::BI__builtin_ia32_vec_init_v2si:
7812 return Builder.CreateBitCast(BuildVector(Ops),
John McCallad7c5c12011-02-08 08:22:06 +00007813 llvm::Type::getX86_MMXTy(getLLVMContext()));
Argyrios Kyrtzidis073c9cb2010-10-10 03:19:11 +00007814 case X86::BI__builtin_ia32_vec_ext_v2si:
7815 return Builder.CreateExtractElement(Ops[0],
7816 llvm::ConstantInt::get(Ops[1]->getType(), 0));
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007817 case X86::BI_mm_setcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007818 case X86::BI__builtin_ia32_ldmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007819 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Nate Begeman91f40e32008-04-14 04:49:57 +00007820 Builder.CreateStore(Ops[0], Tmp);
7821 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007822 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007823 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007824 case X86::BI_mm_getcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007825 case X86::BI__builtin_ia32_stmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007826 Address Tmp = CreateMemTemp(E->getType());
Ted Kremenekc14efa72011-08-17 21:04:19 +00007827 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007828 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007829 return Builder.CreateLoad(Tmp, "stmxcsr");
7830 }
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007831 case X86::BI__builtin_ia32_xsave:
7832 case X86::BI__builtin_ia32_xsave64:
7833 case X86::BI__builtin_ia32_xrstor:
7834 case X86::BI__builtin_ia32_xrstor64:
7835 case X86::BI__builtin_ia32_xsaveopt:
7836 case X86::BI__builtin_ia32_xsaveopt64:
7837 case X86::BI__builtin_ia32_xrstors:
7838 case X86::BI__builtin_ia32_xrstors64:
7839 case X86::BI__builtin_ia32_xsavec:
7840 case X86::BI__builtin_ia32_xsavec64:
7841 case X86::BI__builtin_ia32_xsaves:
Reid Kleckner66e77172016-08-16 16:04:14 +00007842 case X86::BI__builtin_ia32_xsaves64: {
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007843 Intrinsic::ID ID;
7844#define INTRINSIC_X86_XSAVE_ID(NAME) \
7845 case X86::BI__builtin_ia32_##NAME: \
7846 ID = Intrinsic::x86_##NAME; \
7847 break
7848 switch (BuiltinID) {
7849 default: llvm_unreachable("Unsupported intrinsic!");
7850 INTRINSIC_X86_XSAVE_ID(xsave);
7851 INTRINSIC_X86_XSAVE_ID(xsave64);
7852 INTRINSIC_X86_XSAVE_ID(xrstor);
7853 INTRINSIC_X86_XSAVE_ID(xrstor64);
7854 INTRINSIC_X86_XSAVE_ID(xsaveopt);
7855 INTRINSIC_X86_XSAVE_ID(xsaveopt64);
7856 INTRINSIC_X86_XSAVE_ID(xrstors);
7857 INTRINSIC_X86_XSAVE_ID(xrstors64);
7858 INTRINSIC_X86_XSAVE_ID(xsavec);
7859 INTRINSIC_X86_XSAVE_ID(xsavec64);
7860 INTRINSIC_X86_XSAVE_ID(xsaves);
7861 INTRINSIC_X86_XSAVE_ID(xsaves64);
7862 }
7863#undef INTRINSIC_X86_XSAVE_ID
7864 Value *Mhi = Builder.CreateTrunc(
7865 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty);
7866 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty);
7867 Ops[1] = Mhi;
7868 Ops.push_back(Mlo);
7869 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
7870 }
Craig Topper6e891fb2016-05-31 01:50:10 +00007871 case X86::BI__builtin_ia32_storedqudi128_mask:
7872 case X86::BI__builtin_ia32_storedqusi128_mask:
7873 case X86::BI__builtin_ia32_storedquhi128_mask:
7874 case X86::BI__builtin_ia32_storedquqi128_mask:
7875 case X86::BI__builtin_ia32_storeupd128_mask:
7876 case X86::BI__builtin_ia32_storeups128_mask:
7877 case X86::BI__builtin_ia32_storedqudi256_mask:
7878 case X86::BI__builtin_ia32_storedqusi256_mask:
7879 case X86::BI__builtin_ia32_storedquhi256_mask:
7880 case X86::BI__builtin_ia32_storedquqi256_mask:
7881 case X86::BI__builtin_ia32_storeupd256_mask:
7882 case X86::BI__builtin_ia32_storeups256_mask:
7883 case X86::BI__builtin_ia32_storedqudi512_mask:
7884 case X86::BI__builtin_ia32_storedqusi512_mask:
7885 case X86::BI__builtin_ia32_storedquhi512_mask:
7886 case X86::BI__builtin_ia32_storedquqi512_mask:
7887 case X86::BI__builtin_ia32_storeupd512_mask:
7888 case X86::BI__builtin_ia32_storeups512_mask:
7889 return EmitX86MaskedStore(*this, Ops, 1);
7890
Ayman Musae60a41c2016-11-08 12:00:30 +00007891 case X86::BI__builtin_ia32_storess128_mask:
7892 case X86::BI__builtin_ia32_storesd128_mask: {
7893 return EmitX86MaskedStore(*this, Ops, 16);
7894 }
Oren Ben Simhon140c1fb2017-05-25 13:44:11 +00007895 case X86::BI__builtin_ia32_vpopcntd_512:
7896 case X86::BI__builtin_ia32_vpopcntq_512: {
7897 llvm::Type *ResultType = ConvertType(E->getType());
7898 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
7899 return Builder.CreateCall(F, Ops);
7900 }
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007901 case X86::BI__builtin_ia32_cvtmask2b128:
7902 case X86::BI__builtin_ia32_cvtmask2b256:
7903 case X86::BI__builtin_ia32_cvtmask2b512:
7904 case X86::BI__builtin_ia32_cvtmask2w128:
7905 case X86::BI__builtin_ia32_cvtmask2w256:
7906 case X86::BI__builtin_ia32_cvtmask2w512:
7907 case X86::BI__builtin_ia32_cvtmask2d128:
7908 case X86::BI__builtin_ia32_cvtmask2d256:
7909 case X86::BI__builtin_ia32_cvtmask2d512:
7910 case X86::BI__builtin_ia32_cvtmask2q128:
7911 case X86::BI__builtin_ia32_cvtmask2q256:
7912 case X86::BI__builtin_ia32_cvtmask2q512:
7913 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType()));
7914
Craig Topper6e891fb2016-05-31 01:50:10 +00007915 case X86::BI__builtin_ia32_movdqa32store128_mask:
7916 case X86::BI__builtin_ia32_movdqa64store128_mask:
7917 case X86::BI__builtin_ia32_storeaps128_mask:
7918 case X86::BI__builtin_ia32_storeapd128_mask:
7919 case X86::BI__builtin_ia32_movdqa32store256_mask:
7920 case X86::BI__builtin_ia32_movdqa64store256_mask:
7921 case X86::BI__builtin_ia32_storeaps256_mask:
7922 case X86::BI__builtin_ia32_storeapd256_mask:
7923 case X86::BI__builtin_ia32_movdqa32store512_mask:
7924 case X86::BI__builtin_ia32_movdqa64store512_mask:
7925 case X86::BI__builtin_ia32_storeaps512_mask:
7926 case X86::BI__builtin_ia32_storeapd512_mask: {
7927 unsigned Align =
7928 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7929 return EmitX86MaskedStore(*this, Ops, Align);
7930 }
Craig Topper4b060e32016-05-31 06:58:07 +00007931 case X86::BI__builtin_ia32_loadups128_mask:
7932 case X86::BI__builtin_ia32_loadups256_mask:
7933 case X86::BI__builtin_ia32_loadups512_mask:
7934 case X86::BI__builtin_ia32_loadupd128_mask:
7935 case X86::BI__builtin_ia32_loadupd256_mask:
7936 case X86::BI__builtin_ia32_loadupd512_mask:
7937 case X86::BI__builtin_ia32_loaddquqi128_mask:
7938 case X86::BI__builtin_ia32_loaddquqi256_mask:
7939 case X86::BI__builtin_ia32_loaddquqi512_mask:
7940 case X86::BI__builtin_ia32_loaddquhi128_mask:
7941 case X86::BI__builtin_ia32_loaddquhi256_mask:
7942 case X86::BI__builtin_ia32_loaddquhi512_mask:
7943 case X86::BI__builtin_ia32_loaddqusi128_mask:
7944 case X86::BI__builtin_ia32_loaddqusi256_mask:
7945 case X86::BI__builtin_ia32_loaddqusi512_mask:
7946 case X86::BI__builtin_ia32_loaddqudi128_mask:
7947 case X86::BI__builtin_ia32_loaddqudi256_mask:
7948 case X86::BI__builtin_ia32_loaddqudi512_mask:
7949 return EmitX86MaskedLoad(*this, Ops, 1);
7950
Ayman Musae60a41c2016-11-08 12:00:30 +00007951 case X86::BI__builtin_ia32_loadss128_mask:
7952 case X86::BI__builtin_ia32_loadsd128_mask:
7953 return EmitX86MaskedLoad(*this, Ops, 16);
7954
Craig Topper4b060e32016-05-31 06:58:07 +00007955 case X86::BI__builtin_ia32_loadaps128_mask:
7956 case X86::BI__builtin_ia32_loadaps256_mask:
7957 case X86::BI__builtin_ia32_loadaps512_mask:
7958 case X86::BI__builtin_ia32_loadapd128_mask:
7959 case X86::BI__builtin_ia32_loadapd256_mask:
7960 case X86::BI__builtin_ia32_loadapd512_mask:
7961 case X86::BI__builtin_ia32_movdqa32load128_mask:
7962 case X86::BI__builtin_ia32_movdqa32load256_mask:
7963 case X86::BI__builtin_ia32_movdqa32load512_mask:
7964 case X86::BI__builtin_ia32_movdqa64load128_mask:
7965 case X86::BI__builtin_ia32_movdqa64load256_mask:
7966 case X86::BI__builtin_ia32_movdqa64load512_mask: {
7967 unsigned Align =
7968 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7969 return EmitX86MaskedLoad(*this, Ops, Align);
7970 }
Simon Pilgrim2d851732016-07-22 13:58:56 +00007971
7972 case X86::BI__builtin_ia32_vbroadcastf128_pd256:
7973 case X86::BI__builtin_ia32_vbroadcastf128_ps256: {
7974 llvm::Type *DstTy = ConvertType(E->getType());
Chandler Carruth4c5e8cc2016-08-10 07:32:47 +00007975 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1);
Simon Pilgrim2d851732016-07-22 13:58:56 +00007976 }
7977
Nate Begeman91f40e32008-04-14 04:49:57 +00007978 case X86::BI__builtin_ia32_storehps:
7979 case X86::BI__builtin_ia32_storelps: {
Chris Lattner5e016ae2010-06-27 07:15:29 +00007980 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty);
7981 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2);
Mike Stump11289f42009-09-09 15:08:12 +00007982
Nate Begeman91f40e32008-04-14 04:49:57 +00007983 // cast val v2i64
7984 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
Mike Stump11289f42009-09-09 15:08:12 +00007985
Nate Begeman91f40e32008-04-14 04:49:57 +00007986 // extract (0, 1)
7987 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
Michael J. Spencerdd597752014-05-31 00:22:12 +00007988 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index);
Nate Begeman91f40e32008-04-14 04:49:57 +00007989 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
7990
7991 // cast pointer to i64 & store
7992 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00007993 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begeman91f40e32008-04-14 04:49:57 +00007994 }
Craig Topper480e2b62015-02-17 06:37:58 +00007995 case X86::BI__builtin_ia32_palignr128:
Craig Topperf51cc072016-06-06 06:13:01 +00007996 case X86::BI__builtin_ia32_palignr256:
Craig Topperf51cc072016-06-06 06:13:01 +00007997 case X86::BI__builtin_ia32_palignr512_mask: {
Craig Topper480e2b62015-02-17 06:37:58 +00007998 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
Craig Topper94aba2c2011-12-19 07:03:25 +00007999
Craig Topperf2f1a092016-07-08 02:17:35 +00008000 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topper480e2b62015-02-17 06:37:58 +00008001 assert(NumElts % 16 == 0);
Craig Topper480e2b62015-02-17 06:37:58 +00008002
Craig Topper480e2b62015-02-17 06:37:58 +00008003 // If palignr is shifting the pair of vectors more than the size of two
8004 // lanes, emit zero.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008005 if (ShiftVal >= 32)
Craig Topper480e2b62015-02-17 06:37:58 +00008006 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Craig Topper94aba2c2011-12-19 07:03:25 +00008007
Craig Topper480e2b62015-02-17 06:37:58 +00008008 // If palignr is shifting the pair of input vectors more than one lane,
Craig Topper96f9a572015-02-17 07:18:01 +00008009 // but less than two lanes, convert to shifting in zeroes.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008010 if (ShiftVal > 16) {
8011 ShiftVal -= 16;
Benjamin Kramerb5960562015-07-20 15:31:17 +00008012 Ops[1] = Ops[0];
Craig Topper96f9a572015-02-17 07:18:01 +00008013 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType());
Craig Topper94aba2c2011-12-19 07:03:25 +00008014 }
8015
Craig Topperd1cb4ce2016-06-12 00:41:24 +00008016 uint32_t Indices[64];
Craig Topper96f9a572015-02-17 07:18:01 +00008017 // 256-bit palignr operates on 128-bit lanes so we need to handle that
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008018 for (unsigned l = 0; l != NumElts; l += 16) {
8019 for (unsigned i = 0; i != 16; ++i) {
Craig Topper96f9a572015-02-17 07:18:01 +00008020 unsigned Idx = ShiftVal + i;
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008021 if (Idx >= 16)
8022 Idx += NumElts - 16; // End of lane, switch operand.
Benjamin Kramerc385a802015-07-28 15:40:11 +00008023 Indices[l + i] = Idx + l;
Craig Topper96f9a572015-02-17 07:18:01 +00008024 }
8025 }
8026
Craig Topperf51cc072016-06-06 06:13:01 +00008027 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0],
8028 makeArrayRef(Indices, NumElts),
8029 "palignr");
8030
8031 // If this isn't a masked builtin, just return the align operation.
8032 if (Ops.size() == 3)
8033 return Align;
8034
Simon Pilgrim532de1c2016-06-13 10:05:19 +00008035 return EmitX86Select(*this, Ops[4], Align, Ops[3]);
8036 }
8037
Craig Topper8cd7b0c2017-09-15 23:00:59 +00008038 case X86::BI__builtin_ia32_vperm2f128_pd256:
8039 case X86::BI__builtin_ia32_vperm2f128_ps256:
8040 case X86::BI__builtin_ia32_vperm2f128_si256:
8041 case X86::BI__builtin_ia32_permti256: {
8042 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
8043 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
8044
8045 // This takes a very simple approach since there are two lanes and a
8046 // shuffle can have 2 inputs. So we reserve the first input for the first
8047 // lane and the second input for the second lane. This may result in
8048 // duplicate sources, but this can be dealt with in the backend.
8049
8050 Value *OutOps[2];
8051 uint32_t Indices[8];
8052 for (unsigned l = 0; l != 2; ++l) {
8053 // Determine the source for this lane.
8054 if (Imm & (1 << ((l * 4) + 3)))
8055 OutOps[l] = llvm::ConstantAggregateZero::get(Ops[0]->getType());
8056 else if (Imm & (1 << ((l * 4) + 1)))
8057 OutOps[l] = Ops[1];
8058 else
8059 OutOps[l] = Ops[0];
8060
8061 for (unsigned i = 0; i != NumElts/2; ++i) {
8062 // Start with ith element of the source for this lane.
8063 unsigned Idx = (l * NumElts) + i;
8064 // If bit 0 of the immediate half is set, switch to the high half of
8065 // the source.
8066 if (Imm & (1 << (l * 4)))
8067 Idx += NumElts/2;
8068 Indices[(l * (NumElts/2)) + i] = Idx;
8069 }
8070 }
8071
8072 return Builder.CreateShuffleVector(OutOps[0], OutOps[1],
8073 makeArrayRef(Indices, NumElts),
8074 "vperm");
8075 }
8076
Simon Pilgrim532de1c2016-06-13 10:05:19 +00008077 case X86::BI__builtin_ia32_movnti:
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008078 case X86::BI__builtin_ia32_movnti64:
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008079 case X86::BI__builtin_ia32_movntsd:
8080 case X86::BI__builtin_ia32_movntss: {
8081 llvm::MDNode *Node = llvm::MDNode::get(
8082 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
8083
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008084 Value *Ptr = Ops[0];
8085 Value *Src = Ops[1];
8086
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008087 // Extract the 0'th element of the source vector.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008088 if (BuiltinID == X86::BI__builtin_ia32_movntsd ||
8089 BuiltinID == X86::BI__builtin_ia32_movntss)
8090 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008091
8092 // Convert the type of the pointer to a pointer to the stored type.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008093 Value *BC = Builder.CreateBitCast(
8094 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008095
8096 // Unaligned nontemporal store of the scalar value.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008097 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC);
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008098 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
8099 SI->setAlignment(1);
8100 return SI;
8101 }
8102
Simon Pilgrim532de1c2016-06-13 10:05:19 +00008103 case X86::BI__builtin_ia32_selectb_128:
Igor Bregeraadb8762016-06-08 13:59:20 +00008104 case X86::BI__builtin_ia32_selectb_256:
8105 case X86::BI__builtin_ia32_selectb_512:
8106 case X86::BI__builtin_ia32_selectw_128:
8107 case X86::BI__builtin_ia32_selectw_256:
8108 case X86::BI__builtin_ia32_selectw_512:
8109 case X86::BI__builtin_ia32_selectd_128:
8110 case X86::BI__builtin_ia32_selectd_256:
8111 case X86::BI__builtin_ia32_selectd_512:
8112 case X86::BI__builtin_ia32_selectq_128:
8113 case X86::BI__builtin_ia32_selectq_256:
8114 case X86::BI__builtin_ia32_selectq_512:
8115 case X86::BI__builtin_ia32_selectps_128:
8116 case X86::BI__builtin_ia32_selectps_256:
8117 case X86::BI__builtin_ia32_selectps_512:
8118 case X86::BI__builtin_ia32_selectpd_128:
8119 case X86::BI__builtin_ia32_selectpd_256:
8120 case X86::BI__builtin_ia32_selectpd_512:
Craig Topperc1442972016-06-09 05:15:00 +00008121 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]);
Craig Toppera54c21e2016-06-15 14:06:34 +00008122 case X86::BI__builtin_ia32_pcmpeqb128_mask:
8123 case X86::BI__builtin_ia32_pcmpeqb256_mask:
8124 case X86::BI__builtin_ia32_pcmpeqb512_mask:
8125 case X86::BI__builtin_ia32_pcmpeqw128_mask:
8126 case X86::BI__builtin_ia32_pcmpeqw256_mask:
8127 case X86::BI__builtin_ia32_pcmpeqw512_mask:
8128 case X86::BI__builtin_ia32_pcmpeqd128_mask:
8129 case X86::BI__builtin_ia32_pcmpeqd256_mask:
8130 case X86::BI__builtin_ia32_pcmpeqd512_mask:
8131 case X86::BI__builtin_ia32_pcmpeqq128_mask:
8132 case X86::BI__builtin_ia32_pcmpeqq256_mask:
8133 case X86::BI__builtin_ia32_pcmpeqq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00008134 return EmitX86MaskedCompare(*this, 0, false, Ops);
Craig Toppera54c21e2016-06-15 14:06:34 +00008135 case X86::BI__builtin_ia32_pcmpgtb128_mask:
8136 case X86::BI__builtin_ia32_pcmpgtb256_mask:
8137 case X86::BI__builtin_ia32_pcmpgtb512_mask:
8138 case X86::BI__builtin_ia32_pcmpgtw128_mask:
8139 case X86::BI__builtin_ia32_pcmpgtw256_mask:
8140 case X86::BI__builtin_ia32_pcmpgtw512_mask:
8141 case X86::BI__builtin_ia32_pcmpgtd128_mask:
8142 case X86::BI__builtin_ia32_pcmpgtd256_mask:
8143 case X86::BI__builtin_ia32_pcmpgtd512_mask:
8144 case X86::BI__builtin_ia32_pcmpgtq128_mask:
8145 case X86::BI__builtin_ia32_pcmpgtq256_mask:
8146 case X86::BI__builtin_ia32_pcmpgtq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00008147 return EmitX86MaskedCompare(*this, 6, true, Ops);
8148 case X86::BI__builtin_ia32_cmpb128_mask:
8149 case X86::BI__builtin_ia32_cmpb256_mask:
8150 case X86::BI__builtin_ia32_cmpb512_mask:
8151 case X86::BI__builtin_ia32_cmpw128_mask:
8152 case X86::BI__builtin_ia32_cmpw256_mask:
8153 case X86::BI__builtin_ia32_cmpw512_mask:
8154 case X86::BI__builtin_ia32_cmpd128_mask:
8155 case X86::BI__builtin_ia32_cmpd256_mask:
8156 case X86::BI__builtin_ia32_cmpd512_mask:
8157 case X86::BI__builtin_ia32_cmpq128_mask:
8158 case X86::BI__builtin_ia32_cmpq256_mask:
8159 case X86::BI__builtin_ia32_cmpq512_mask: {
8160 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
8161 return EmitX86MaskedCompare(*this, CC, true, Ops);
8162 }
8163 case X86::BI__builtin_ia32_ucmpb128_mask:
8164 case X86::BI__builtin_ia32_ucmpb256_mask:
8165 case X86::BI__builtin_ia32_ucmpb512_mask:
8166 case X86::BI__builtin_ia32_ucmpw128_mask:
8167 case X86::BI__builtin_ia32_ucmpw256_mask:
8168 case X86::BI__builtin_ia32_ucmpw512_mask:
8169 case X86::BI__builtin_ia32_ucmpd128_mask:
8170 case X86::BI__builtin_ia32_ucmpd256_mask:
8171 case X86::BI__builtin_ia32_ucmpd512_mask:
8172 case X86::BI__builtin_ia32_ucmpq128_mask:
8173 case X86::BI__builtin_ia32_ucmpq256_mask:
8174 case X86::BI__builtin_ia32_ucmpq512_mask: {
8175 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
8176 return EmitX86MaskedCompare(*this, CC, false, Ops);
8177 }
Sanjay Patel7495ec02016-06-15 17:18:50 +00008178
Craig Topper46e75552016-07-06 04:24:29 +00008179 case X86::BI__builtin_ia32_vplzcntd_128_mask:
8180 case X86::BI__builtin_ia32_vplzcntd_256_mask:
8181 case X86::BI__builtin_ia32_vplzcntd_512_mask:
8182 case X86::BI__builtin_ia32_vplzcntq_128_mask:
8183 case X86::BI__builtin_ia32_vplzcntq_256_mask:
8184 case X86::BI__builtin_ia32_vplzcntq_512_mask: {
8185 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType());
8186 return EmitX86Select(*this, Ops[2],
8187 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}),
8188 Ops[1]);
8189 }
8190
Uriel Korach3fba3c32017-09-13 09:02:02 +00008191 case X86::BI__builtin_ia32_pabsb128:
8192 case X86::BI__builtin_ia32_pabsw128:
8193 case X86::BI__builtin_ia32_pabsd128:
8194 case X86::BI__builtin_ia32_pabsb256:
8195 case X86::BI__builtin_ia32_pabsw256:
8196 case X86::BI__builtin_ia32_pabsd256:
8197 case X86::BI__builtin_ia32_pabsq128_mask:
8198 case X86::BI__builtin_ia32_pabsq256_mask:
8199 case X86::BI__builtin_ia32_pabsb512_mask:
8200 case X86::BI__builtin_ia32_pabsw512_mask:
8201 case X86::BI__builtin_ia32_pabsd512_mask:
8202 case X86::BI__builtin_ia32_pabsq512_mask:
8203 return EmitX86Abs(*this, Ops);
8204
Sanjay Patel7495ec02016-06-15 17:18:50 +00008205 case X86::BI__builtin_ia32_pmaxsb128:
8206 case X86::BI__builtin_ia32_pmaxsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008207 case X86::BI__builtin_ia32_pmaxsd128:
Craig Topper531ce282016-10-24 04:04:24 +00008208 case X86::BI__builtin_ia32_pmaxsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008209 case X86::BI__builtin_ia32_pmaxsb256:
8210 case X86::BI__builtin_ia32_pmaxsw256:
Craig Topper531ce282016-10-24 04:04:24 +00008211 case X86::BI__builtin_ia32_pmaxsd256:
8212 case X86::BI__builtin_ia32_pmaxsq256_mask:
8213 case X86::BI__builtin_ia32_pmaxsb512_mask:
8214 case X86::BI__builtin_ia32_pmaxsw512_mask:
8215 case X86::BI__builtin_ia32_pmaxsd512_mask:
8216 case X86::BI__builtin_ia32_pmaxsq512_mask:
8217 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008218 case X86::BI__builtin_ia32_pmaxub128:
8219 case X86::BI__builtin_ia32_pmaxuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008220 case X86::BI__builtin_ia32_pmaxud128:
Craig Topper531ce282016-10-24 04:04:24 +00008221 case X86::BI__builtin_ia32_pmaxuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008222 case X86::BI__builtin_ia32_pmaxub256:
8223 case X86::BI__builtin_ia32_pmaxuw256:
Craig Topper531ce282016-10-24 04:04:24 +00008224 case X86::BI__builtin_ia32_pmaxud256:
8225 case X86::BI__builtin_ia32_pmaxuq256_mask:
8226 case X86::BI__builtin_ia32_pmaxub512_mask:
8227 case X86::BI__builtin_ia32_pmaxuw512_mask:
8228 case X86::BI__builtin_ia32_pmaxud512_mask:
8229 case X86::BI__builtin_ia32_pmaxuq512_mask:
8230 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008231 case X86::BI__builtin_ia32_pminsb128:
8232 case X86::BI__builtin_ia32_pminsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008233 case X86::BI__builtin_ia32_pminsd128:
Craig Topper531ce282016-10-24 04:04:24 +00008234 case X86::BI__builtin_ia32_pminsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008235 case X86::BI__builtin_ia32_pminsb256:
8236 case X86::BI__builtin_ia32_pminsw256:
Craig Topper531ce282016-10-24 04:04:24 +00008237 case X86::BI__builtin_ia32_pminsd256:
8238 case X86::BI__builtin_ia32_pminsq256_mask:
8239 case X86::BI__builtin_ia32_pminsb512_mask:
8240 case X86::BI__builtin_ia32_pminsw512_mask:
8241 case X86::BI__builtin_ia32_pminsd512_mask:
8242 case X86::BI__builtin_ia32_pminsq512_mask:
8243 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008244 case X86::BI__builtin_ia32_pminub128:
8245 case X86::BI__builtin_ia32_pminuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008246 case X86::BI__builtin_ia32_pminud128:
Craig Topper531ce282016-10-24 04:04:24 +00008247 case X86::BI__builtin_ia32_pminuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008248 case X86::BI__builtin_ia32_pminub256:
8249 case X86::BI__builtin_ia32_pminuw256:
Craig Topper531ce282016-10-24 04:04:24 +00008250 case X86::BI__builtin_ia32_pminud256:
8251 case X86::BI__builtin_ia32_pminuq256_mask:
8252 case X86::BI__builtin_ia32_pminub512_mask:
8253 case X86::BI__builtin_ia32_pminuw512_mask:
8254 case X86::BI__builtin_ia32_pminud512_mask:
8255 case X86::BI__builtin_ia32_pminuq512_mask:
8256 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008257
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008258 // 3DNow!
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008259 case X86::BI__builtin_ia32_pswapdsf:
8260 case X86::BI__builtin_ia32_pswapdsi: {
Chandler Carrutha2a54102012-02-20 07:35:45 +00008261 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext());
8262 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast");
Craig Topperd2f814d2015-02-16 21:30:08 +00008263 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd);
8264 return Builder.CreateCall(F, Ops, "pswapd");
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008265 }
Benjamin Kramera43b6992012-07-12 09:33:03 +00008266 case X86::BI__builtin_ia32_rdrand16_step:
8267 case X86::BI__builtin_ia32_rdrand32_step:
Michael Liaoffaae352013-03-29 05:17:55 +00008268 case X86::BI__builtin_ia32_rdrand64_step:
8269 case X86::BI__builtin_ia32_rdseed16_step:
8270 case X86::BI__builtin_ia32_rdseed32_step:
8271 case X86::BI__builtin_ia32_rdseed64_step: {
Benjamin Kramera43b6992012-07-12 09:33:03 +00008272 Intrinsic::ID ID;
8273 switch (BuiltinID) {
8274 default: llvm_unreachable("Unsupported intrinsic!");
8275 case X86::BI__builtin_ia32_rdrand16_step:
8276 ID = Intrinsic::x86_rdrand_16;
8277 break;
8278 case X86::BI__builtin_ia32_rdrand32_step:
8279 ID = Intrinsic::x86_rdrand_32;
8280 break;
8281 case X86::BI__builtin_ia32_rdrand64_step:
8282 ID = Intrinsic::x86_rdrand_64;
8283 break;
Michael Liaoffaae352013-03-29 05:17:55 +00008284 case X86::BI__builtin_ia32_rdseed16_step:
8285 ID = Intrinsic::x86_rdseed_16;
8286 break;
8287 case X86::BI__builtin_ia32_rdseed32_step:
8288 ID = Intrinsic::x86_rdseed_32;
8289 break;
8290 case X86::BI__builtin_ia32_rdseed64_step:
8291 ID = Intrinsic::x86_rdseed_64;
8292 break;
Benjamin Kramera43b6992012-07-12 09:33:03 +00008293 }
8294
David Blaikie4ba525b2015-07-14 17:27:39 +00008295 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID));
John McCall7f416cc2015-09-08 08:05:57 +00008296 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0),
8297 Ops[0]);
Benjamin Kramera43b6992012-07-12 09:33:03 +00008298 return Builder.CreateExtractValue(Call, 1);
8299 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008300
8301 // SSE packed comparison intrinsics
Craig Topper2094d8f2014-12-27 06:59:57 +00008302 case X86::BI__builtin_ia32_cmpeqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008303 case X86::BI__builtin_ia32_cmpeqpd:
Craig Topper01600632016-07-08 01:57:24 +00008304 return getVectorFCmpIR(CmpInst::FCMP_OEQ);
Craig Topper925ef0a2016-07-08 01:48:44 +00008305 case X86::BI__builtin_ia32_cmpltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008306 case X86::BI__builtin_ia32_cmpltpd:
Craig Topper01600632016-07-08 01:57:24 +00008307 return getVectorFCmpIR(CmpInst::FCMP_OLT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008308 case X86::BI__builtin_ia32_cmpleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008309 case X86::BI__builtin_ia32_cmplepd:
Craig Topper01600632016-07-08 01:57:24 +00008310 return getVectorFCmpIR(CmpInst::FCMP_OLE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008311 case X86::BI__builtin_ia32_cmpunordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008312 case X86::BI__builtin_ia32_cmpunordpd:
Craig Topper01600632016-07-08 01:57:24 +00008313 return getVectorFCmpIR(CmpInst::FCMP_UNO);
Craig Topper925ef0a2016-07-08 01:48:44 +00008314 case X86::BI__builtin_ia32_cmpneqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008315 case X86::BI__builtin_ia32_cmpneqpd:
Craig Topper01600632016-07-08 01:57:24 +00008316 return getVectorFCmpIR(CmpInst::FCMP_UNE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008317 case X86::BI__builtin_ia32_cmpnltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008318 case X86::BI__builtin_ia32_cmpnltpd:
Craig Topper01600632016-07-08 01:57:24 +00008319 return getVectorFCmpIR(CmpInst::FCMP_UGE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008320 case X86::BI__builtin_ia32_cmpnleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008321 case X86::BI__builtin_ia32_cmpnlepd:
Craig Topper01600632016-07-08 01:57:24 +00008322 return getVectorFCmpIR(CmpInst::FCMP_UGT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008323 case X86::BI__builtin_ia32_cmpordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008324 case X86::BI__builtin_ia32_cmpordpd:
Craig Topper01600632016-07-08 01:57:24 +00008325 return getVectorFCmpIR(CmpInst::FCMP_ORD);
Craig Topper425d02d2016-07-06 06:27:31 +00008326 case X86::BI__builtin_ia32_cmpps:
8327 case X86::BI__builtin_ia32_cmpps256:
8328 case X86::BI__builtin_ia32_cmppd:
8329 case X86::BI__builtin_ia32_cmppd256: {
8330 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
8331 // If this one of the SSE immediates, we can use native IR.
8332 if (CC < 8) {
8333 FCmpInst::Predicate Pred;
8334 switch (CC) {
8335 case 0: Pred = FCmpInst::FCMP_OEQ; break;
8336 case 1: Pred = FCmpInst::FCMP_OLT; break;
8337 case 2: Pred = FCmpInst::FCMP_OLE; break;
8338 case 3: Pred = FCmpInst::FCMP_UNO; break;
8339 case 4: Pred = FCmpInst::FCMP_UNE; break;
8340 case 5: Pred = FCmpInst::FCMP_UGE; break;
8341 case 6: Pred = FCmpInst::FCMP_UGT; break;
8342 case 7: Pred = FCmpInst::FCMP_ORD; break;
8343 }
Craig Topper01600632016-07-08 01:57:24 +00008344 return getVectorFCmpIR(Pred);
Craig Topper425d02d2016-07-06 06:27:31 +00008345 }
8346
8347 // We can't handle 8-31 immediates with native IR, use the intrinsic.
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008348 // Except for predicates that create constants.
Craig Topper425d02d2016-07-06 06:27:31 +00008349 Intrinsic::ID ID;
8350 switch (BuiltinID) {
8351 default: llvm_unreachable("Unsupported intrinsic!");
8352 case X86::BI__builtin_ia32_cmpps:
8353 ID = Intrinsic::x86_sse_cmp_ps;
8354 break;
8355 case X86::BI__builtin_ia32_cmpps256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008356 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8357 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8358 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8359 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8360 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) :
8361 llvm::Constant::getNullValue(Builder.getInt32Ty());
8362 Value *Vec = Builder.CreateVectorSplat(
8363 Ops[0]->getType()->getVectorNumElements(), Constant);
8364 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8365 }
Craig Topper425d02d2016-07-06 06:27:31 +00008366 ID = Intrinsic::x86_avx_cmp_ps_256;
8367 break;
8368 case X86::BI__builtin_ia32_cmppd:
8369 ID = Intrinsic::x86_sse2_cmp_pd;
8370 break;
8371 case X86::BI__builtin_ia32_cmppd256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008372 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8373 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8374 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8375 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8376 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) :
8377 llvm::Constant::getNullValue(Builder.getInt64Ty());
8378 Value *Vec = Builder.CreateVectorSplat(
8379 Ops[0]->getType()->getVectorNumElements(), Constant);
8380 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8381 }
Craig Topper425d02d2016-07-06 06:27:31 +00008382 ID = Intrinsic::x86_avx_cmp_pd_256;
8383 break;
8384 }
8385
8386 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
8387 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008388
8389 // SSE scalar comparison intrinsics
8390 case X86::BI__builtin_ia32_cmpeqss:
8391 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0);
8392 case X86::BI__builtin_ia32_cmpltss:
8393 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1);
8394 case X86::BI__builtin_ia32_cmpless:
8395 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2);
8396 case X86::BI__builtin_ia32_cmpunordss:
8397 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3);
8398 case X86::BI__builtin_ia32_cmpneqss:
8399 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4);
8400 case X86::BI__builtin_ia32_cmpnltss:
8401 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5);
8402 case X86::BI__builtin_ia32_cmpnless:
8403 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6);
8404 case X86::BI__builtin_ia32_cmpordss:
8405 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7);
Craig Topper2094d8f2014-12-27 06:59:57 +00008406 case X86::BI__builtin_ia32_cmpeqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008407 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0);
Craig Topper2094d8f2014-12-27 06:59:57 +00008408 case X86::BI__builtin_ia32_cmpltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008409 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1);
Craig Topper2094d8f2014-12-27 06:59:57 +00008410 case X86::BI__builtin_ia32_cmplesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008411 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2);
Craig Topper2094d8f2014-12-27 06:59:57 +00008412 case X86::BI__builtin_ia32_cmpunordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008413 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3);
Craig Topper2094d8f2014-12-27 06:59:57 +00008414 case X86::BI__builtin_ia32_cmpneqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008415 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4);
Craig Topper2094d8f2014-12-27 06:59:57 +00008416 case X86::BI__builtin_ia32_cmpnltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008417 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5);
Craig Topper2094d8f2014-12-27 06:59:57 +00008418 case X86::BI__builtin_ia32_cmpnlesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008419 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6);
Craig Topper2094d8f2014-12-27 06:59:57 +00008420 case X86::BI__builtin_ia32_cmpordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008421 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008422
Albert Gutowski7216f172016-10-10 18:09:27 +00008423 case X86::BI__emul:
8424 case X86::BI__emulu: {
8425 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64);
8426 bool isSigned = (BuiltinID == X86::BI__emul);
8427 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned);
8428 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned);
8429 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned);
8430 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008431 case X86::BI__mulh:
Albert Gutowski7216f172016-10-10 18:09:27 +00008432 case X86::BI__umulh:
8433 case X86::BI_mul128:
8434 case X86::BI_umul128: {
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008435 llvm::Type *ResType = ConvertType(E->getType());
8436 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
8437
Albert Gutowski7216f172016-10-10 18:09:27 +00008438 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128);
8439 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned);
8440 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008441
8442 Value *MulResult, *HigherBits;
8443 if (IsSigned) {
8444 MulResult = Builder.CreateNSWMul(LHS, RHS);
8445 HigherBits = Builder.CreateAShr(MulResult, 64);
8446 } else {
8447 MulResult = Builder.CreateNUWMul(LHS, RHS);
8448 HigherBits = Builder.CreateLShr(MulResult, 64);
8449 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008450 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned);
Albert Gutowski7216f172016-10-10 18:09:27 +00008451
8452 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh)
8453 return HigherBits;
8454
8455 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2));
8456 Builder.CreateStore(HigherBits, HighBitsAddress);
8457 return Builder.CreateIntCast(MulResult, ResType, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008458 }
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008459
8460 case X86::BI__faststorefence: {
8461 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008462 llvm::SyncScope::System);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008463 }
8464 case X86::BI_ReadWriteBarrier:
8465 case X86::BI_ReadBarrier:
8466 case X86::BI_WriteBarrier: {
8467 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008468 llvm::SyncScope::SingleThread);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008469 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00008470 case X86::BI_BitScanForward:
8471 case X86::BI_BitScanForward64:
8472 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
8473 case X86::BI_BitScanReverse:
8474 case X86::BI_BitScanReverse64:
8475 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00008476
8477 case X86::BI_InterlockedAnd64:
8478 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
8479 case X86::BI_InterlockedExchange64:
8480 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
8481 case X86::BI_InterlockedExchangeAdd64:
8482 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
8483 case X86::BI_InterlockedExchangeSub64:
8484 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
8485 case X86::BI_InterlockedOr64:
8486 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
8487 case X86::BI_InterlockedXor64:
8488 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
8489 case X86::BI_InterlockedDecrement64:
8490 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
8491 case X86::BI_InterlockedIncrement64:
8492 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
8493
Albert Gutowski397d81b2016-10-13 16:03:42 +00008494 case X86::BI_AddressOfReturnAddress: {
8495 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
8496 return Builder.CreateCall(F);
8497 }
Albert Gutowski1deab382016-10-14 17:33:05 +00008498 case X86::BI__stosb: {
8499 // We treat __stosb as a volatile memset - it may not generate "rep stosb"
8500 // instruction, but it will create a memset that won't be optimized away.
8501 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true);
8502 }
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008503 case X86::BI__ud2:
8504 // llvm.trap makes a ud2a instruction on x86.
8505 return EmitTrapCall(Intrinsic::trap);
8506 case X86::BI__int2c: {
8507 // This syscall signals a driver assertion failure in x86 NT kernels.
8508 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
8509 llvm::InlineAsm *IA =
8510 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true);
Reid Klecknerde864822017-03-21 16:57:30 +00008511 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
8512 getLLVMContext(), llvm::AttributeList::FunctionIndex,
8513 llvm::Attribute::NoReturn);
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008514 CallSite CS = Builder.CreateCall(IA);
8515 CS.setAttributes(NoReturnAttr);
8516 return CS.getInstruction();
8517 }
Hans Wennborg043f4022017-03-22 19:13:13 +00008518 case X86::BI__readfsbyte:
8519 case X86::BI__readfsword:
8520 case X86::BI__readfsdword:
8521 case X86::BI__readfsqword: {
8522 llvm::Type *IntTy = ConvertType(E->getType());
8523 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8524 llvm::PointerType::get(IntTy, 257));
8525 LoadInst *Load = Builder.CreateAlignedLoad(
8526 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8527 Load->setVolatile(true);
8528 return Load;
8529 }
8530 case X86::BI__readgsbyte:
8531 case X86::BI__readgsword:
8532 case X86::BI__readgsdword:
8533 case X86::BI__readgsqword: {
8534 llvm::Type *IntTy = ConvertType(E->getType());
8535 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8536 llvm::PointerType::get(IntTy, 256));
8537 LoadInst *Load = Builder.CreateAlignedLoad(
8538 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8539 Load->setVolatile(true);
8540 return Load;
8541 }
Anders Carlsson895af082007-12-09 23:17:02 +00008542 }
8543}
8544
Tony Linthicum76329bf2011-12-12 21:14:55 +00008545
Mike Stump11289f42009-09-09 15:08:12 +00008546Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00008547 const CallExpr *E) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00008548 SmallVector<Value*, 4> Ops;
Chris Lattnerdad40622010-04-14 03:54:58 +00008549
8550 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
8551 Ops.push_back(EmitScalarExpr(E->getArg(i)));
8552
8553 Intrinsic::ID ID = Intrinsic::not_intrinsic;
8554
8555 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00008556 default: return nullptr;
Chris Lattnerdad40622010-04-14 03:54:58 +00008557
Hal Finkel65e1e4d2015-08-31 23:55:19 +00008558 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we
8559 // call __builtin_readcyclecounter.
8560 case PPC::BI__builtin_ppc_get_timebase:
8561 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter));
8562
Tony Jiang6a49aad2016-11-15 14:30:56 +00008563 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008564 case PPC::BI__builtin_altivec_lvx:
8565 case PPC::BI__builtin_altivec_lvxl:
8566 case PPC::BI__builtin_altivec_lvebx:
8567 case PPC::BI__builtin_altivec_lvehx:
8568 case PPC::BI__builtin_altivec_lvewx:
8569 case PPC::BI__builtin_altivec_lvsl:
8570 case PPC::BI__builtin_altivec_lvsr:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008571 case PPC::BI__builtin_vsx_lxvd2x:
8572 case PPC::BI__builtin_vsx_lxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008573 case PPC::BI__builtin_vsx_lxvd2x_be:
8574 case PPC::BI__builtin_vsx_lxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008575 case PPC::BI__builtin_vsx_lxvl:
8576 case PPC::BI__builtin_vsx_lxvll:
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008577 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008578 if(BuiltinID == PPC::BI__builtin_vsx_lxvl ||
8579 BuiltinID == PPC::BI__builtin_vsx_lxvll){
8580 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
8581 }else {
8582 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8583 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]);
8584 Ops.pop_back();
8585 }
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008586
8587 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008588 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008589 case PPC::BI__builtin_altivec_lvx:
8590 ID = Intrinsic::ppc_altivec_lvx;
8591 break;
8592 case PPC::BI__builtin_altivec_lvxl:
8593 ID = Intrinsic::ppc_altivec_lvxl;
8594 break;
8595 case PPC::BI__builtin_altivec_lvebx:
8596 ID = Intrinsic::ppc_altivec_lvebx;
8597 break;
8598 case PPC::BI__builtin_altivec_lvehx:
8599 ID = Intrinsic::ppc_altivec_lvehx;
8600 break;
8601 case PPC::BI__builtin_altivec_lvewx:
8602 ID = Intrinsic::ppc_altivec_lvewx;
8603 break;
8604 case PPC::BI__builtin_altivec_lvsl:
8605 ID = Intrinsic::ppc_altivec_lvsl;
8606 break;
8607 case PPC::BI__builtin_altivec_lvsr:
8608 ID = Intrinsic::ppc_altivec_lvsr;
8609 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008610 case PPC::BI__builtin_vsx_lxvd2x:
8611 ID = Intrinsic::ppc_vsx_lxvd2x;
8612 break;
8613 case PPC::BI__builtin_vsx_lxvw4x:
8614 ID = Intrinsic::ppc_vsx_lxvw4x;
8615 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008616 case PPC::BI__builtin_vsx_lxvd2x_be:
8617 ID = Intrinsic::ppc_vsx_lxvd2x_be;
8618 break;
8619 case PPC::BI__builtin_vsx_lxvw4x_be:
8620 ID = Intrinsic::ppc_vsx_lxvw4x_be;
8621 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008622 case PPC::BI__builtin_vsx_lxvl:
8623 ID = Intrinsic::ppc_vsx_lxvl;
8624 break;
8625 case PPC::BI__builtin_vsx_lxvll:
8626 ID = Intrinsic::ppc_vsx_lxvll;
8627 break;
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008628 }
8629 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008630 return Builder.CreateCall(F, Ops, "");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008631 }
8632
Tony Jiang6a49aad2016-11-15 14:30:56 +00008633 // vec_st, vec_xst_be
Chris Lattnerdad40622010-04-14 03:54:58 +00008634 case PPC::BI__builtin_altivec_stvx:
8635 case PPC::BI__builtin_altivec_stvxl:
8636 case PPC::BI__builtin_altivec_stvebx:
8637 case PPC::BI__builtin_altivec_stvehx:
8638 case PPC::BI__builtin_altivec_stvewx:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008639 case PPC::BI__builtin_vsx_stxvd2x:
8640 case PPC::BI__builtin_vsx_stxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008641 case PPC::BI__builtin_vsx_stxvd2x_be:
8642 case PPC::BI__builtin_vsx_stxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008643 case PPC::BI__builtin_vsx_stxvl:
8644 case PPC::BI__builtin_vsx_stxvll:
Chris Lattnerdad40622010-04-14 03:54:58 +00008645 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008646 if(BuiltinID == PPC::BI__builtin_vsx_stxvl ||
8647 BuiltinID == PPC::BI__builtin_vsx_stxvll ){
8648 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8649 }else {
8650 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy);
8651 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]);
8652 Ops.pop_back();
8653 }
Chris Lattnerdad40622010-04-14 03:54:58 +00008654
8655 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008656 default: llvm_unreachable("Unsupported st intrinsic!");
Chris Lattnerdad40622010-04-14 03:54:58 +00008657 case PPC::BI__builtin_altivec_stvx:
8658 ID = Intrinsic::ppc_altivec_stvx;
8659 break;
8660 case PPC::BI__builtin_altivec_stvxl:
8661 ID = Intrinsic::ppc_altivec_stvxl;
8662 break;
8663 case PPC::BI__builtin_altivec_stvebx:
8664 ID = Intrinsic::ppc_altivec_stvebx;
8665 break;
8666 case PPC::BI__builtin_altivec_stvehx:
8667 ID = Intrinsic::ppc_altivec_stvehx;
8668 break;
8669 case PPC::BI__builtin_altivec_stvewx:
8670 ID = Intrinsic::ppc_altivec_stvewx;
8671 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008672 case PPC::BI__builtin_vsx_stxvd2x:
8673 ID = Intrinsic::ppc_vsx_stxvd2x;
8674 break;
8675 case PPC::BI__builtin_vsx_stxvw4x:
8676 ID = Intrinsic::ppc_vsx_stxvw4x;
8677 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008678 case PPC::BI__builtin_vsx_stxvd2x_be:
8679 ID = Intrinsic::ppc_vsx_stxvd2x_be;
8680 break;
8681 case PPC::BI__builtin_vsx_stxvw4x_be:
8682 ID = Intrinsic::ppc_vsx_stxvw4x_be;
8683 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008684 case PPC::BI__builtin_vsx_stxvl:
8685 ID = Intrinsic::ppc_vsx_stxvl;
8686 break;
8687 case PPC::BI__builtin_vsx_stxvll:
8688 ID = Intrinsic::ppc_vsx_stxvll;
8689 break;
Chris Lattnerdad40622010-04-14 03:54:58 +00008690 }
8691 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008692 return Builder.CreateCall(F, Ops, "");
Chris Lattnerdad40622010-04-14 03:54:58 +00008693 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008694 // Square root
8695 case PPC::BI__builtin_vsx_xvsqrtsp:
8696 case PPC::BI__builtin_vsx_xvsqrtdp: {
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008697 llvm::Type *ResultType = ConvertType(E->getType());
8698 Value *X = EmitScalarExpr(E->getArg(0));
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008699 ID = Intrinsic::sqrt;
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008700 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8701 return Builder.CreateCall(F, X);
Chris Lattnerdad40622010-04-14 03:54:58 +00008702 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008703 // Count leading zeros
8704 case PPC::BI__builtin_altivec_vclzb:
8705 case PPC::BI__builtin_altivec_vclzh:
8706 case PPC::BI__builtin_altivec_vclzw:
8707 case PPC::BI__builtin_altivec_vclzd: {
8708 llvm::Type *ResultType = ConvertType(E->getType());
8709 Value *X = EmitScalarExpr(E->getArg(0));
8710 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8711 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
8712 return Builder.CreateCall(F, {X, Undef});
8713 }
Nemanja Ivanovic10e2b5d2016-09-27 10:45:22 +00008714 case PPC::BI__builtin_altivec_vctzb:
8715 case PPC::BI__builtin_altivec_vctzh:
8716 case PPC::BI__builtin_altivec_vctzw:
8717 case PPC::BI__builtin_altivec_vctzd: {
8718 llvm::Type *ResultType = ConvertType(E->getType());
8719 Value *X = EmitScalarExpr(E->getArg(0));
8720 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8721 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
8722 return Builder.CreateCall(F, {X, Undef});
8723 }
8724 case PPC::BI__builtin_altivec_vpopcntb:
8725 case PPC::BI__builtin_altivec_vpopcnth:
8726 case PPC::BI__builtin_altivec_vpopcntw:
8727 case PPC::BI__builtin_altivec_vpopcntd: {
8728 llvm::Type *ResultType = ConvertType(E->getType());
8729 Value *X = EmitScalarExpr(E->getArg(0));
8730 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
8731 return Builder.CreateCall(F, X);
8732 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008733 // Copy sign
8734 case PPC::BI__builtin_vsx_xvcpsgnsp:
8735 case PPC::BI__builtin_vsx_xvcpsgndp: {
8736 llvm::Type *ResultType = ConvertType(E->getType());
8737 Value *X = EmitScalarExpr(E->getArg(0));
8738 Value *Y = EmitScalarExpr(E->getArg(1));
8739 ID = Intrinsic::copysign;
8740 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8741 return Builder.CreateCall(F, {X, Y});
8742 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008743 // Rounding/truncation
8744 case PPC::BI__builtin_vsx_xvrspip:
8745 case PPC::BI__builtin_vsx_xvrdpip:
8746 case PPC::BI__builtin_vsx_xvrdpim:
8747 case PPC::BI__builtin_vsx_xvrspim:
8748 case PPC::BI__builtin_vsx_xvrdpi:
8749 case PPC::BI__builtin_vsx_xvrspi:
8750 case PPC::BI__builtin_vsx_xvrdpic:
8751 case PPC::BI__builtin_vsx_xvrspic:
8752 case PPC::BI__builtin_vsx_xvrdpiz:
8753 case PPC::BI__builtin_vsx_xvrspiz: {
8754 llvm::Type *ResultType = ConvertType(E->getType());
8755 Value *X = EmitScalarExpr(E->getArg(0));
8756 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
8757 BuiltinID == PPC::BI__builtin_vsx_xvrspim)
8758 ID = Intrinsic::floor;
8759 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
8760 BuiltinID == PPC::BI__builtin_vsx_xvrspi)
8761 ID = Intrinsic::round;
8762 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
8763 BuiltinID == PPC::BI__builtin_vsx_xvrspic)
8764 ID = Intrinsic::nearbyint;
8765 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
8766 BuiltinID == PPC::BI__builtin_vsx_xvrspip)
8767 ID = Intrinsic::ceil;
8768 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
8769 BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
8770 ID = Intrinsic::trunc;
8771 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8772 return Builder.CreateCall(F, X);
8773 }
Kit Bartonfbab1582016-03-09 19:28:31 +00008774
8775 // Absolute value
8776 case PPC::BI__builtin_vsx_xvabsdp:
8777 case PPC::BI__builtin_vsx_xvabssp: {
8778 llvm::Type *ResultType = ConvertType(E->getType());
8779 Value *X = EmitScalarExpr(E->getArg(0));
8780 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
8781 return Builder.CreateCall(F, X);
8782 }
8783
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008784 // FMA variations
8785 case PPC::BI__builtin_vsx_xvmaddadp:
8786 case PPC::BI__builtin_vsx_xvmaddasp:
8787 case PPC::BI__builtin_vsx_xvnmaddadp:
8788 case PPC::BI__builtin_vsx_xvnmaddasp:
8789 case PPC::BI__builtin_vsx_xvmsubadp:
8790 case PPC::BI__builtin_vsx_xvmsubasp:
8791 case PPC::BI__builtin_vsx_xvnmsubadp:
8792 case PPC::BI__builtin_vsx_xvnmsubasp: {
8793 llvm::Type *ResultType = ConvertType(E->getType());
8794 Value *X = EmitScalarExpr(E->getArg(0));
8795 Value *Y = EmitScalarExpr(E->getArg(1));
8796 Value *Z = EmitScalarExpr(E->getArg(2));
8797 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
8798 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
8799 switch (BuiltinID) {
8800 case PPC::BI__builtin_vsx_xvmaddadp:
8801 case PPC::BI__builtin_vsx_xvmaddasp:
8802 return Builder.CreateCall(F, {X, Y, Z});
8803 case PPC::BI__builtin_vsx_xvnmaddadp:
8804 case PPC::BI__builtin_vsx_xvnmaddasp:
8805 return Builder.CreateFSub(Zero,
8806 Builder.CreateCall(F, {X, Y, Z}), "sub");
8807 case PPC::BI__builtin_vsx_xvmsubadp:
8808 case PPC::BI__builtin_vsx_xvmsubasp:
8809 return Builder.CreateCall(F,
8810 {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8811 case PPC::BI__builtin_vsx_xvnmsubadp:
8812 case PPC::BI__builtin_vsx_xvnmsubasp:
8813 Value *FsubRes =
8814 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8815 return Builder.CreateFSub(Zero, FsubRes, "sub");
8816 }
8817 llvm_unreachable("Unknown FMA operation");
8818 return nullptr; // Suppress no-return warning
8819 }
Sean Fertile96d9e0e2017-01-05 21:43:30 +00008820
8821 case PPC::BI__builtin_vsx_insertword: {
8822 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
8823
8824 // Third argument is a compile time constant int. It must be clamped to
8825 // to the range [0, 12].
8826 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8827 assert(ArgCI &&
8828 "Third arg to xxinsertw intrinsic must be constant integer");
8829 const int64_t MaxIndex = 12;
8830 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8831
8832 // The builtin semantics don't exactly match the xxinsertw instructions
8833 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the
8834 // word from the first argument, and inserts it in the second argument. The
8835 // instruction extracts the word from its second input register and inserts
8836 // it into its first input register, so swap the first and second arguments.
8837 std::swap(Ops[0], Ops[1]);
8838
8839 // Need to cast the second argument from a vector of unsigned int to a
8840 // vector of long long.
8841 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8842
8843 if (getTarget().isLittleEndian()) {
8844 // Create a shuffle mask of (1, 0)
8845 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8846 ConstantInt::get(Int32Ty, 0)
8847 };
8848 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8849
8850 // Reverse the double words in the vector we will extract from.
8851 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8852 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask);
8853
8854 // Reverse the index.
8855 Index = MaxIndex - Index;
8856 }
8857
8858 // Intrinsic expects the first arg to be a vector of int.
8859 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8860 Ops[2] = ConstantInt::getSigned(Int32Ty, Index);
8861 return Builder.CreateCall(F, Ops);
8862 }
8863
8864 case PPC::BI__builtin_vsx_extractuword: {
8865 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
8866
8867 // Intrinsic expects the first argument to be a vector of doublewords.
8868 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8869
8870 // The second argument is a compile time constant int that needs to
8871 // be clamped to the range [0, 12].
8872 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]);
8873 assert(ArgCI &&
8874 "Second Arg to xxextractuw intrinsic must be a constant integer!");
8875 const int64_t MaxIndex = 12;
8876 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8877
8878 if (getTarget().isLittleEndian()) {
8879 // Reverse the index.
8880 Index = MaxIndex - Index;
8881 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8882
8883 // Emit the call, then reverse the double words of the results vector.
8884 Value *Call = Builder.CreateCall(F, Ops);
8885
8886 // Create a shuffle mask of (1, 0)
8887 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8888 ConstantInt::get(Int32Ty, 0)
8889 };
8890 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8891
8892 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask);
8893 return ShuffleCall;
8894 } else {
8895 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8896 return Builder.CreateCall(F, Ops);
8897 }
8898 }
Tony Jiangbbc48e92017-05-24 15:13:32 +00008899
8900 case PPC::BI__builtin_vsx_xxpermdi: {
8901 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8902 assert(ArgCI && "Third arg must be constant integer!");
8903
8904 unsigned Index = ArgCI->getZExtValue();
8905 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8906 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8907
8908 // Element zero comes from the first input vector and element one comes from
8909 // the second. The element indices within each vector are numbered in big
8910 // endian order so the shuffle mask must be adjusted for this on little
8911 // endian platforms (i.e. index is complemented and source vector reversed).
8912 unsigned ElemIdx0;
8913 unsigned ElemIdx1;
8914 if (getTarget().isLittleEndian()) {
8915 ElemIdx0 = (~Index & 1) + 2;
8916 ElemIdx1 = (~Index & 2) >> 1;
8917 } else { // BigEndian
8918 ElemIdx0 = (Index & 2) >> 1;
8919 ElemIdx1 = 2 + (Index & 1);
8920 }
8921
8922 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0),
8923 ConstantInt::get(Int32Ty, ElemIdx1)};
8924 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8925
8926 Value *ShuffleCall =
8927 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8928 QualType BIRetType = E->getType();
8929 auto RetTy = ConvertType(BIRetType);
8930 return Builder.CreateBitCast(ShuffleCall, RetTy);
8931 }
Tony Jiang9aa2c032017-05-24 15:54:13 +00008932
8933 case PPC::BI__builtin_vsx_xxsldwi: {
8934 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8935 assert(ArgCI && "Third argument must be a compile time constant");
8936 unsigned Index = ArgCI->getZExtValue() & 0x3;
8937 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8938 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4));
8939
8940 // Create a shuffle mask
8941 unsigned ElemIdx0;
8942 unsigned ElemIdx1;
8943 unsigned ElemIdx2;
8944 unsigned ElemIdx3;
8945 if (getTarget().isLittleEndian()) {
8946 // Little endian element N comes from element 8+N-Index of the
8947 // concatenated wide vector (of course, using modulo arithmetic on
8948 // the total number of elements).
8949 ElemIdx0 = (8 - Index) % 8;
8950 ElemIdx1 = (9 - Index) % 8;
8951 ElemIdx2 = (10 - Index) % 8;
8952 ElemIdx3 = (11 - Index) % 8;
8953 } else {
8954 // Big endian ElemIdx<N> = Index + N
8955 ElemIdx0 = Index;
8956 ElemIdx1 = Index + 1;
8957 ElemIdx2 = Index + 2;
8958 ElemIdx3 = Index + 3;
8959 }
8960
8961 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0),
8962 ConstantInt::get(Int32Ty, ElemIdx1),
8963 ConstantInt::get(Int32Ty, ElemIdx2),
8964 ConstantInt::get(Int32Ty, ElemIdx3)};
8965
8966 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8967 Value *ShuffleCall =
8968 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8969 QualType BIRetType = E->getType();
8970 auto RetTy = ConvertType(BIRetType);
8971 return Builder.CreateBitCast(ShuffleCall, RetTy);
8972 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008973 }
Mike Stump11289f42009-09-09 15:08:12 +00008974}
Matt Arsenault56f008d2014-06-24 20:45:01 +00008975
Matt Arsenault3ea39f92015-06-19 17:54:10 +00008976Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
8977 const CallExpr *E) {
Matt Arsenault56f008d2014-06-24 20:45:01 +00008978 switch (BuiltinID) {
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008979 case AMDGPU::BI__builtin_amdgcn_div_scale:
8980 case AMDGPU::BI__builtin_amdgcn_div_scalef: {
Matt Arsenault56f008d2014-06-24 20:45:01 +00008981 // Translate from the intrinsics's struct return to the builtin's out
8982 // argument.
8983
John McCall7f416cc2015-09-08 08:05:57 +00008984 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3));
Matt Arsenault56f008d2014-06-24 20:45:01 +00008985
8986 llvm::Value *X = EmitScalarExpr(E->getArg(0));
8987 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
8988 llvm::Value *Z = EmitScalarExpr(E->getArg(2));
8989
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008990 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale,
Matt Arsenault56f008d2014-06-24 20:45:01 +00008991 X->getType());
8992
David Blaikie43f9bb72015-05-18 22:14:03 +00008993 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z});
Matt Arsenault56f008d2014-06-24 20:45:01 +00008994
8995 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0);
8996 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1);
8997
8998 llvm::Type *RealFlagType
John McCall7f416cc2015-09-08 08:05:57 +00008999 = FlagOutPtr.getPointer()->getType()->getPointerElementType();
Matt Arsenault56f008d2014-06-24 20:45:01 +00009000
9001 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType);
John McCall7f416cc2015-09-08 08:05:57 +00009002 Builder.CreateStore(FlagExt, FlagOutPtr);
Matt Arsenault56f008d2014-06-24 20:45:01 +00009003 return Result;
Matt Arsenault85877112014-07-15 17:23:46 +00009004 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009005 case AMDGPU::BI__builtin_amdgcn_div_fmas:
9006 case AMDGPU::BI__builtin_amdgcn_div_fmasf: {
Matt Arsenault2174a9d2014-10-21 22:21:41 +00009007 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0));
9008 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1));
9009 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2));
9010 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3));
9011
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009012 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas,
Matt Arsenault2174a9d2014-10-21 22:21:41 +00009013 Src0->getType());
9014 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3);
David Blaikie43f9bb72015-05-18 22:14:03 +00009015 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool});
Matt Arsenault2174a9d2014-10-21 22:21:41 +00009016 }
Changpeng Fang03bdd8f2016-08-18 22:04:54 +00009017
9018 case AMDGPU::BI__builtin_amdgcn_ds_swizzle:
9019 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle);
Yaxun Liu4d867992017-03-10 01:30:46 +00009020 case AMDGPU::BI__builtin_amdgcn_mov_dpp: {
9021 llvm::SmallVector<llvm::Value *, 5> Args;
9022 for (unsigned I = 0; I != 5; ++I)
9023 Args.push_back(EmitScalarExpr(E->getArg(I)));
9024 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp,
9025 Args[0]->getType());
9026 return Builder.CreateCall(F, Args);
9027 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009028 case AMDGPU::BI__builtin_amdgcn_div_fixup:
9029 case AMDGPU::BI__builtin_amdgcn_div_fixupf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009030 case AMDGPU::BI__builtin_amdgcn_div_fixuph:
Matt Arsenaultf652cae2016-07-01 17:38:14 +00009031 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009032 case AMDGPU::BI__builtin_amdgcn_trig_preop:
9033 case AMDGPU::BI__builtin_amdgcn_trig_preopf:
9034 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop);
9035 case AMDGPU::BI__builtin_amdgcn_rcp:
9036 case AMDGPU::BI__builtin_amdgcn_rcpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009037 case AMDGPU::BI__builtin_amdgcn_rcph:
Matt Arsenault105e8922016-02-03 17:49:38 +00009038 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009039 case AMDGPU::BI__builtin_amdgcn_rsq:
9040 case AMDGPU::BI__builtin_amdgcn_rsqf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009041 case AMDGPU::BI__builtin_amdgcn_rsqh:
Matt Arsenault105e8922016-02-03 17:49:38 +00009042 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq);
Matt Arsenaultf5c1f472016-02-13 01:03:09 +00009043 case AMDGPU::BI__builtin_amdgcn_rsq_clamp:
9044 case AMDGPU::BI__builtin_amdgcn_rsq_clampf:
9045 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp);
Matt Arsenault9b277b42016-02-13 01:21:09 +00009046 case AMDGPU::BI__builtin_amdgcn_sinf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009047 case AMDGPU::BI__builtin_amdgcn_sinh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00009048 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin);
9049 case AMDGPU::BI__builtin_amdgcn_cosf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009050 case AMDGPU::BI__builtin_amdgcn_cosh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00009051 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos);
9052 case AMDGPU::BI__builtin_amdgcn_log_clampf:
9053 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009054 case AMDGPU::BI__builtin_amdgcn_ldexp:
9055 case AMDGPU::BI__builtin_amdgcn_ldexpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009056 case AMDGPU::BI__builtin_amdgcn_ldexph:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009057 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp);
Matt Arsenault3fb96332016-03-30 22:57:40 +00009058 case AMDGPU::BI__builtin_amdgcn_frexp_mant:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009059 case AMDGPU::BI__builtin_amdgcn_frexp_mantf:
9060 case AMDGPU::BI__builtin_amdgcn_frexp_manth:
Matt Arsenault3fb96332016-03-30 22:57:40 +00009061 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant);
Matt Arsenault3fb96332016-03-30 22:57:40 +00009062 case AMDGPU::BI__builtin_amdgcn_frexp_exp:
Konstantin Zhuravlyov62ae8f62016-11-18 22:31:51 +00009063 case AMDGPU::BI__builtin_amdgcn_frexp_expf: {
9064 Value *Src0 = EmitScalarExpr(E->getArg(0));
9065 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
9066 { Builder.getInt32Ty(), Src0->getType() });
9067 return Builder.CreateCall(F, Src0);
9068 }
9069 case AMDGPU::BI__builtin_amdgcn_frexp_exph: {
9070 Value *Src0 = EmitScalarExpr(E->getArg(0));
9071 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
9072 { Builder.getInt16Ty(), Src0->getType() });
9073 return Builder.CreateCall(F, Src0);
9074 }
Matt Arsenault2d510592016-05-28 00:43:27 +00009075 case AMDGPU::BI__builtin_amdgcn_fract:
9076 case AMDGPU::BI__builtin_amdgcn_fractf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009077 case AMDGPU::BI__builtin_amdgcn_fracth:
Matt Arsenault2d510592016-05-28 00:43:27 +00009078 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract);
Wei Dingea41f352016-07-15 16:43:03 +00009079 case AMDGPU::BI__builtin_amdgcn_lerp:
9080 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp);
Wei Ding91c84502016-08-05 15:38:46 +00009081 case AMDGPU::BI__builtin_amdgcn_uicmp:
9082 case AMDGPU::BI__builtin_amdgcn_uicmpl:
9083 case AMDGPU::BI__builtin_amdgcn_sicmp:
9084 case AMDGPU::BI__builtin_amdgcn_sicmpl:
9085 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp);
9086 case AMDGPU::BI__builtin_amdgcn_fcmp:
9087 case AMDGPU::BI__builtin_amdgcn_fcmpf:
9088 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009089 case AMDGPU::BI__builtin_amdgcn_class:
9090 case AMDGPU::BI__builtin_amdgcn_classf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009091 case AMDGPU::BI__builtin_amdgcn_classh:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009092 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class);
Matt Arsenaulta274b202017-01-31 03:42:07 +00009093 case AMDGPU::BI__builtin_amdgcn_fmed3f:
Matt Arsenaulta0c6dca2017-02-22 20:55:59 +00009094 case AMDGPU::BI__builtin_amdgcn_fmed3h:
Matt Arsenaulta274b202017-01-31 03:42:07 +00009095 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3);
Matt Arsenault64665bc2016-06-28 00:13:17 +00009096 case AMDGPU::BI__builtin_amdgcn_read_exec: {
9097 CallInst *CI = cast<CallInst>(
9098 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec"));
9099 CI->setConvergent();
9100 return CI;
9101 }
Jan Veselyd7e03a52016-07-10 22:38:04 +00009102
9103 // amdgcn workitem
9104 case AMDGPU::BI__builtin_amdgcn_workitem_id_x:
9105 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024);
9106 case AMDGPU::BI__builtin_amdgcn_workitem_id_y:
9107 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024);
9108 case AMDGPU::BI__builtin_amdgcn_workitem_id_z:
9109 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024);
9110
Matt Arsenaultc86671d2016-07-15 21:33:02 +00009111 // r600 intrinsics
9112 case AMDGPU::BI__builtin_r600_recipsqrt_ieee:
9113 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef:
9114 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee);
Jan Veselyd7e03a52016-07-10 22:38:04 +00009115 case AMDGPU::BI__builtin_r600_read_tidig_x:
9116 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024);
9117 case AMDGPU::BI__builtin_r600_read_tidig_y:
9118 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024);
9119 case AMDGPU::BI__builtin_r600_read_tidig_z:
9120 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009121 default:
Matt Arsenault56f008d2014-06-24 20:45:01 +00009122 return nullptr;
9123 }
9124}
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009125
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009126/// Handle a SystemZ function in which the final argument is a pointer
9127/// to an int that receives the post-instruction CC value. At the LLVM level
9128/// this is represented as a function that returns a {result, cc} pair.
9129static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF,
9130 unsigned IntrinsicID,
9131 const CallExpr *E) {
9132 unsigned NumArgs = E->getNumArgs() - 1;
9133 SmallVector<Value *, 8> Args(NumArgs);
9134 for (unsigned I = 0; I < NumArgs; ++I)
9135 Args[I] = CGF.EmitScalarExpr(E->getArg(I));
John McCall7f416cc2015-09-08 08:05:57 +00009136 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs));
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009137 Value *F = CGF.CGM.getIntrinsic(IntrinsicID);
9138 Value *Call = CGF.Builder.CreateCall(F, Args);
9139 Value *CC = CGF.Builder.CreateExtractValue(Call, 1);
9140 CGF.Builder.CreateStore(CC, CCPtr);
9141 return CGF.Builder.CreateExtractValue(Call, 0);
9142}
9143
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009144Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
9145 const CallExpr *E) {
9146 switch (BuiltinID) {
9147 case SystemZ::BI__builtin_tbegin: {
9148 Value *TDB = EmitScalarExpr(E->getArg(0));
9149 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
9150 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin);
David Blaikie43f9bb72015-05-18 22:14:03 +00009151 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009152 }
9153 case SystemZ::BI__builtin_tbegin_nofloat: {
9154 Value *TDB = EmitScalarExpr(E->getArg(0));
9155 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
9156 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat);
David Blaikie43f9bb72015-05-18 22:14:03 +00009157 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009158 }
9159 case SystemZ::BI__builtin_tbeginc: {
9160 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy);
9161 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08);
9162 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc);
David Blaikie43f9bb72015-05-18 22:14:03 +00009163 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009164 }
9165 case SystemZ::BI__builtin_tabort: {
9166 Value *Data = EmitScalarExpr(E->getArg(0));
9167 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort);
9168 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort"));
9169 }
9170 case SystemZ::BI__builtin_non_tx_store: {
9171 Value *Address = EmitScalarExpr(E->getArg(0));
9172 Value *Data = EmitScalarExpr(E->getArg(1));
9173 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg);
David Blaikie43f9bb72015-05-18 22:14:03 +00009174 return Builder.CreateCall(F, {Data, Address});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009175 }
9176
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009177 // Vector builtins. Note that most vector builtins are mapped automatically
9178 // to target-specific LLVM intrinsics. The ones handled specially here can
9179 // be represented via standard LLVM IR, which is preferable to enable common
9180 // LLVM optimizations.
9181
9182 case SystemZ::BI__builtin_s390_vpopctb:
9183 case SystemZ::BI__builtin_s390_vpopcth:
9184 case SystemZ::BI__builtin_s390_vpopctf:
9185 case SystemZ::BI__builtin_s390_vpopctg: {
9186 llvm::Type *ResultType = ConvertType(E->getType());
9187 Value *X = EmitScalarExpr(E->getArg(0));
9188 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
9189 return Builder.CreateCall(F, X);
9190 }
9191
9192 case SystemZ::BI__builtin_s390_vclzb:
9193 case SystemZ::BI__builtin_s390_vclzh:
9194 case SystemZ::BI__builtin_s390_vclzf:
9195 case SystemZ::BI__builtin_s390_vclzg: {
9196 llvm::Type *ResultType = ConvertType(E->getType());
9197 Value *X = EmitScalarExpr(E->getArg(0));
9198 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
9199 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009200 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009201 }
9202
9203 case SystemZ::BI__builtin_s390_vctzb:
9204 case SystemZ::BI__builtin_s390_vctzh:
9205 case SystemZ::BI__builtin_s390_vctzf:
9206 case SystemZ::BI__builtin_s390_vctzg: {
9207 llvm::Type *ResultType = ConvertType(E->getType());
9208 Value *X = EmitScalarExpr(E->getArg(0));
9209 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
9210 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009211 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009212 }
9213
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009214 case SystemZ::BI__builtin_s390_vfsqsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009215 case SystemZ::BI__builtin_s390_vfsqdb: {
9216 llvm::Type *ResultType = ConvertType(E->getType());
9217 Value *X = EmitScalarExpr(E->getArg(0));
9218 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
9219 return Builder.CreateCall(F, X);
9220 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009221 case SystemZ::BI__builtin_s390_vfmasb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009222 case SystemZ::BI__builtin_s390_vfmadb: {
9223 llvm::Type *ResultType = ConvertType(E->getType());
9224 Value *X = EmitScalarExpr(E->getArg(0));
9225 Value *Y = EmitScalarExpr(E->getArg(1));
9226 Value *Z = EmitScalarExpr(E->getArg(2));
9227 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009228 return Builder.CreateCall(F, {X, Y, Z});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009229 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009230 case SystemZ::BI__builtin_s390_vfmssb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009231 case SystemZ::BI__builtin_s390_vfmsdb: {
9232 llvm::Type *ResultType = ConvertType(E->getType());
9233 Value *X = EmitScalarExpr(E->getArg(0));
9234 Value *Y = EmitScalarExpr(E->getArg(1));
9235 Value *Z = EmitScalarExpr(E->getArg(2));
9236 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9237 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009238 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009239 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009240 case SystemZ::BI__builtin_s390_vfnmasb:
9241 case SystemZ::BI__builtin_s390_vfnmadb: {
9242 llvm::Type *ResultType = ConvertType(E->getType());
9243 Value *X = EmitScalarExpr(E->getArg(0));
9244 Value *Y = EmitScalarExpr(E->getArg(1));
9245 Value *Z = EmitScalarExpr(E->getArg(2));
9246 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9247 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9248 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub");
9249 }
9250 case SystemZ::BI__builtin_s390_vfnmssb:
9251 case SystemZ::BI__builtin_s390_vfnmsdb: {
9252 llvm::Type *ResultType = ConvertType(E->getType());
9253 Value *X = EmitScalarExpr(E->getArg(0));
9254 Value *Y = EmitScalarExpr(E->getArg(1));
9255 Value *Z = EmitScalarExpr(E->getArg(2));
9256 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9257 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9258 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub");
9259 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ}));
9260 }
9261 case SystemZ::BI__builtin_s390_vflpsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009262 case SystemZ::BI__builtin_s390_vflpdb: {
9263 llvm::Type *ResultType = ConvertType(E->getType());
9264 Value *X = EmitScalarExpr(E->getArg(0));
9265 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9266 return Builder.CreateCall(F, X);
9267 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009268 case SystemZ::BI__builtin_s390_vflnsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009269 case SystemZ::BI__builtin_s390_vflndb: {
9270 llvm::Type *ResultType = ConvertType(E->getType());
9271 Value *X = EmitScalarExpr(E->getArg(0));
9272 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9273 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9274 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub");
9275 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009276 case SystemZ::BI__builtin_s390_vfisb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009277 case SystemZ::BI__builtin_s390_vfidb: {
9278 llvm::Type *ResultType = ConvertType(E->getType());
9279 Value *X = EmitScalarExpr(E->getArg(0));
9280 // Constant-fold the M4 and M5 mask arguments.
9281 llvm::APSInt M4, M5;
9282 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext());
9283 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext());
9284 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?");
9285 (void)IsConstM4; (void)IsConstM5;
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009286 // Check whether this instance can be represented via a LLVM standard
9287 // intrinsic. We only support some combinations of M4 and M5.
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009288 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9289 switch (M4.getZExtValue()) {
9290 default: break;
9291 case 0: // IEEE-inexact exception allowed
9292 switch (M5.getZExtValue()) {
9293 default: break;
9294 case 0: ID = Intrinsic::rint; break;
9295 }
9296 break;
9297 case 4: // IEEE-inexact exception suppressed
9298 switch (M5.getZExtValue()) {
9299 default: break;
9300 case 0: ID = Intrinsic::nearbyint; break;
9301 case 1: ID = Intrinsic::round; break;
9302 case 5: ID = Intrinsic::trunc; break;
9303 case 6: ID = Intrinsic::ceil; break;
9304 case 7: ID = Intrinsic::floor; break;
9305 }
9306 break;
9307 }
9308 if (ID != Intrinsic::not_intrinsic) {
9309 Function *F = CGM.getIntrinsic(ID, ResultType);
9310 return Builder.CreateCall(F, X);
9311 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009312 switch (BuiltinID) {
9313 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break;
9314 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break;
9315 default: llvm_unreachable("Unknown BuiltinID");
9316 }
9317 Function *F = CGM.getIntrinsic(ID);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009318 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9319 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5);
David Blaikie43f9bb72015-05-18 22:14:03 +00009320 return Builder.CreateCall(F, {X, M4Value, M5Value});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009321 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009322 case SystemZ::BI__builtin_s390_vfmaxsb:
9323 case SystemZ::BI__builtin_s390_vfmaxdb: {
9324 llvm::Type *ResultType = ConvertType(E->getType());
9325 Value *X = EmitScalarExpr(E->getArg(0));
9326 Value *Y = EmitScalarExpr(E->getArg(1));
9327 // Constant-fold the M4 mask argument.
9328 llvm::APSInt M4;
9329 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9330 assert(IsConstM4 && "Constant arg isn't actually constant?");
9331 (void)IsConstM4;
9332 // Check whether this instance can be represented via a LLVM standard
9333 // intrinsic. We only support some values of M4.
9334 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9335 switch (M4.getZExtValue()) {
9336 default: break;
9337 case 4: ID = Intrinsic::maxnum; break;
9338 }
9339 if (ID != Intrinsic::not_intrinsic) {
9340 Function *F = CGM.getIntrinsic(ID, ResultType);
9341 return Builder.CreateCall(F, {X, Y});
9342 }
9343 switch (BuiltinID) {
9344 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break;
9345 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break;
9346 default: llvm_unreachable("Unknown BuiltinID");
9347 }
9348 Function *F = CGM.getIntrinsic(ID);
9349 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9350 return Builder.CreateCall(F, {X, Y, M4Value});
9351 }
9352 case SystemZ::BI__builtin_s390_vfminsb:
9353 case SystemZ::BI__builtin_s390_vfmindb: {
9354 llvm::Type *ResultType = ConvertType(E->getType());
9355 Value *X = EmitScalarExpr(E->getArg(0));
9356 Value *Y = EmitScalarExpr(E->getArg(1));
9357 // Constant-fold the M4 mask argument.
9358 llvm::APSInt M4;
9359 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9360 assert(IsConstM4 && "Constant arg isn't actually constant?");
9361 (void)IsConstM4;
9362 // Check whether this instance can be represented via a LLVM standard
9363 // intrinsic. We only support some values of M4.
9364 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9365 switch (M4.getZExtValue()) {
9366 default: break;
9367 case 4: ID = Intrinsic::minnum; break;
9368 }
9369 if (ID != Intrinsic::not_intrinsic) {
9370 Function *F = CGM.getIntrinsic(ID, ResultType);
9371 return Builder.CreateCall(F, {X, Y});
9372 }
9373 switch (BuiltinID) {
9374 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break;
9375 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break;
9376 default: llvm_unreachable("Unknown BuiltinID");
9377 }
9378 Function *F = CGM.getIntrinsic(ID);
9379 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9380 return Builder.CreateCall(F, {X, Y, M4Value});
9381 }
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009382
9383 // Vector intrisincs that output the post-instruction CC value.
9384
9385#define INTRINSIC_WITH_CC(NAME) \
9386 case SystemZ::BI__builtin_##NAME: \
9387 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E)
9388
9389 INTRINSIC_WITH_CC(s390_vpkshs);
9390 INTRINSIC_WITH_CC(s390_vpksfs);
9391 INTRINSIC_WITH_CC(s390_vpksgs);
9392
9393 INTRINSIC_WITH_CC(s390_vpklshs);
9394 INTRINSIC_WITH_CC(s390_vpklsfs);
9395 INTRINSIC_WITH_CC(s390_vpklsgs);
9396
9397 INTRINSIC_WITH_CC(s390_vceqbs);
9398 INTRINSIC_WITH_CC(s390_vceqhs);
9399 INTRINSIC_WITH_CC(s390_vceqfs);
9400 INTRINSIC_WITH_CC(s390_vceqgs);
9401
9402 INTRINSIC_WITH_CC(s390_vchbs);
9403 INTRINSIC_WITH_CC(s390_vchhs);
9404 INTRINSIC_WITH_CC(s390_vchfs);
9405 INTRINSIC_WITH_CC(s390_vchgs);
9406
9407 INTRINSIC_WITH_CC(s390_vchlbs);
9408 INTRINSIC_WITH_CC(s390_vchlhs);
9409 INTRINSIC_WITH_CC(s390_vchlfs);
9410 INTRINSIC_WITH_CC(s390_vchlgs);
9411
9412 INTRINSIC_WITH_CC(s390_vfaebs);
9413 INTRINSIC_WITH_CC(s390_vfaehs);
9414 INTRINSIC_WITH_CC(s390_vfaefs);
9415
9416 INTRINSIC_WITH_CC(s390_vfaezbs);
9417 INTRINSIC_WITH_CC(s390_vfaezhs);
9418 INTRINSIC_WITH_CC(s390_vfaezfs);
9419
9420 INTRINSIC_WITH_CC(s390_vfeebs);
9421 INTRINSIC_WITH_CC(s390_vfeehs);
9422 INTRINSIC_WITH_CC(s390_vfeefs);
9423
9424 INTRINSIC_WITH_CC(s390_vfeezbs);
9425 INTRINSIC_WITH_CC(s390_vfeezhs);
9426 INTRINSIC_WITH_CC(s390_vfeezfs);
9427
9428 INTRINSIC_WITH_CC(s390_vfenebs);
9429 INTRINSIC_WITH_CC(s390_vfenehs);
9430 INTRINSIC_WITH_CC(s390_vfenefs);
9431
9432 INTRINSIC_WITH_CC(s390_vfenezbs);
9433 INTRINSIC_WITH_CC(s390_vfenezhs);
9434 INTRINSIC_WITH_CC(s390_vfenezfs);
9435
9436 INTRINSIC_WITH_CC(s390_vistrbs);
9437 INTRINSIC_WITH_CC(s390_vistrhs);
9438 INTRINSIC_WITH_CC(s390_vistrfs);
9439
9440 INTRINSIC_WITH_CC(s390_vstrcbs);
9441 INTRINSIC_WITH_CC(s390_vstrchs);
9442 INTRINSIC_WITH_CC(s390_vstrcfs);
9443
9444 INTRINSIC_WITH_CC(s390_vstrczbs);
9445 INTRINSIC_WITH_CC(s390_vstrczhs);
9446 INTRINSIC_WITH_CC(s390_vstrczfs);
9447
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009448 INTRINSIC_WITH_CC(s390_vfcesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009449 INTRINSIC_WITH_CC(s390_vfcedbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009450 INTRINSIC_WITH_CC(s390_vfchsbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009451 INTRINSIC_WITH_CC(s390_vfchdbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009452 INTRINSIC_WITH_CC(s390_vfchesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009453 INTRINSIC_WITH_CC(s390_vfchedbs);
9454
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009455 INTRINSIC_WITH_CC(s390_vftcisb);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009456 INTRINSIC_WITH_CC(s390_vftcidb);
9457
9458#undef INTRINSIC_WITH_CC
9459
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009460 default:
9461 return nullptr;
9462 }
9463}
Artem Belevichd21e5c62015-06-25 18:29:42 +00009464
9465Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
9466 const CallExpr *E) {
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009467 auto MakeLdg = [&](unsigned IntrinsicID) {
9468 Value *Ptr = EmitScalarExpr(E->getArg(0));
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009469 clang::CharUnits Align =
Krzysztof Parzyszek8f248232017-05-18 17:07:11 +00009470 getNaturalPointeeTypeAlignment(E->getArg(0)->getType());
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009471 return Builder.CreateCall(
9472 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9473 Ptr->getType()}),
9474 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())});
9475 };
Artem Belevichfda99052016-09-28 17:47:35 +00009476 auto MakeScopedAtomic = [&](unsigned IntrinsicID) {
9477 Value *Ptr = EmitScalarExpr(E->getArg(0));
9478 return Builder.CreateCall(
9479 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9480 Ptr->getType()}),
9481 {Ptr, EmitScalarExpr(E->getArg(1))});
9482 };
Artem Belevichd21e5c62015-06-25 18:29:42 +00009483 switch (BuiltinID) {
9484 case NVPTX::BI__nvvm_atom_add_gen_i:
9485 case NVPTX::BI__nvvm_atom_add_gen_l:
9486 case NVPTX::BI__nvvm_atom_add_gen_ll:
9487 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E);
9488
9489 case NVPTX::BI__nvvm_atom_sub_gen_i:
9490 case NVPTX::BI__nvvm_atom_sub_gen_l:
9491 case NVPTX::BI__nvvm_atom_sub_gen_ll:
9492 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E);
9493
9494 case NVPTX::BI__nvvm_atom_and_gen_i:
9495 case NVPTX::BI__nvvm_atom_and_gen_l:
9496 case NVPTX::BI__nvvm_atom_and_gen_ll:
9497 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E);
9498
9499 case NVPTX::BI__nvvm_atom_or_gen_i:
9500 case NVPTX::BI__nvvm_atom_or_gen_l:
9501 case NVPTX::BI__nvvm_atom_or_gen_ll:
9502 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E);
9503
9504 case NVPTX::BI__nvvm_atom_xor_gen_i:
9505 case NVPTX::BI__nvvm_atom_xor_gen_l:
9506 case NVPTX::BI__nvvm_atom_xor_gen_ll:
9507 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E);
9508
9509 case NVPTX::BI__nvvm_atom_xchg_gen_i:
9510 case NVPTX::BI__nvvm_atom_xchg_gen_l:
9511 case NVPTX::BI__nvvm_atom_xchg_gen_ll:
9512 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E);
9513
9514 case NVPTX::BI__nvvm_atom_max_gen_i:
9515 case NVPTX::BI__nvvm_atom_max_gen_l:
9516 case NVPTX::BI__nvvm_atom_max_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009517 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E);
9518
Artem Belevichd21e5c62015-06-25 18:29:42 +00009519 case NVPTX::BI__nvvm_atom_max_gen_ui:
9520 case NVPTX::BI__nvvm_atom_max_gen_ul:
9521 case NVPTX::BI__nvvm_atom_max_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009522 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009523
9524 case NVPTX::BI__nvvm_atom_min_gen_i:
9525 case NVPTX::BI__nvvm_atom_min_gen_l:
9526 case NVPTX::BI__nvvm_atom_min_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009527 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E);
9528
Artem Belevichd21e5c62015-06-25 18:29:42 +00009529 case NVPTX::BI__nvvm_atom_min_gen_ui:
9530 case NVPTX::BI__nvvm_atom_min_gen_ul:
9531 case NVPTX::BI__nvvm_atom_min_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009532 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009533
9534 case NVPTX::BI__nvvm_atom_cas_gen_i:
9535 case NVPTX::BI__nvvm_atom_cas_gen_l:
9536 case NVPTX::BI__nvvm_atom_cas_gen_ll:
Jingyue Wuf1eca252015-09-30 21:49:32 +00009537 // __nvvm_atom_cas_gen_* should return the old value rather than the
9538 // success flag.
9539 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009540
9541 case NVPTX::BI__nvvm_atom_add_gen_f: {
9542 Value *Ptr = EmitScalarExpr(E->getArg(0));
9543 Value *Val = EmitScalarExpr(E->getArg(1));
9544 // atomicrmw only deals with integer arguments so we need to use
9545 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that.
9546 Value *FnALAF32 =
9547 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType());
9548 return Builder.CreateCall(FnALAF32, {Ptr, Val});
9549 }
9550
Justin Lebar717d2b02016-03-22 00:09:28 +00009551 case NVPTX::BI__nvvm_atom_inc_gen_ui: {
9552 Value *Ptr = EmitScalarExpr(E->getArg(0));
9553 Value *Val = EmitScalarExpr(E->getArg(1));
9554 Value *FnALI32 =
9555 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType());
9556 return Builder.CreateCall(FnALI32, {Ptr, Val});
9557 }
9558
9559 case NVPTX::BI__nvvm_atom_dec_gen_ui: {
9560 Value *Ptr = EmitScalarExpr(E->getArg(0));
9561 Value *Val = EmitScalarExpr(E->getArg(1));
9562 Value *FnALD32 =
9563 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType());
9564 return Builder.CreateCall(FnALD32, {Ptr, Val});
9565 }
9566
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009567 case NVPTX::BI__nvvm_ldg_c:
9568 case NVPTX::BI__nvvm_ldg_c2:
9569 case NVPTX::BI__nvvm_ldg_c4:
9570 case NVPTX::BI__nvvm_ldg_s:
9571 case NVPTX::BI__nvvm_ldg_s2:
9572 case NVPTX::BI__nvvm_ldg_s4:
9573 case NVPTX::BI__nvvm_ldg_i:
9574 case NVPTX::BI__nvvm_ldg_i2:
9575 case NVPTX::BI__nvvm_ldg_i4:
9576 case NVPTX::BI__nvvm_ldg_l:
9577 case NVPTX::BI__nvvm_ldg_ll:
9578 case NVPTX::BI__nvvm_ldg_ll2:
9579 case NVPTX::BI__nvvm_ldg_uc:
9580 case NVPTX::BI__nvvm_ldg_uc2:
9581 case NVPTX::BI__nvvm_ldg_uc4:
9582 case NVPTX::BI__nvvm_ldg_us:
9583 case NVPTX::BI__nvvm_ldg_us2:
9584 case NVPTX::BI__nvvm_ldg_us4:
9585 case NVPTX::BI__nvvm_ldg_ui:
9586 case NVPTX::BI__nvvm_ldg_ui2:
9587 case NVPTX::BI__nvvm_ldg_ui4:
9588 case NVPTX::BI__nvvm_ldg_ul:
9589 case NVPTX::BI__nvvm_ldg_ull:
9590 case NVPTX::BI__nvvm_ldg_ull2:
9591 // PTX Interoperability section 2.2: "For a vector with an even number of
9592 // elements, its alignment is set to number of elements times the alignment
9593 // of its member: n*alignof(t)."
9594 return MakeLdg(Intrinsic::nvvm_ldg_global_i);
9595 case NVPTX::BI__nvvm_ldg_f:
9596 case NVPTX::BI__nvvm_ldg_f2:
9597 case NVPTX::BI__nvvm_ldg_f4:
9598 case NVPTX::BI__nvvm_ldg_d:
9599 case NVPTX::BI__nvvm_ldg_d2:
9600 return MakeLdg(Intrinsic::nvvm_ldg_global_f);
Artem Belevichfda99052016-09-28 17:47:35 +00009601
9602 case NVPTX::BI__nvvm_atom_cta_add_gen_i:
9603 case NVPTX::BI__nvvm_atom_cta_add_gen_l:
9604 case NVPTX::BI__nvvm_atom_cta_add_gen_ll:
9605 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta);
9606 case NVPTX::BI__nvvm_atom_sys_add_gen_i:
9607 case NVPTX::BI__nvvm_atom_sys_add_gen_l:
9608 case NVPTX::BI__nvvm_atom_sys_add_gen_ll:
9609 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys);
9610 case NVPTX::BI__nvvm_atom_cta_add_gen_f:
9611 case NVPTX::BI__nvvm_atom_cta_add_gen_d:
9612 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta);
9613 case NVPTX::BI__nvvm_atom_sys_add_gen_f:
9614 case NVPTX::BI__nvvm_atom_sys_add_gen_d:
9615 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys);
9616 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i:
9617 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l:
9618 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll:
9619 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta);
9620 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i:
9621 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l:
9622 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll:
9623 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys);
9624 case NVPTX::BI__nvvm_atom_cta_max_gen_i:
9625 case NVPTX::BI__nvvm_atom_cta_max_gen_ui:
9626 case NVPTX::BI__nvvm_atom_cta_max_gen_l:
9627 case NVPTX::BI__nvvm_atom_cta_max_gen_ul:
9628 case NVPTX::BI__nvvm_atom_cta_max_gen_ll:
9629 case NVPTX::BI__nvvm_atom_cta_max_gen_ull:
9630 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta);
9631 case NVPTX::BI__nvvm_atom_sys_max_gen_i:
9632 case NVPTX::BI__nvvm_atom_sys_max_gen_ui:
9633 case NVPTX::BI__nvvm_atom_sys_max_gen_l:
9634 case NVPTX::BI__nvvm_atom_sys_max_gen_ul:
9635 case NVPTX::BI__nvvm_atom_sys_max_gen_ll:
9636 case NVPTX::BI__nvvm_atom_sys_max_gen_ull:
9637 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys);
9638 case NVPTX::BI__nvvm_atom_cta_min_gen_i:
9639 case NVPTX::BI__nvvm_atom_cta_min_gen_ui:
9640 case NVPTX::BI__nvvm_atom_cta_min_gen_l:
9641 case NVPTX::BI__nvvm_atom_cta_min_gen_ul:
9642 case NVPTX::BI__nvvm_atom_cta_min_gen_ll:
9643 case NVPTX::BI__nvvm_atom_cta_min_gen_ull:
9644 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta);
9645 case NVPTX::BI__nvvm_atom_sys_min_gen_i:
9646 case NVPTX::BI__nvvm_atom_sys_min_gen_ui:
9647 case NVPTX::BI__nvvm_atom_sys_min_gen_l:
9648 case NVPTX::BI__nvvm_atom_sys_min_gen_ul:
9649 case NVPTX::BI__nvvm_atom_sys_min_gen_ll:
9650 case NVPTX::BI__nvvm_atom_sys_min_gen_ull:
9651 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys);
9652 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui:
9653 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta);
9654 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui:
9655 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta);
9656 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui:
9657 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys);
9658 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui:
9659 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys);
9660 case NVPTX::BI__nvvm_atom_cta_and_gen_i:
9661 case NVPTX::BI__nvvm_atom_cta_and_gen_l:
9662 case NVPTX::BI__nvvm_atom_cta_and_gen_ll:
9663 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta);
9664 case NVPTX::BI__nvvm_atom_sys_and_gen_i:
9665 case NVPTX::BI__nvvm_atom_sys_and_gen_l:
9666 case NVPTX::BI__nvvm_atom_sys_and_gen_ll:
9667 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys);
9668 case NVPTX::BI__nvvm_atom_cta_or_gen_i:
9669 case NVPTX::BI__nvvm_atom_cta_or_gen_l:
9670 case NVPTX::BI__nvvm_atom_cta_or_gen_ll:
9671 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta);
9672 case NVPTX::BI__nvvm_atom_sys_or_gen_i:
9673 case NVPTX::BI__nvvm_atom_sys_or_gen_l:
9674 case NVPTX::BI__nvvm_atom_sys_or_gen_ll:
9675 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys);
9676 case NVPTX::BI__nvvm_atom_cta_xor_gen_i:
9677 case NVPTX::BI__nvvm_atom_cta_xor_gen_l:
9678 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll:
9679 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta);
9680 case NVPTX::BI__nvvm_atom_sys_xor_gen_i:
9681 case NVPTX::BI__nvvm_atom_sys_xor_gen_l:
9682 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll:
9683 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys);
9684 case NVPTX::BI__nvvm_atom_cta_cas_gen_i:
9685 case NVPTX::BI__nvvm_atom_cta_cas_gen_l:
9686 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: {
9687 Value *Ptr = EmitScalarExpr(E->getArg(0));
9688 return Builder.CreateCall(
9689 CGM.getIntrinsic(
9690 Intrinsic::nvvm_atomic_cas_gen_i_cta,
9691 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9692 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9693 }
9694 case NVPTX::BI__nvvm_atom_sys_cas_gen_i:
9695 case NVPTX::BI__nvvm_atom_sys_cas_gen_l:
9696 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: {
9697 Value *Ptr = EmitScalarExpr(E->getArg(0));
9698 return Builder.CreateCall(
9699 CGM.getIntrinsic(
9700 Intrinsic::nvvm_atomic_cas_gen_i_sys,
9701 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9702 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9703 }
Artem Belevichbab95c72017-09-26 17:07:23 +00009704 case NVPTX::BI__nvvm_match_all_sync_i32p:
9705 case NVPTX::BI__nvvm_match_all_sync_i64p: {
9706 Value *Mask = EmitScalarExpr(E->getArg(0));
9707 Value *Val = EmitScalarExpr(E->getArg(1));
9708 Address PredOutPtr = EmitPointerWithAlignment(E->getArg(2));
9709 Value *ResultPair = Builder.CreateCall(
9710 CGM.getIntrinsic(BuiltinID == NVPTX::BI__nvvm_match_all_sync_i32p
9711 ? Intrinsic::nvvm_match_all_sync_i32p
9712 : Intrinsic::nvvm_match_all_sync_i64p),
9713 {Mask, Val});
9714 Value *Pred = Builder.CreateZExt(Builder.CreateExtractValue(ResultPair, 1),
9715 PredOutPtr.getElementType());
9716 Builder.CreateStore(Pred, PredOutPtr);
9717 return Builder.CreateExtractValue(ResultPair, 0);
9718 }
Artem Belevichd21e5c62015-06-25 18:29:42 +00009719 default:
9720 return nullptr;
9721 }
9722}
Dan Gohmanc2853072015-09-03 22:51:53 +00009723
9724Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
9725 const CallExpr *E) {
9726 switch (BuiltinID) {
Derek Schuffdbd24b42016-05-02 17:26:19 +00009727 case WebAssembly::BI__builtin_wasm_current_memory: {
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009728 llvm::Type *ResultType = ConvertType(E->getType());
Derek Schuffdbd24b42016-05-02 17:26:19 +00009729 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType);
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009730 return Builder.CreateCall(Callee);
9731 }
Dan Gohman24f0a082015-11-05 20:16:37 +00009732 case WebAssembly::BI__builtin_wasm_grow_memory: {
Dan Gohman266b38a2015-10-02 20:20:01 +00009733 Value *X = EmitScalarExpr(E->getArg(0));
Dan Gohman24f0a082015-11-05 20:16:37 +00009734 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType());
Dan Gohman266b38a2015-10-02 20:20:01 +00009735 return Builder.CreateCall(Callee, X);
9736 }
Heejin Ahnb92440e2017-06-30 00:44:01 +00009737 case WebAssembly::BI__builtin_wasm_throw: {
9738 Value *Tag = EmitScalarExpr(E->getArg(0));
9739 Value *Obj = EmitScalarExpr(E->getArg(1));
9740 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
9741 return Builder.CreateCall(Callee, {Tag, Obj});
9742 }
Heejin Ahnb29a17b2017-09-16 01:07:43 +00009743 case WebAssembly::BI__builtin_wasm_rethrow: {
9744 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow);
9745 return Builder.CreateCall(Callee);
9746 }
Dan Gohmanc2853072015-09-03 22:51:53 +00009747
9748 default:
9749 return nullptr;
9750 }
9751}