blob: f80b259f834cd133e1f7601453365de69f0b249b [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
Mike Stump11289f42009-09-09 15:08:12 +0000666RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Peter Collingbournef7706832014-12-12 23:41:25 +0000667 unsigned BuiltinID, const CallExpr *E,
668 ReturnValueSlot ReturnValue) {
Chris Lattner24355b52008-10-06 06:56:41 +0000669 // See if we can constant fold this builtin. If so, don't emit it at all.
Anders Carlssonc9687902008-12-01 02:31:41 +0000670 Expr::EvalResult Result;
Eli Friedmandf88c542012-01-06 20:03:09 +0000671 if (E->EvaluateAsRValue(Result, CGM.getContext()) &&
Fariborz Jahanian24ac1592011-04-25 23:10:07 +0000672 !Result.hasSideEffects()) {
Anders Carlssonc9687902008-12-01 02:31:41 +0000673 if (Result.Val.isInt())
John McCallad7c5c12011-02-08 08:22:06 +0000674 return RValue::get(llvm::ConstantInt::get(getLLVMContext(),
Owen Andersonb7a2fe62009-07-24 23:12:58 +0000675 Result.Val.getInt()));
Chris Lattner07e96862010-10-01 23:43:16 +0000676 if (Result.Val.isFloat())
John McCallad7c5c12011-02-08 08:22:06 +0000677 return RValue::get(llvm::ConstantFP::get(getLLVMContext(),
678 Result.Val.getFloat()));
Chris Lattnera1518b12008-10-06 06:09:18 +0000679 }
Mike Stump11289f42009-09-09 15:08:12 +0000680
Chris Lattner24355b52008-10-06 06:56:41 +0000681 switch (BuiltinID) {
682 default: break; // Handle intrinsics and libm functions below.
Chris Lattnera97132a2008-10-06 07:26:43 +0000683 case Builtin::BI__builtin___CFStringMakeConstantString:
David Chisnall481e3a82010-01-23 02:40:42 +0000684 case Builtin::BI__builtin___NSStringMakeConstantString:
John McCallde0fe072017-08-15 21:42:52 +0000685 return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType()));
Chris Lattner0bf67912008-07-09 17:28:44 +0000686 case Builtin::BI__builtin_stdarg_start:
Anders Carlsson24ebce62007-10-12 23:56:29 +0000687 case Builtin::BI__builtin_va_start:
Reid Kleckner597e81d2014-03-26 15:38:33 +0000688 case Builtin::BI__va_start:
Charles Davisc7d5c942015-09-17 20:55:33 +0000689 case Builtin::BI__builtin_va_end:
690 return RValue::get(
691 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start
692 ? EmitScalarExpr(E->getArg(0))
693 : EmitVAListRef(E->getArg(0)).getPointer(),
694 BuiltinID != Builtin::BI__builtin_va_end));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000695 case Builtin::BI__builtin_va_copy: {
John McCall7f416cc2015-09-08 08:05:57 +0000696 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer();
697 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer();
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000698
Chris Lattner2192fe52011-07-18 04:24:23 +0000699 llvm::Type *Type = Int8PtrTy;
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000700
701 DstPtr = Builder.CreateBitCast(DstPtr, Type);
702 SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
David Blaikie43f9bb72015-05-18 22:14:03 +0000703 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy),
704 {DstPtr, SrcPtr}));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000705 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000706 case Builtin::BI__builtin_abs:
Eli Friedman65499b42012-01-17 22:11:30 +0000707 case Builtin::BI__builtin_labs:
708 case Builtin::BI__builtin_llabs: {
Mike Stump11289f42009-09-09 15:08:12 +0000709 Value *ArgValue = EmitScalarExpr(E->getArg(0));
710
Chris Lattner28ee5b32008-07-23 06:53:34 +0000711 Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
Mike Stump11289f42009-09-09 15:08:12 +0000712 Value *CmpResult =
713 Builder.CreateICmpSGE(ArgValue,
Owen Anderson0b75f232009-07-31 20:28:54 +0000714 llvm::Constant::getNullValue(ArgValue->getType()),
Chris Lattner28ee5b32008-07-23 06:53:34 +0000715 "abscond");
Mike Stump11289f42009-09-09 15:08:12 +0000716 Value *Result =
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000717 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
Mike Stump11289f42009-09-09 15:08:12 +0000718
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000719 return RValue::get(Result);
720 }
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000721 case Builtin::BI__builtin_fabs:
722 case Builtin::BI__builtin_fabsf:
723 case Builtin::BI__builtin_fabsl: {
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000724 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs));
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000725 }
Jan Veselyb4379f92014-09-26 01:19:41 +0000726 case Builtin::BI__builtin_fmod:
727 case Builtin::BI__builtin_fmodf:
728 case Builtin::BI__builtin_fmodl: {
729 Value *Arg1 = EmitScalarExpr(E->getArg(0));
730 Value *Arg2 = EmitScalarExpr(E->getArg(1));
731 Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod");
732 return RValue::get(Result);
733 }
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000734 case Builtin::BI__builtin_copysign:
735 case Builtin::BI__builtin_copysignf:
736 case Builtin::BI__builtin_copysignl: {
737 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign));
738 }
739 case Builtin::BI__builtin_ceil:
740 case Builtin::BI__builtin_ceilf:
741 case Builtin::BI__builtin_ceill: {
742 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil));
743 }
744 case Builtin::BI__builtin_floor:
745 case Builtin::BI__builtin_floorf:
746 case Builtin::BI__builtin_floorl: {
747 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor));
748 }
749 case Builtin::BI__builtin_trunc:
750 case Builtin::BI__builtin_truncf:
751 case Builtin::BI__builtin_truncl: {
752 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc));
753 }
754 case Builtin::BI__builtin_rint:
755 case Builtin::BI__builtin_rintf:
756 case Builtin::BI__builtin_rintl: {
757 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint));
758 }
759 case Builtin::BI__builtin_nearbyint:
760 case Builtin::BI__builtin_nearbyintf:
761 case Builtin::BI__builtin_nearbyintl: {
762 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint));
763 }
764 case Builtin::BI__builtin_round:
765 case Builtin::BI__builtin_roundf:
766 case Builtin::BI__builtin_roundl: {
767 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round));
768 }
769 case Builtin::BI__builtin_fmin:
770 case Builtin::BI__builtin_fminf:
771 case Builtin::BI__builtin_fminl: {
772 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum));
773 }
774 case Builtin::BI__builtin_fmax:
775 case Builtin::BI__builtin_fmaxf:
776 case Builtin::BI__builtin_fmaxl: {
777 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum));
778 }
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000779 case Builtin::BI__builtin_conj:
780 case Builtin::BI__builtin_conjf:
781 case Builtin::BI__builtin_conjl: {
782 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
783 Value *Real = ComplexVal.first;
784 Value *Imag = ComplexVal.second;
Jim Grosbachd3608f42012-09-21 00:18:27 +0000785 Value *Zero =
786 Imag->getType()->isFPOrFPVectorTy()
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000787 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType())
788 : llvm::Constant::getNullValue(Imag->getType());
Jim Grosbachd3608f42012-09-21 00:18:27 +0000789
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000790 Imag = Builder.CreateFSub(Zero, Imag, "sub");
791 return RValue::getComplex(std::make_pair(Real, Imag));
792 }
793 case Builtin::BI__builtin_creal:
794 case Builtin::BI__builtin_crealf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000795 case Builtin::BI__builtin_creall:
796 case Builtin::BIcreal:
797 case Builtin::BIcrealf:
798 case Builtin::BIcreall: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000799 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
800 return RValue::get(ComplexVal.first);
801 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000802
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000803 case Builtin::BI__builtin_cimag:
804 case Builtin::BI__builtin_cimagf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000805 case Builtin::BI__builtin_cimagl:
806 case Builtin::BIcimag:
807 case Builtin::BIcimagf:
808 case Builtin::BIcimagl: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000809 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
810 return RValue::get(ComplexVal.second);
811 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000812
Benjamin Kramer14128162012-01-28 18:42:57 +0000813 case Builtin::BI__builtin_ctzs:
Anders Carlsson093f1a02008-02-06 07:19:27 +0000814 case Builtin::BI__builtin_ctz:
815 case Builtin::BI__builtin_ctzl:
816 case Builtin::BI__builtin_ctzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +0000817 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +0000818
Chris Lattnera5f58b02011-07-09 17:41:47 +0000819 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000820 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Anders Carlsson093f1a02008-02-06 07:19:27 +0000821
Chris Lattner2192fe52011-07-18 04:24:23 +0000822 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +0000823 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +0000824 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Anders Carlsson093f1a02008-02-06 07:19:27 +0000825 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000826 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
827 "cast");
Anders Carlsson093f1a02008-02-06 07:19:27 +0000828 return RValue::get(Result);
829 }
Benjamin Kramer14128162012-01-28 18:42:57 +0000830 case Builtin::BI__builtin_clzs:
Eli Friedman5e2281e2008-05-27 15:32:46 +0000831 case Builtin::BI__builtin_clz:
832 case Builtin::BI__builtin_clzl:
833 case Builtin::BI__builtin_clzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +0000834 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +0000835
Chris Lattnera5f58b02011-07-09 17:41:47 +0000836 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000837 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
Eli Friedman5e2281e2008-05-27 15:32:46 +0000838
Chris Lattner2192fe52011-07-18 04:24:23 +0000839 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +0000840 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +0000841 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Eli Friedman5e2281e2008-05-27 15:32:46 +0000842 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000843 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
844 "cast");
Eli Friedman5e2281e2008-05-27 15:32:46 +0000845 return RValue::get(Result);
846 }
Daniel Dunbard93abc32008-07-21 17:19:41 +0000847 case Builtin::BI__builtin_ffs:
848 case Builtin::BI__builtin_ffsl:
849 case Builtin::BI__builtin_ffsll: {
850 // ffs(x) -> x ? cttz(x) + 1 : 0
851 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +0000852
Chris Lattnera5f58b02011-07-09 17:41:47 +0000853 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000854 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +0000855
Chris Lattner2192fe52011-07-18 04:24:23 +0000856 llvm::Type *ResultType = ConvertType(E->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +0000857 Value *Tmp =
858 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}),
859 llvm::ConstantInt::get(ArgType, 1));
Owen Anderson0b75f232009-07-31 20:28:54 +0000860 Value *Zero = llvm::Constant::getNullValue(ArgType);
Daniel Dunbard93abc32008-07-21 17:19:41 +0000861 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
862 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs");
863 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000864 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
865 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +0000866 return RValue::get(Result);
867 }
868 case Builtin::BI__builtin_parity:
869 case Builtin::BI__builtin_parityl:
870 case Builtin::BI__builtin_parityll: {
871 // parity(x) -> ctpop(x) & 1
872 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +0000873
Chris Lattnera5f58b02011-07-09 17:41:47 +0000874 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000875 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +0000876
Chris Lattner2192fe52011-07-18 04:24:23 +0000877 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +0000878 Value *Tmp = Builder.CreateCall(F, ArgValue);
879 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1));
Daniel Dunbard93abc32008-07-21 17:19:41 +0000880 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000881 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
882 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +0000883 return RValue::get(Result);
884 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +0000885 case Builtin::BI__popcnt16:
886 case Builtin::BI__popcnt:
887 case Builtin::BI__popcnt64:
Daniel Dunbard93abc32008-07-21 17:19:41 +0000888 case Builtin::BI__builtin_popcount:
889 case Builtin::BI__builtin_popcountl:
890 case Builtin::BI__builtin_popcountll: {
891 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +0000892
Chris Lattnera5f58b02011-07-09 17:41:47 +0000893 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000894 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +0000895
Chris Lattner2192fe52011-07-18 04:24:23 +0000896 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +0000897 Value *Result = Builder.CreateCall(F, ArgValue);
Daniel Dunbard93abc32008-07-21 17:19:41 +0000898 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000899 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
900 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +0000901 return RValue::get(Result);
902 }
Albert Gutowskib6a11ac2016-09-08 22:32:19 +0000903 case Builtin::BI_rotr8:
904 case Builtin::BI_rotr16:
905 case Builtin::BI_rotr:
906 case Builtin::BI_lrotr:
907 case Builtin::BI_rotr64: {
908 Value *Val = EmitScalarExpr(E->getArg(0));
909 Value *Shift = EmitScalarExpr(E->getArg(1));
910
911 llvm::Type *ArgType = Val->getType();
912 Shift = Builder.CreateIntCast(Shift, ArgType, false);
913 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
914 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
915 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
916
917 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
918 Shift = Builder.CreateAnd(Shift, Mask);
919 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift);
920
921 Value *RightShifted = Builder.CreateLShr(Val, Shift);
922 Value *LeftShifted = Builder.CreateShl(Val, LeftShift);
923 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
924
925 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
926 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
927 return RValue::get(Result);
928 }
929 case Builtin::BI_rotl8:
930 case Builtin::BI_rotl16:
931 case Builtin::BI_rotl:
932 case Builtin::BI_lrotl:
933 case Builtin::BI_rotl64: {
934 Value *Val = EmitScalarExpr(E->getArg(0));
935 Value *Shift = EmitScalarExpr(E->getArg(1));
936
937 llvm::Type *ArgType = Val->getType();
938 Shift = Builder.CreateIntCast(Shift, ArgType, false);
939 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
940 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
941 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
942
943 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
944 Shift = Builder.CreateAnd(Shift, Mask);
945 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift);
946
947 Value *LeftShifted = Builder.CreateShl(Val, Shift);
948 Value *RightShifted = Builder.CreateLShr(Val, RightShift);
949 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
950
951 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
952 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
953 return RValue::get(Result);
954 }
Sanjay Patela24296b2015-09-02 20:01:30 +0000955 case Builtin::BI__builtin_unpredictable: {
956 // Always return the argument of __builtin_unpredictable. LLVM does not
957 // handle this builtin. Metadata for this builtin should be added directly
958 // to instructions such as branches or switches that use it.
959 return RValue::get(EmitScalarExpr(E->getArg(0)));
960 }
Fariborz Jahanian0ebca282010-07-26 23:11:03 +0000961 case Builtin::BI__builtin_expect: {
Fariborz Jahanian24ac1592011-04-25 23:10:07 +0000962 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000963 llvm::Type *ArgType = ArgValue->getType();
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000964
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000965 Value *ExpectedValue = EmitScalarExpr(E->getArg(1));
Pete Cooperf051cbf2015-01-26 20:51:58 +0000966 // Don't generate llvm.expect on -O0 as the backend won't use it for
967 // anything.
968 // Note, we still IRGen ExpectedValue because it could have side-effects.
969 if (CGM.getCodeGenOpts().OptimizationLevel == 0)
970 return RValue::get(ArgValue);
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000971
Pete Cooperf051cbf2015-01-26 20:51:58 +0000972 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +0000973 Value *Result =
974 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval");
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000975 return RValue::get(Result);
Fariborz Jahanian0ebca282010-07-26 23:11:03 +0000976 }
Hal Finkelbcc06082014-09-07 22:58:14 +0000977 case Builtin::BI__builtin_assume_aligned: {
978 Value *PtrValue = EmitScalarExpr(E->getArg(0));
979 Value *OffsetValue =
980 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
981
982 Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
983 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
984 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();
985
986 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);
987 return RValue::get(PtrValue);
988 }
989 case Builtin::BI__assume:
990 case Builtin::BI__builtin_assume: {
991 if (E->getArg(0)->HasSideEffects(getContext()))
992 return RValue::get(nullptr);
993
994 Value *ArgValue = EmitScalarExpr(E->getArg(0));
995 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
996 return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
997 }
Benjamin Kramera801f4a2012-10-06 14:42:22 +0000998 case Builtin::BI__builtin_bswap16:
Anders Carlssonef93b9d2007-12-02 21:58:10 +0000999 case Builtin::BI__builtin_bswap32:
1000 case Builtin::BI__builtin_bswap64: {
Matt Arsenault105e8922016-02-03 17:49:38 +00001001 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap));
1002 }
Matt Arsenault08087c52016-03-23 22:14:43 +00001003 case Builtin::BI__builtin_bitreverse8:
Matt Arsenault105e8922016-02-03 17:49:38 +00001004 case Builtin::BI__builtin_bitreverse16:
1005 case Builtin::BI__builtin_bitreverse32:
1006 case Builtin::BI__builtin_bitreverse64: {
1007 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse));
Mike Stump11289f42009-09-09 15:08:12 +00001008 }
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001009 case Builtin::BI__builtin_object_size: {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001010 unsigned Type =
1011 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
1012 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType()));
Richard Smith01ade172012-05-23 04:13:20 +00001013
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001014 // We pass this builtin onto the optimizer so that it can figure out the
1015 // object size in more complex cases.
George Burgess IV0d6592a2017-02-23 05:59:56 +00001016 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType,
1017 /*EmittedE=*/nullptr));
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001018 }
Daniel Dunbarb7257262008-07-21 22:59:13 +00001019 case Builtin::BI__builtin_prefetch: {
1020 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
1021 // FIXME: Technically these constants should of type 'int', yes?
Mike Stump11289f42009-09-09 15:08:12 +00001022 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001023 llvm::ConstantInt::get(Int32Ty, 0);
Mike Stump11289f42009-09-09 15:08:12 +00001024 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001025 llvm::ConstantInt::get(Int32Ty, 3);
Bruno Cardoso Lopes3b0297a2011-06-14 05:00:30 +00001026 Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001027 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00001028 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data}));
Anders Carlssonef93b9d2007-12-02 21:58:10 +00001029 }
Hal Finkel3fadbb52012-08-05 22:03:08 +00001030 case Builtin::BI__builtin_readcyclecounter: {
1031 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
David Blaikie4ba525b2015-07-14 17:27:39 +00001032 return RValue::get(Builder.CreateCall(F));
Hal Finkel3fadbb52012-08-05 22:03:08 +00001033 }
Renato Golinc491a8d2014-03-26 15:36:05 +00001034 case Builtin::BI__builtin___clear_cache: {
1035 Value *Begin = EmitScalarExpr(E->getArg(0));
1036 Value *End = EmitScalarExpr(E->getArg(1));
1037 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache);
David Blaikie43f9bb72015-05-18 22:14:03 +00001038 return RValue::get(Builder.CreateCall(F, {Begin, End}));
Renato Golinc491a8d2014-03-26 15:36:05 +00001039 }
Akira Hatanaka85365cd2015-07-02 22:15:41 +00001040 case Builtin::BI__builtin_trap:
1041 return RValue::get(EmitTrapCall(Intrinsic::trap));
1042 case Builtin::BI__debugbreak:
1043 return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
Chris Lattnerbf206382009-09-21 03:09:59 +00001044 case Builtin::BI__builtin_unreachable: {
Alexey Samsonovedf99a92014-11-07 22:29:38 +00001045 if (SanOpts.has(SanitizerKind::Unreachable)) {
Alexey Samsonov24cad992014-07-17 18:46:27 +00001046 SanitizerScope SanScope(this);
Alexey Samsonove396bfc2014-11-11 22:03:54 +00001047 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
1048 SanitizerKind::Unreachable),
Filipe Cabecinhas322ecd92016-12-12 16:18:40 +00001049 SanitizerHandler::BuiltinUnreachable,
1050 EmitCheckSourceLocation(E->getExprLoc()), None);
Alexey Samsonov24cad992014-07-17 18:46:27 +00001051 } else
John McCall20f6ab82011-01-12 03:41:02 +00001052 Builder.CreateUnreachable();
1053
1054 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001055 EmitBlock(createBasicBlock("unreachable.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001056
Craig Topper8a13c412014-05-21 05:09:00 +00001057 return RValue::get(nullptr);
Chris Lattnerbf206382009-09-21 03:09:59 +00001058 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001059
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001060 case Builtin::BI__builtin_powi:
1061 case Builtin::BI__builtin_powif:
Reid Kleckner1fcccdd2015-02-05 00:24:57 +00001062 case Builtin::BI__builtin_powil: {
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001063 Value *Base = EmitScalarExpr(E->getArg(0));
1064 Value *Exponent = EmitScalarExpr(E->getArg(1));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001065 llvm::Type *ArgType = Base->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001066 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001067 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001068 }
1069
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001070 case Builtin::BI__builtin_isgreater:
1071 case Builtin::BI__builtin_isgreaterequal:
1072 case Builtin::BI__builtin_isless:
1073 case Builtin::BI__builtin_islessequal:
1074 case Builtin::BI__builtin_islessgreater:
1075 case Builtin::BI__builtin_isunordered: {
1076 // Ordered comparisons: we know the arguments to these are matching scalar
1077 // floating point values.
Mike Stump11289f42009-09-09 15:08:12 +00001078 Value *LHS = EmitScalarExpr(E->getArg(0));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001079 Value *RHS = EmitScalarExpr(E->getArg(1));
Mike Stump11289f42009-09-09 15:08:12 +00001080
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001081 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00001082 default: llvm_unreachable("Unknown ordered comparison");
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001083 case Builtin::BI__builtin_isgreater:
1084 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
1085 break;
1086 case Builtin::BI__builtin_isgreaterequal:
1087 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
1088 break;
1089 case Builtin::BI__builtin_isless:
1090 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
1091 break;
1092 case Builtin::BI__builtin_islessequal:
1093 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
1094 break;
1095 case Builtin::BI__builtin_islessgreater:
1096 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
1097 break;
Mike Stump11289f42009-09-09 15:08:12 +00001098 case Builtin::BI__builtin_isunordered:
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001099 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
1100 break;
1101 }
1102 // ZExt bool to int type.
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001103 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType())));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001104 }
Eli Friedman1c277d02009-09-01 04:19:44 +00001105 case Builtin::BI__builtin_isnan: {
1106 Value *V = EmitScalarExpr(E->getArg(0));
1107 V = Builder.CreateFCmpUNO(V, V, "cmp");
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001108 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
Eli Friedman1c277d02009-09-01 04:19:44 +00001109 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001110
Dehao Chen5d4f0be2016-09-14 17:34:14 +00001111 case Builtin::BIfinite:
1112 case Builtin::BI__finite:
1113 case Builtin::BIfinitef:
1114 case Builtin::BI__finitef:
1115 case Builtin::BIfinitel:
1116 case Builtin::BI__finitel:
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001117 case Builtin::BI__builtin_isinf:
1118 case Builtin::BI__builtin_isfinite: {
1119 // isinf(x) --> fabs(x) == infinity
1120 // isfinite(x) --> fabs(x) != infinity
1121 // x != NaN via the ordered compare in either case.
Chris Lattner43660c52010-05-06 05:35:16 +00001122 Value *V = EmitScalarExpr(E->getArg(0));
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001123 Value *Fabs = EmitFAbs(*this, V);
1124 Constant *Infinity = ConstantFP::getInfinity(V->getType());
1125 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf)
1126 ? CmpInst::FCMP_OEQ
1127 : CmpInst::FCMP_ONE;
1128 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf");
1129 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType())));
Chris Lattner43660c52010-05-06 05:35:16 +00001130 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001131
Chandler Carruthc66deaf2015-03-19 22:39:51 +00001132 case Builtin::BI__builtin_isinf_sign: {
1133 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0
1134 Value *Arg = EmitScalarExpr(E->getArg(0));
1135 Value *AbsArg = EmitFAbs(*this, Arg);
1136 Value *IsInf = Builder.CreateFCmpOEQ(
1137 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf");
1138 Value *IsNeg = EmitSignBit(*this, Arg);
1139
1140 llvm::Type *IntTy = ConvertType(E->getType());
1141 Value *Zero = Constant::getNullValue(IntTy);
1142 Value *One = ConstantInt::get(IntTy, 1);
1143 Value *NegativeOne = ConstantInt::get(IntTy, -1);
1144 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One);
1145 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero);
1146 return RValue::get(Result);
1147 }
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001148
1149 case Builtin::BI__builtin_isnormal: {
1150 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min
1151 Value *V = EmitScalarExpr(E->getArg(0));
1152 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
1153
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001154 Value *Abs = EmitFAbs(*this, V);
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001155 Value *IsLessThanInf =
1156 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf");
1157 APFloat Smallest = APFloat::getSmallestNormalized(
1158 getContext().getFloatTypeSemantics(E->getArg(0)->getType()));
1159 Value *IsNormal =
1160 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest),
1161 "isnormal");
1162 V = Builder.CreateAnd(Eq, IsLessThanInf, "and");
1163 V = Builder.CreateAnd(V, IsNormal, "and");
1164 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
1165 }
1166
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001167 case Builtin::BI__builtin_fpclassify: {
1168 Value *V = EmitScalarExpr(E->getArg(5));
Chris Lattner2192fe52011-07-18 04:24:23 +00001169 llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001170
1171 // Create Result
1172 BasicBlock *Begin = Builder.GetInsertBlock();
1173 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn);
1174 Builder.SetInsertPoint(End);
1175 PHINode *Result =
Jay Foad20c0f022011-03-30 11:28:58 +00001176 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4,
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001177 "fpclassify_result");
1178
1179 // if (V==0) return FP_ZERO
1180 Builder.SetInsertPoint(Begin);
1181 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty),
1182 "iszero");
1183 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4));
1184 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn);
1185 Builder.CreateCondBr(IsZero, End, NotZero);
1186 Result->addIncoming(ZeroLiteral, Begin);
1187
1188 // if (V != V) return FP_NAN
1189 Builder.SetInsertPoint(NotZero);
1190 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp");
1191 Value *NanLiteral = EmitScalarExpr(E->getArg(0));
1192 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn);
1193 Builder.CreateCondBr(IsNan, End, NotNan);
1194 Result->addIncoming(NanLiteral, NotZero);
1195
1196 // if (fabs(V) == infinity) return FP_INFINITY
1197 Builder.SetInsertPoint(NotNan);
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001198 Value *VAbs = EmitFAbs(*this, V);
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001199 Value *IsInf =
1200 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()),
1201 "isinf");
1202 Value *InfLiteral = EmitScalarExpr(E->getArg(1));
1203 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn);
1204 Builder.CreateCondBr(IsInf, End, NotInf);
1205 Result->addIncoming(InfLiteral, NotNan);
1206
1207 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL
1208 Builder.SetInsertPoint(NotInf);
1209 APFloat Smallest = APFloat::getSmallestNormalized(
1210 getContext().getFloatTypeSemantics(E->getArg(5)->getType()));
1211 Value *IsNormal =
1212 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest),
1213 "isnormal");
1214 Value *NormalResult =
1215 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)),
1216 EmitScalarExpr(E->getArg(3)));
1217 Builder.CreateBr(End);
1218 Result->addIncoming(NormalResult, NotInf);
1219
1220 // return Result
1221 Builder.SetInsertPoint(End);
1222 return RValue::get(Result);
1223 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001224
Eli Friedmanf6bd1502009-06-02 07:10:30 +00001225 case Builtin::BIalloca:
Reid Kleckner59e4a6f2013-11-13 22:58:53 +00001226 case Builtin::BI_alloca:
Chris Lattner22b9ff42008-06-16 17:15:14 +00001227 case Builtin::BI__builtin_alloca: {
Chris Lattner22b9ff42008-06-16 17:15:14 +00001228 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemer1878da42016-10-27 17:18:24 +00001229 const TargetInfo &TI = getContext().getTargetInfo();
1230 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
1231 unsigned SuitableAlignmentInBytes =
David Majnemerbb103d92016-10-31 16:48:30 +00001232 CGM.getContext()
1233 .toCharUnitsFromBits(TI.getSuitableAlign())
1234 .getQuantity();
David Majnemer1878da42016-10-27 17:18:24 +00001235 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1236 AI->setAlignment(SuitableAlignmentInBytes);
1237 return RValue::get(AI);
Daniel Dunbar327acd72008-07-22 00:26:45 +00001238 }
David Majnemer51169932016-10-31 05:37:48 +00001239
1240 case Builtin::BI__builtin_alloca_with_align: {
1241 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemerbb103d92016-10-31 16:48:30 +00001242 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1));
1243 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue);
1244 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue();
1245 unsigned AlignmentInBytes =
1246 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity();
David Majnemer51169932016-10-31 05:37:48 +00001247 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1248 AI->setAlignment(AlignmentInBytes);
1249 return RValue::get(AI);
1250 }
1251
Eli Friedmand6ef69a2010-01-23 19:00:10 +00001252 case Builtin::BIbzero:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001253 case Builtin::BI__builtin_bzero: {
John McCall7f416cc2015-09-08 08:05:57 +00001254 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001255 Value *SizeVal = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00001256 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001257 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001258 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false);
1259 return RValue::get(Dest.getPointer());
Chris Lattner22b9ff42008-06-16 17:15:14 +00001260 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001261 case Builtin::BImemcpy:
Eli Friedmana3a40682008-05-19 23:27:48 +00001262 case Builtin::BI__builtin_memcpy: {
John McCall7f416cc2015-09-08 08:05:57 +00001263 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1264 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001265 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001266 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001267 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001268 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001269 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001270 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1271 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001272 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001273
Richard Smith5e29dd32017-01-20 00:45:35 +00001274 case Builtin::BI__builtin_char_memchr:
1275 BuiltinID = Builtin::BI__builtin_memchr;
1276 break;
1277
Chris Lattner30107ed2011-04-17 00:40:24 +00001278 case Builtin::BI__builtin___memcpy_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001279 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001280 llvm::APSInt Size, DstSize;
1281 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1282 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001283 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001284 if (Size.ugt(DstSize))
1285 break;
John McCall7f416cc2015-09-08 08:05:57 +00001286 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1287 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001288 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001289 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1290 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001291 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001292
Fariborz Jahanian4a303072010-06-16 16:22:04 +00001293 case Builtin::BI__builtin_objc_memmove_collectable: {
John McCall7f416cc2015-09-08 08:05:57 +00001294 Address DestAddr = EmitPointerWithAlignment(E->getArg(0));
1295 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1));
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001296 Value *SizeVal = EmitScalarExpr(E->getArg(2));
Jim Grosbachd3608f42012-09-21 00:18:27 +00001297 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this,
John McCall7f416cc2015-09-08 08:05:57 +00001298 DestAddr, SrcAddr, SizeVal);
1299 return RValue::get(DestAddr.getPointer());
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001300 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001301
1302 case Builtin::BI__builtin___memmove_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001303 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001304 llvm::APSInt Size, DstSize;
1305 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1306 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001307 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001308 if (Size.ugt(DstSize))
1309 break;
John McCall7f416cc2015-09-08 08:05:57 +00001310 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1311 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001312 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001313 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1314 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001315 }
1316
Eli Friedman7f4933f2009-12-17 00:14:28 +00001317 case Builtin::BImemmove:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001318 case Builtin::BI__builtin_memmove: {
John McCall7f416cc2015-09-08 08:05:57 +00001319 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1320 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001321 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001322 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001323 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001324 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001325 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001326 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1327 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001328 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001329 case Builtin::BImemset:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001330 case Builtin::BI__builtin_memset: {
John McCall7f416cc2015-09-08 08:05:57 +00001331 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Benjamin Krameracc6b4e2010-12-30 00:13:21 +00001332 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1333 Builder.getInt8Ty());
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001334 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001335 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001336 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001337 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1338 return RValue::get(Dest.getPointer());
Eli Friedmana3a40682008-05-19 23:27:48 +00001339 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001340 case Builtin::BI__builtin___memset_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001341 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001342 llvm::APSInt Size, DstSize;
1343 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1344 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001345 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001346 if (Size.ugt(DstSize))
1347 break;
John McCall7f416cc2015-09-08 08:05:57 +00001348 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Chris Lattner30107ed2011-04-17 00:40:24 +00001349 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1350 Builder.getInt8Ty());
1351 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001352 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1353 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001354 }
John McCall515c3c52010-03-03 10:30:05 +00001355 case Builtin::BI__builtin_dwarf_cfa: {
1356 // The offset in bytes from the first argument to the CFA.
1357 //
1358 // Why on earth is this in the frontend? Is there any reason at
1359 // all that the backend can't reasonably determine this while
1360 // lowering llvm.eh.dwarf.cfa()?
1361 //
1362 // TODO: If there's a satisfactory reason, add a target hook for
1363 // this instead of hard-coding 0, which is correct for most targets.
1364 int32_t Offset = 0;
1365
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001366 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa);
Jim Grosbachd3608f42012-09-21 00:18:27 +00001367 return RValue::get(Builder.CreateCall(F,
Chris Lattner5e016ae2010-06-27 07:15:29 +00001368 llvm::ConstantInt::get(Int32Ty, Offset)));
John McCall515c3c52010-03-03 10:30:05 +00001369 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001370 case Builtin::BI__builtin_return_address: {
John McCallde0fe072017-08-15 21:42:52 +00001371 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1372 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001373 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001374 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001375 }
Albert Gutowski397d81b2016-10-13 16:03:42 +00001376 case Builtin::BI_ReturnAddress: {
1377 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
1378 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
1379 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001380 case Builtin::BI__builtin_frame_address: {
John McCallde0fe072017-08-15 21:42:52 +00001381 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1382 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001383 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001384 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001385 }
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001386 case Builtin::BI__builtin_extract_return_addr: {
John McCalld4f4b7f2010-03-03 04:15:11 +00001387 Value *Address = EmitScalarExpr(E->getArg(0));
1388 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address);
1389 return RValue::get(Result);
1390 }
1391 case Builtin::BI__builtin_frob_return_addr: {
1392 Value *Address = EmitScalarExpr(E->getArg(0));
1393 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address);
1394 return RValue::get(Result);
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001395 }
John McCallbeec5a02010-03-06 00:35:14 +00001396 case Builtin::BI__builtin_dwarf_sp_column: {
Chris Lattner2192fe52011-07-18 04:24:23 +00001397 llvm::IntegerType *Ty
John McCallbeec5a02010-03-06 00:35:14 +00001398 = cast<llvm::IntegerType>(ConvertType(E->getType()));
1399 int Column = getTargetHooks().getDwarfEHStackPointer(CGM);
1400 if (Column == -1) {
1401 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column");
1402 return RValue::get(llvm::UndefValue::get(Ty));
1403 }
1404 return RValue::get(llvm::ConstantInt::get(Ty, Column, true));
1405 }
1406 case Builtin::BI__builtin_init_dwarf_reg_size_table: {
1407 Value *Address = EmitScalarExpr(E->getArg(0));
1408 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address))
1409 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table");
1410 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
1411 }
John McCall66769f82010-03-03 05:38:58 +00001412 case Builtin::BI__builtin_eh_return: {
1413 Value *Int = EmitScalarExpr(E->getArg(0));
1414 Value *Ptr = EmitScalarExpr(E->getArg(1));
1415
Chris Lattner2192fe52011-07-18 04:24:23 +00001416 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType());
John McCall66769f82010-03-03 05:38:58 +00001417 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) &&
1418 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants");
1419 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32
1420 ? Intrinsic::eh_return_i32
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001421 : Intrinsic::eh_return_i64);
David Blaikie43f9bb72015-05-18 22:14:03 +00001422 Builder.CreateCall(F, {Int, Ptr});
John McCall20f6ab82011-01-12 03:41:02 +00001423 Builder.CreateUnreachable();
1424
1425 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001426 EmitBlock(createBasicBlock("builtin_eh_return.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001427
Craig Topper8a13c412014-05-21 05:09:00 +00001428 return RValue::get(nullptr);
John McCall66769f82010-03-03 05:38:58 +00001429 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001430 case Builtin::BI__builtin_unwind_init: {
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001431 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
David Blaikie4ba525b2015-07-14 17:27:39 +00001432 return RValue::get(Builder.CreateCall(F));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001433 }
John McCall4b613fa2010-03-02 02:31:24 +00001434 case Builtin::BI__builtin_extend_pointer: {
1435 // Extends a pointer to the size of an _Unwind_Word, which is
John McCallb6cc2c042010-03-02 03:50:12 +00001436 // uint64_t on all platforms. Generally this gets poked into a
1437 // register and eventually used as an address, so if the
1438 // addressing registers are wider than pointers and the platform
1439 // doesn't implicitly ignore high-order bits when doing
1440 // addressing, we need to make sure we zext / sext based on
1441 // the platform's expectations.
John McCall4b613fa2010-03-02 02:31:24 +00001442 //
1443 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html
John McCallb6cc2c042010-03-02 03:50:12 +00001444
John McCallb6cc2c042010-03-02 03:50:12 +00001445 // Cast the pointer to intptr_t.
John McCall4b613fa2010-03-02 02:31:24 +00001446 Value *Ptr = EmitScalarExpr(E->getArg(0));
John McCallb6cc2c042010-03-02 03:50:12 +00001447 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast");
1448
1449 // If that's 64 bits, we're done.
1450 if (IntPtrTy->getBitWidth() == 64)
1451 return RValue::get(Result);
1452
1453 // Otherwise, ask the codegen data what to do.
John McCalld4f4b7f2010-03-03 04:15:11 +00001454 if (getTargetHooks().extendPointerWithSExt())
John McCallb6cc2c042010-03-02 03:50:12 +00001455 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext"));
1456 else
1457 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
John McCall4b613fa2010-03-02 02:31:24 +00001458 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001459 case Builtin::BI__builtin_setjmp: {
John McCall02269a62010-05-27 18:47:06 +00001460 // Buffer is a void**.
John McCall7f416cc2015-09-08 08:05:57 +00001461 Address Buf = EmitPointerWithAlignment(E->getArg(0));
John McCall02269a62010-05-27 18:47:06 +00001462
1463 // Store the frame pointer to the setjmp buffer.
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001464 Value *FrameAddr =
John McCall02269a62010-05-27 18:47:06 +00001465 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
Chris Lattner5e016ae2010-06-27 07:15:29 +00001466 ConstantInt::get(Int32Ty, 0));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001467 Builder.CreateStore(FrameAddr, Buf);
John McCall02269a62010-05-27 18:47:06 +00001468
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001469 // Store the stack pointer to the setjmp buffer.
1470 Value *StackAddr =
David Blaikie4ba525b2015-07-14 17:27:39 +00001471 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave));
John McCall7f416cc2015-09-08 08:05:57 +00001472 Address StackSaveSlot =
1473 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize());
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001474 Builder.CreateStore(StackAddr, StackSaveSlot);
1475
John McCall02269a62010-05-27 18:47:06 +00001476 // Call LLVM's EH setjmp, which is lightweight.
1477 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
John McCallad7c5c12011-02-08 08:22:06 +00001478 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00001479 return RValue::get(Builder.CreateCall(F, Buf.getPointer()));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001480 }
1481 case Builtin::BI__builtin_longjmp: {
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001482 Value *Buf = EmitScalarExpr(E->getArg(0));
John McCallad7c5c12011-02-08 08:22:06 +00001483 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall02269a62010-05-27 18:47:06 +00001484
1485 // Call LLVM's EH longjmp, which is lightweight.
1486 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf);
1487
John McCall20f6ab82011-01-12 03:41:02 +00001488 // longjmp doesn't return; mark this as unreachable.
1489 Builder.CreateUnreachable();
1490
1491 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001492 EmitBlock(createBasicBlock("longjmp.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001493
Craig Topper8a13c412014-05-21 05:09:00 +00001494 return RValue::get(nullptr);
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001495 }
Mon P Wangb84407d2008-05-09 22:40:52 +00001496 case Builtin::BI__sync_fetch_and_add:
Mon P Wangb84407d2008-05-09 22:40:52 +00001497 case Builtin::BI__sync_fetch_and_sub:
Chris Lattnerdc046542009-05-08 06:58:22 +00001498 case Builtin::BI__sync_fetch_and_or:
1499 case Builtin::BI__sync_fetch_and_and:
1500 case Builtin::BI__sync_fetch_and_xor:
Hal Finkeld2208b52014-10-02 20:53:50 +00001501 case Builtin::BI__sync_fetch_and_nand:
Chris Lattnerdc046542009-05-08 06:58:22 +00001502 case Builtin::BI__sync_add_and_fetch:
1503 case Builtin::BI__sync_sub_and_fetch:
1504 case Builtin::BI__sync_and_and_fetch:
1505 case Builtin::BI__sync_or_and_fetch:
1506 case Builtin::BI__sync_xor_and_fetch:
Hal Finkeld2208b52014-10-02 20:53:50 +00001507 case Builtin::BI__sync_nand_and_fetch:
Chris Lattnerdc046542009-05-08 06:58:22 +00001508 case Builtin::BI__sync_val_compare_and_swap:
1509 case Builtin::BI__sync_bool_compare_and_swap:
1510 case Builtin::BI__sync_lock_test_and_set:
1511 case Builtin::BI__sync_lock_release:
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001512 case Builtin::BI__sync_swap:
David Blaikie83d382b2011-09-23 05:06:16 +00001513 llvm_unreachable("Shouldn't make it through sema");
Chris Lattnerdc046542009-05-08 06:58:22 +00001514 case Builtin::BI__sync_fetch_and_add_1:
1515 case Builtin::BI__sync_fetch_and_add_2:
1516 case Builtin::BI__sync_fetch_and_add_4:
1517 case Builtin::BI__sync_fetch_and_add_8:
1518 case Builtin::BI__sync_fetch_and_add_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001519 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001520 case Builtin::BI__sync_fetch_and_sub_1:
1521 case Builtin::BI__sync_fetch_and_sub_2:
1522 case Builtin::BI__sync_fetch_and_sub_4:
1523 case Builtin::BI__sync_fetch_and_sub_8:
1524 case Builtin::BI__sync_fetch_and_sub_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001525 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001526 case Builtin::BI__sync_fetch_and_or_1:
1527 case Builtin::BI__sync_fetch_and_or_2:
1528 case Builtin::BI__sync_fetch_and_or_4:
1529 case Builtin::BI__sync_fetch_and_or_8:
1530 case Builtin::BI__sync_fetch_and_or_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001531 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001532 case Builtin::BI__sync_fetch_and_and_1:
1533 case Builtin::BI__sync_fetch_and_and_2:
1534 case Builtin::BI__sync_fetch_and_and_4:
1535 case Builtin::BI__sync_fetch_and_and_8:
1536 case Builtin::BI__sync_fetch_and_and_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001537 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001538 case Builtin::BI__sync_fetch_and_xor_1:
1539 case Builtin::BI__sync_fetch_and_xor_2:
1540 case Builtin::BI__sync_fetch_and_xor_4:
1541 case Builtin::BI__sync_fetch_and_xor_8:
1542 case Builtin::BI__sync_fetch_and_xor_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001543 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E);
Hal Finkeld2208b52014-10-02 20:53:50 +00001544 case Builtin::BI__sync_fetch_and_nand_1:
1545 case Builtin::BI__sync_fetch_and_nand_2:
1546 case Builtin::BI__sync_fetch_and_nand_4:
1547 case Builtin::BI__sync_fetch_and_nand_8:
1548 case Builtin::BI__sync_fetch_and_nand_16:
1549 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E);
Mike Stump11289f42009-09-09 15:08:12 +00001550
Chris Lattnerdc046542009-05-08 06:58:22 +00001551 // Clang extensions: not overloaded yet.
Mon P Wangb84407d2008-05-09 22:40:52 +00001552 case Builtin::BI__sync_fetch_and_min:
Eli Friedmane9f81132011-09-07 01:41:24 +00001553 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001554 case Builtin::BI__sync_fetch_and_max:
Eli Friedmane9f81132011-09-07 01:41:24 +00001555 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001556 case Builtin::BI__sync_fetch_and_umin:
Eli Friedmane9f81132011-09-07 01:41:24 +00001557 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001558 case Builtin::BI__sync_fetch_and_umax:
Eli Friedmane9f81132011-09-07 01:41:24 +00001559 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E);
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001560
Chris Lattnerdc046542009-05-08 06:58:22 +00001561 case Builtin::BI__sync_add_and_fetch_1:
1562 case Builtin::BI__sync_add_and_fetch_2:
1563 case Builtin::BI__sync_add_and_fetch_4:
1564 case Builtin::BI__sync_add_and_fetch_8:
1565 case Builtin::BI__sync_add_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001566 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001567 llvm::Instruction::Add);
Chris Lattnerdc046542009-05-08 06:58:22 +00001568 case Builtin::BI__sync_sub_and_fetch_1:
1569 case Builtin::BI__sync_sub_and_fetch_2:
1570 case Builtin::BI__sync_sub_and_fetch_4:
1571 case Builtin::BI__sync_sub_and_fetch_8:
1572 case Builtin::BI__sync_sub_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001573 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001574 llvm::Instruction::Sub);
Chris Lattnerdc046542009-05-08 06:58:22 +00001575 case Builtin::BI__sync_and_and_fetch_1:
1576 case Builtin::BI__sync_and_and_fetch_2:
1577 case Builtin::BI__sync_and_and_fetch_4:
1578 case Builtin::BI__sync_and_and_fetch_8:
1579 case Builtin::BI__sync_and_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001580 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001581 llvm::Instruction::And);
Chris Lattnerdc046542009-05-08 06:58:22 +00001582 case Builtin::BI__sync_or_and_fetch_1:
1583 case Builtin::BI__sync_or_and_fetch_2:
1584 case Builtin::BI__sync_or_and_fetch_4:
1585 case Builtin::BI__sync_or_and_fetch_8:
1586 case Builtin::BI__sync_or_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001587 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001588 llvm::Instruction::Or);
Chris Lattnerdc046542009-05-08 06:58:22 +00001589 case Builtin::BI__sync_xor_and_fetch_1:
1590 case Builtin::BI__sync_xor_and_fetch_2:
1591 case Builtin::BI__sync_xor_and_fetch_4:
1592 case Builtin::BI__sync_xor_and_fetch_8:
1593 case Builtin::BI__sync_xor_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001594 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001595 llvm::Instruction::Xor);
Hal Finkeld2208b52014-10-02 20:53:50 +00001596 case Builtin::BI__sync_nand_and_fetch_1:
1597 case Builtin::BI__sync_nand_and_fetch_2:
1598 case Builtin::BI__sync_nand_and_fetch_4:
1599 case Builtin::BI__sync_nand_and_fetch_8:
1600 case Builtin::BI__sync_nand_and_fetch_16:
1601 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E,
1602 llvm::Instruction::And, true);
Mike Stump11289f42009-09-09 15:08:12 +00001603
Chris Lattnerdc046542009-05-08 06:58:22 +00001604 case Builtin::BI__sync_val_compare_and_swap_1:
1605 case Builtin::BI__sync_val_compare_and_swap_2:
1606 case Builtin::BI__sync_val_compare_and_swap_4:
1607 case Builtin::BI__sync_val_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001608 case Builtin::BI__sync_val_compare_and_swap_16:
1609 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001610
Chris Lattnerdc046542009-05-08 06:58:22 +00001611 case Builtin::BI__sync_bool_compare_and_swap_1:
1612 case Builtin::BI__sync_bool_compare_and_swap_2:
1613 case Builtin::BI__sync_bool_compare_and_swap_4:
1614 case Builtin::BI__sync_bool_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001615 case Builtin::BI__sync_bool_compare_and_swap_16:
1616 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001617
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001618 case Builtin::BI__sync_swap_1:
1619 case Builtin::BI__sync_swap_2:
1620 case Builtin::BI__sync_swap_4:
1621 case Builtin::BI__sync_swap_8:
1622 case Builtin::BI__sync_swap_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001623 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001624
Chris Lattnerdc046542009-05-08 06:58:22 +00001625 case Builtin::BI__sync_lock_test_and_set_1:
1626 case Builtin::BI__sync_lock_test_and_set_2:
1627 case Builtin::BI__sync_lock_test_and_set_4:
1628 case Builtin::BI__sync_lock_test_and_set_8:
1629 case Builtin::BI__sync_lock_test_and_set_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001630 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Daniel Dunbar4ff562d2010-03-20 07:04:11 +00001631
Chris Lattnerdc046542009-05-08 06:58:22 +00001632 case Builtin::BI__sync_lock_release_1:
1633 case Builtin::BI__sync_lock_release_2:
1634 case Builtin::BI__sync_lock_release_4:
1635 case Builtin::BI__sync_lock_release_8:
Chris Lattnerafde2592009-05-13 04:46:13 +00001636 case Builtin::BI__sync_lock_release_16: {
1637 Value *Ptr = EmitScalarExpr(E->getArg(0));
Eli Friedman84d28122011-09-13 22:21:56 +00001638 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
1639 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
Eli Friedmanfefe0d02012-03-16 01:48:04 +00001640 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
1641 StoreSize.getQuantity() * 8);
1642 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
Jim Grosbachd3608f42012-09-21 00:18:27 +00001643 llvm::StoreInst *Store =
John McCall7f416cc2015-09-08 08:05:57 +00001644 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr,
1645 StoreSize);
JF Bastien92f4ef12016-04-06 17:26:42 +00001646 Store->setAtomic(llvm::AtomicOrdering::Release);
Craig Topper8a13c412014-05-21 05:09:00 +00001647 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001648 }
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001649
Chris Lattnerafde2592009-05-13 04:46:13 +00001650 case Builtin::BI__sync_synchronize: {
Eli Friedmane9f81132011-09-07 01:41:24 +00001651 // We assume this is supposed to correspond to a C++0x-style
1652 // sequentially-consistent fence (i.e. this is only usable for
1653 // synchonization, not device I/O or anything like that). This intrinsic
Jim Grosbachd3608f42012-09-21 00:18:27 +00001654 // is really badly designed in the sense that in theory, there isn't
Eli Friedmane9f81132011-09-07 01:41:24 +00001655 // any way to safely use it... but in practice, it mostly works
1656 // to use it with non-atomic loads and stores to get acquire/release
1657 // semantics.
JF Bastien92f4ef12016-04-06 17:26:42 +00001658 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent);
Craig Topper8a13c412014-05-21 05:09:00 +00001659 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001660 }
Mike Stump11289f42009-09-09 15:08:12 +00001661
Michael Zolotukhin84df1232015-09-08 23:52:33 +00001662 case Builtin::BI__builtin_nontemporal_load:
1663 return RValue::get(EmitNontemporalLoad(*this, E));
1664 case Builtin::BI__builtin_nontemporal_store:
1665 return RValue::get(EmitNontemporalStore(*this, E));
Richard Smith01ba47d2012-04-13 00:45:38 +00001666 case Builtin::BI__c11_atomic_is_lock_free:
1667 case Builtin::BI__atomic_is_lock_free: {
1668 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the
1669 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since
1670 // _Atomic(T) is always properly-aligned.
1671 const char *LibCallName = "__atomic_is_lock_free";
1672 CallArgList Args;
1673 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))),
1674 getContext().getSizeType());
1675 if (BuiltinID == Builtin::BI__atomic_is_lock_free)
1676 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))),
1677 getContext().VoidPtrTy);
1678 else
1679 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)),
1680 getContext().VoidPtrTy);
1681 const CGFunctionInfo &FuncInfo =
John McCallc56a8b32016-03-11 04:30:31 +00001682 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001683 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
1684 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
John McCallb92ab1a2016-10-26 23:46:34 +00001685 return EmitCall(FuncInfo, CGCallee::forDirect(Func),
1686 ReturnValueSlot(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001687 }
1688
1689 case Builtin::BI__atomic_test_and_set: {
1690 // Look at the argument type to determine whether this is a volatile
1691 // operation. The parameter type is always volatile.
1692 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1693 bool Volatile =
1694 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1695
1696 Value *Ptr = EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +00001697 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001698 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1699 Value *NewVal = Builder.getInt8(1);
1700 Value *Order = EmitScalarExpr(E->getArg(1));
1701 if (isa<llvm::ConstantInt>(Order)) {
1702 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
Craig Topper8a13c412014-05-21 05:09:00 +00001703 AtomicRMWInst *Result = nullptr;
Richard Smith01ba47d2012-04-13 00:45:38 +00001704 switch (ord) {
1705 case 0: // memory_order_relaxed
1706 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001707 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1708 llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001709 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001710 case 1: // memory_order_consume
1711 case 2: // memory_order_acquire
1712 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1713 llvm::AtomicOrdering::Acquire);
Richard Smith01ba47d2012-04-13 00:45:38 +00001714 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001715 case 3: // memory_order_release
1716 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1717 llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001718 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001719 case 4: // memory_order_acq_rel
1720
1721 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1722 llvm::AtomicOrdering::AcquireRelease);
Richard Smith01ba47d2012-04-13 00:45:38 +00001723 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001724 case 5: // memory_order_seq_cst
1725 Result = Builder.CreateAtomicRMW(
1726 llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1727 llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001728 break;
1729 }
1730 Result->setVolatile(Volatile);
1731 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1732 }
1733
1734 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1735
1736 llvm::BasicBlock *BBs[5] = {
1737 createBasicBlock("monotonic", CurFn),
1738 createBasicBlock("acquire", CurFn),
1739 createBasicBlock("release", CurFn),
1740 createBasicBlock("acqrel", CurFn),
1741 createBasicBlock("seqcst", CurFn)
1742 };
1743 llvm::AtomicOrdering Orders[5] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001744 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire,
1745 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease,
1746 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001747
1748 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1749 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1750
1751 Builder.SetInsertPoint(ContBB);
1752 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set");
1753
1754 for (unsigned i = 0; i < 5; ++i) {
1755 Builder.SetInsertPoint(BBs[i]);
1756 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg,
1757 Ptr, NewVal, Orders[i]);
1758 RMW->setVolatile(Volatile);
1759 Result->addIncoming(RMW, BBs[i]);
1760 Builder.CreateBr(ContBB);
1761 }
1762
1763 SI->addCase(Builder.getInt32(0), BBs[0]);
1764 SI->addCase(Builder.getInt32(1), BBs[1]);
1765 SI->addCase(Builder.getInt32(2), BBs[1]);
1766 SI->addCase(Builder.getInt32(3), BBs[2]);
1767 SI->addCase(Builder.getInt32(4), BBs[3]);
1768 SI->addCase(Builder.getInt32(5), BBs[4]);
1769
1770 Builder.SetInsertPoint(ContBB);
1771 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1772 }
1773
1774 case Builtin::BI__atomic_clear: {
1775 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1776 bool Volatile =
1777 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1778
John McCall7f416cc2015-09-08 08:05:57 +00001779 Address Ptr = EmitPointerWithAlignment(E->getArg(0));
1780 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001781 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1782 Value *NewVal = Builder.getInt8(0);
1783 Value *Order = EmitScalarExpr(E->getArg(1));
1784 if (isa<llvm::ConstantInt>(Order)) {
1785 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1786 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001787 switch (ord) {
1788 case 0: // memory_order_relaxed
1789 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001790 Store->setOrdering(llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001791 break;
1792 case 3: // memory_order_release
JF Bastien92f4ef12016-04-06 17:26:42 +00001793 Store->setOrdering(llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001794 break;
1795 case 5: // memory_order_seq_cst
JF Bastien92f4ef12016-04-06 17:26:42 +00001796 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001797 break;
1798 }
Craig Topper8a13c412014-05-21 05:09:00 +00001799 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00001800 }
1801
1802 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1803
1804 llvm::BasicBlock *BBs[3] = {
1805 createBasicBlock("monotonic", CurFn),
1806 createBasicBlock("release", CurFn),
1807 createBasicBlock("seqcst", CurFn)
1808 };
1809 llvm::AtomicOrdering Orders[3] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001810 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release,
1811 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001812
1813 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1814 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1815
1816 for (unsigned i = 0; i < 3; ++i) {
1817 Builder.SetInsertPoint(BBs[i]);
1818 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001819 Store->setOrdering(Orders[i]);
1820 Builder.CreateBr(ContBB);
1821 }
1822
1823 SI->addCase(Builder.getInt32(0), BBs[0]);
1824 SI->addCase(Builder.getInt32(3), BBs[1]);
1825 SI->addCase(Builder.getInt32(5), BBs[2]);
1826
1827 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00001828 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00001829 }
1830
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001831 case Builtin::BI__atomic_thread_fence:
Richard Smithb1e36c62012-04-11 17:55:32 +00001832 case Builtin::BI__atomic_signal_fence:
1833 case Builtin::BI__c11_atomic_thread_fence:
1834 case Builtin::BI__c11_atomic_signal_fence: {
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001835 llvm::SyncScope::ID SSID;
Richard Smithb1e36c62012-04-11 17:55:32 +00001836 if (BuiltinID == Builtin::BI__atomic_signal_fence ||
1837 BuiltinID == Builtin::BI__c11_atomic_signal_fence)
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001838 SSID = llvm::SyncScope::SingleThread;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001839 else
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001840 SSID = llvm::SyncScope::System;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001841 Value *Order = EmitScalarExpr(E->getArg(0));
1842 if (isa<llvm::ConstantInt>(Order)) {
1843 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1844 switch (ord) {
1845 case 0: // memory_order_relaxed
1846 default: // invalid order
1847 break;
1848 case 1: // memory_order_consume
1849 case 2: // memory_order_acquire
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001850 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001851 break;
1852 case 3: // memory_order_release
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001853 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001854 break;
1855 case 4: // memory_order_acq_rel
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001856 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001857 break;
1858 case 5: // memory_order_seq_cst
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001859 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001860 break;
1861 }
Craig Topper8a13c412014-05-21 05:09:00 +00001862 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001863 }
1864
1865 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB;
1866 AcquireBB = createBasicBlock("acquire", CurFn);
1867 ReleaseBB = createBasicBlock("release", CurFn);
1868 AcqRelBB = createBasicBlock("acqrel", CurFn);
1869 SeqCstBB = createBasicBlock("seqcst", CurFn);
1870 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1871
1872 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1873 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB);
1874
1875 Builder.SetInsertPoint(AcquireBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001876 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001877 Builder.CreateBr(ContBB);
1878 SI->addCase(Builder.getInt32(1), AcquireBB);
1879 SI->addCase(Builder.getInt32(2), AcquireBB);
1880
1881 Builder.SetInsertPoint(ReleaseBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001882 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001883 Builder.CreateBr(ContBB);
1884 SI->addCase(Builder.getInt32(3), ReleaseBB);
1885
1886 Builder.SetInsertPoint(AcqRelBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001887 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001888 Builder.CreateBr(ContBB);
1889 SI->addCase(Builder.getInt32(4), AcqRelBB);
1890
1891 Builder.SetInsertPoint(SeqCstBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001892 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001893 Builder.CreateBr(ContBB);
1894 SI->addCase(Builder.getInt32(5), SeqCstBB);
1895
1896 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00001897 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001898 }
1899
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001900 // Library functions with special handling.
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001901 case Builtin::BIsqrt:
1902 case Builtin::BIsqrtf:
1903 case Builtin::BIsqrtl: {
Hal Finkel28b2ae32013-09-12 23:57:55 +00001904 // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only
1905 // in finite- or unsafe-math mode (the intrinsic has different semantics
1906 // for handling negative numbers compared to the library function, so
1907 // -fmath-errno=0 is not enough).
1908 if (!FD->hasAttr<ConstAttr>())
1909 break;
1910 if (!(CGM.getCodeGenOpts().UnsafeFPMath ||
1911 CGM.getCodeGenOpts().NoNaNsFPMath))
1912 break;
1913 Value *Arg0 = EmitScalarExpr(E->getArg(0));
1914 llvm::Type *ArgType = Arg0->getType();
1915 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType);
1916 return RValue::get(Builder.CreateCall(F, Arg0));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001917 }
1918
Reid Kleckner8a8c1292015-02-05 00:18:01 +00001919 case Builtin::BI__builtin_pow:
1920 case Builtin::BI__builtin_powf:
1921 case Builtin::BI__builtin_powl:
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001922 case Builtin::BIpow:
1923 case Builtin::BIpowf:
1924 case Builtin::BIpowl: {
Eli Benderskyc3496b02013-07-24 21:22:01 +00001925 // Transform a call to pow* into a @llvm.pow.* intrinsic call.
1926 if (!FD->hasAttr<ConstAttr>())
1927 break;
1928 Value *Base = EmitScalarExpr(E->getArg(0));
1929 Value *Exponent = EmitScalarExpr(E->getArg(1));
1930 llvm::Type *ArgType = Base->getType();
1931 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001932 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001933 }
Eli Friedman99d20f82010-03-06 02:17:52 +00001934
Cameron Zwarichae7bc982011-07-08 21:39:34 +00001935 case Builtin::BIfma:
1936 case Builtin::BIfmaf:
1937 case Builtin::BIfmal:
1938 case Builtin::BI__builtin_fma:
1939 case Builtin::BI__builtin_fmaf:
1940 case Builtin::BI__builtin_fmal: {
1941 // Rewrite fma to intrinsic.
1942 Value *FirstArg = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001943 llvm::Type *ArgType = FirstArg->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001944 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001945 return RValue::get(
1946 Builder.CreateCall(F, {FirstArg, EmitScalarExpr(E->getArg(1)),
1947 EmitScalarExpr(E->getArg(2))}));
Cameron Zwarichae7bc982011-07-08 21:39:34 +00001948 }
1949
Eli Friedman99d20f82010-03-06 02:17:52 +00001950 case Builtin::BI__builtin_signbit:
1951 case Builtin::BI__builtin_signbitf:
1952 case Builtin::BI__builtin_signbitl: {
Chandler Carruthc66deaf2015-03-19 22:39:51 +00001953 return RValue::get(
1954 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))),
1955 ConvertType(E->getType())));
Eli Friedman99d20f82010-03-06 02:17:52 +00001956 }
Reid Kleckner30701ed2017-09-05 20:27:35 +00001957 case Builtin::BI__annotation: {
1958 // Re-encode each wide string to UTF8 and make an MDString.
1959 SmallVector<Metadata *, 1> Strings;
1960 for (const Expr *Arg : E->arguments()) {
1961 const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts());
1962 assert(Str->getCharByteWidth() == 2);
1963 StringRef WideBytes = Str->getBytes();
1964 std::string StrUtf8;
1965 if (!convertUTF16ToUTF8String(
1966 makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) {
1967 CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument");
1968 continue;
1969 }
1970 Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8));
1971 }
1972
1973 // Build and MDTuple of MDStrings and emit the intrinsic call.
Reid Klecknerd53c39b2017-09-05 20:38:29 +00001974 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {});
Reid Kleckner30701ed2017-09-05 20:27:35 +00001975 MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings);
1976 Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple));
1977 return RValue::getIgnored();
1978 }
Julien Lerouge5a6b6982011-09-09 22:41:49 +00001979 case Builtin::BI__builtin_annotation: {
1980 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0));
1981 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation,
1982 AnnVal->getType());
1983
1984 // Get the annotation string, go through casts. Sema requires this to be a
1985 // non-wide string literal, potentially casted, so the cast<> is safe.
1986 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts();
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001987 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString();
Julien Lerouge5a6b6982011-09-09 22:41:49 +00001988 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc()));
1989 }
Michael Gottesman15343992013-06-18 20:40:40 +00001990 case Builtin::BI__builtin_addcb:
Michael Gottesman54398012013-01-13 02:22:39 +00001991 case Builtin::BI__builtin_addcs:
1992 case Builtin::BI__builtin_addc:
1993 case Builtin::BI__builtin_addcl:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00001994 case Builtin::BI__builtin_addcll:
Michael Gottesman15343992013-06-18 20:40:40 +00001995 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00001996 case Builtin::BI__builtin_subcs:
1997 case Builtin::BI__builtin_subc:
1998 case Builtin::BI__builtin_subcl:
1999 case Builtin::BI__builtin_subcll: {
Michael Gottesman54398012013-01-13 02:22:39 +00002000
2001 // We translate all of these builtins from expressions of the form:
2002 // int x = ..., y = ..., carryin = ..., carryout, result;
2003 // result = __builtin_addc(x, y, carryin, &carryout);
2004 //
2005 // to LLVM IR of the form:
2006 //
2007 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
2008 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0
2009 // %carry1 = extractvalue {i32, i1} %tmp1, 1
2010 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1,
2011 // i32 %carryin)
2012 // %result = extractvalue {i32, i1} %tmp2, 0
2013 // %carry2 = extractvalue {i32, i1} %tmp2, 1
2014 // %tmp3 = or i1 %carry1, %carry2
2015 // %tmp4 = zext i1 %tmp3 to i32
2016 // store i32 %tmp4, i32* %carryout
2017
2018 // Scalarize our inputs.
2019 llvm::Value *X = EmitScalarExpr(E->getArg(0));
2020 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
2021 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00002022 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3));
Michael Gottesman54398012013-01-13 02:22:39 +00002023
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002024 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow.
2025 llvm::Intrinsic::ID IntrinsicId;
2026 switch (BuiltinID) {
2027 default: llvm_unreachable("Unknown multiprecision builtin id.");
Michael Gottesman15343992013-06-18 20:40:40 +00002028 case Builtin::BI__builtin_addcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002029 case Builtin::BI__builtin_addcs:
2030 case Builtin::BI__builtin_addc:
2031 case Builtin::BI__builtin_addcl:
2032 case Builtin::BI__builtin_addcll:
2033 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2034 break;
Michael Gottesman15343992013-06-18 20:40:40 +00002035 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002036 case Builtin::BI__builtin_subcs:
2037 case Builtin::BI__builtin_subc:
2038 case Builtin::BI__builtin_subcl:
2039 case Builtin::BI__builtin_subcll:
2040 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2041 break;
2042 }
Michael Gottesman54398012013-01-13 02:22:39 +00002043
2044 // Construct our resulting LLVM IR expression.
2045 llvm::Value *Carry1;
2046 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId,
2047 X, Y, Carry1);
2048 llvm::Value *Carry2;
2049 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId,
2050 Sum1, Carryin, Carry2);
2051 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2),
2052 X->getType());
John McCall7f416cc2015-09-08 08:05:57 +00002053 Builder.CreateStore(CarryOut, CarryOutPtr);
Michael Gottesman54398012013-01-13 02:22:39 +00002054 return RValue::get(Sum2);
2055 }
John McCall03107a42015-10-29 20:48:01 +00002056
2057 case Builtin::BI__builtin_add_overflow:
2058 case Builtin::BI__builtin_sub_overflow:
2059 case Builtin::BI__builtin_mul_overflow: {
2060 const clang::Expr *LeftArg = E->getArg(0);
2061 const clang::Expr *RightArg = E->getArg(1);
2062 const clang::Expr *ResultArg = E->getArg(2);
2063
2064 clang::QualType ResultQTy =
2065 ResultArg->getType()->castAs<PointerType>()->getPointeeType();
2066
2067 WidthAndSignedness LeftInfo =
2068 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType());
2069 WidthAndSignedness RightInfo =
2070 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType());
2071 WidthAndSignedness ResultInfo =
2072 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy);
2073 WidthAndSignedness EncompassingInfo =
2074 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo});
2075
2076 llvm::Type *EncompassingLLVMTy =
2077 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width);
2078
2079 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy);
2080
2081 llvm::Intrinsic::ID IntrinsicId;
2082 switch (BuiltinID) {
2083 default:
2084 llvm_unreachable("Unknown overflow builtin id.");
2085 case Builtin::BI__builtin_add_overflow:
2086 IntrinsicId = EncompassingInfo.Signed
2087 ? llvm::Intrinsic::sadd_with_overflow
2088 : llvm::Intrinsic::uadd_with_overflow;
2089 break;
2090 case Builtin::BI__builtin_sub_overflow:
2091 IntrinsicId = EncompassingInfo.Signed
2092 ? llvm::Intrinsic::ssub_with_overflow
2093 : llvm::Intrinsic::usub_with_overflow;
2094 break;
2095 case Builtin::BI__builtin_mul_overflow:
2096 IntrinsicId = EncompassingInfo.Signed
2097 ? llvm::Intrinsic::smul_with_overflow
2098 : llvm::Intrinsic::umul_with_overflow;
2099 break;
2100 }
2101
2102 llvm::Value *Left = EmitScalarExpr(LeftArg);
2103 llvm::Value *Right = EmitScalarExpr(RightArg);
2104 Address ResultPtr = EmitPointerWithAlignment(ResultArg);
2105
2106 // Extend each operand to the encompassing type.
2107 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed);
2108 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed);
2109
2110 // Perform the operation on the extended values.
2111 llvm::Value *Overflow, *Result;
2112 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow);
2113
2114 if (EncompassingInfo.Width > ResultInfo.Width) {
2115 // The encompassing type is wider than the result type, so we need to
2116 // truncate it.
2117 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy);
2118
2119 // To see if the truncation caused an overflow, we will extend
2120 // the result and then compare it to the original result.
2121 llvm::Value *ResultTruncExt = Builder.CreateIntCast(
2122 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed);
2123 llvm::Value *TruncationOverflow =
2124 Builder.CreateICmpNE(Result, ResultTruncExt);
2125
2126 Overflow = Builder.CreateOr(Overflow, TruncationOverflow);
2127 Result = ResultTrunc;
2128 }
2129
2130 // Finally, store the result using the pointer.
2131 bool isVolatile =
2132 ResultArg->getType()->getPointeeType().isVolatileQualified();
2133 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile);
2134
2135 return RValue::get(Overflow);
2136 }
2137
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002138 case Builtin::BI__builtin_uadd_overflow:
2139 case Builtin::BI__builtin_uaddl_overflow:
2140 case Builtin::BI__builtin_uaddll_overflow:
2141 case Builtin::BI__builtin_usub_overflow:
2142 case Builtin::BI__builtin_usubl_overflow:
2143 case Builtin::BI__builtin_usubll_overflow:
2144 case Builtin::BI__builtin_umul_overflow:
2145 case Builtin::BI__builtin_umull_overflow:
2146 case Builtin::BI__builtin_umulll_overflow:
2147 case Builtin::BI__builtin_sadd_overflow:
2148 case Builtin::BI__builtin_saddl_overflow:
2149 case Builtin::BI__builtin_saddll_overflow:
2150 case Builtin::BI__builtin_ssub_overflow:
2151 case Builtin::BI__builtin_ssubl_overflow:
2152 case Builtin::BI__builtin_ssubll_overflow:
2153 case Builtin::BI__builtin_smul_overflow:
2154 case Builtin::BI__builtin_smull_overflow:
2155 case Builtin::BI__builtin_smulll_overflow: {
2156
2157 // We translate all of these builtins directly to the relevant llvm IR node.
2158
2159 // Scalarize our inputs.
2160 llvm::Value *X = EmitScalarExpr(E->getArg(0));
2161 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00002162 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2));
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002163
2164 // Decide which of the overflow intrinsics we are lowering to:
2165 llvm::Intrinsic::ID IntrinsicId;
2166 switch (BuiltinID) {
John McCall03107a42015-10-29 20:48:01 +00002167 default: llvm_unreachable("Unknown overflow builtin id.");
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002168 case Builtin::BI__builtin_uadd_overflow:
2169 case Builtin::BI__builtin_uaddl_overflow:
2170 case Builtin::BI__builtin_uaddll_overflow:
2171 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2172 break;
2173 case Builtin::BI__builtin_usub_overflow:
2174 case Builtin::BI__builtin_usubl_overflow:
2175 case Builtin::BI__builtin_usubll_overflow:
2176 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2177 break;
2178 case Builtin::BI__builtin_umul_overflow:
2179 case Builtin::BI__builtin_umull_overflow:
2180 case Builtin::BI__builtin_umulll_overflow:
2181 IntrinsicId = llvm::Intrinsic::umul_with_overflow;
2182 break;
2183 case Builtin::BI__builtin_sadd_overflow:
2184 case Builtin::BI__builtin_saddl_overflow:
2185 case Builtin::BI__builtin_saddll_overflow:
2186 IntrinsicId = llvm::Intrinsic::sadd_with_overflow;
2187 break;
2188 case Builtin::BI__builtin_ssub_overflow:
2189 case Builtin::BI__builtin_ssubl_overflow:
2190 case Builtin::BI__builtin_ssubll_overflow:
2191 IntrinsicId = llvm::Intrinsic::ssub_with_overflow;
2192 break;
2193 case Builtin::BI__builtin_smul_overflow:
2194 case Builtin::BI__builtin_smull_overflow:
2195 case Builtin::BI__builtin_smulll_overflow:
2196 IntrinsicId = llvm::Intrinsic::smul_with_overflow;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00002197 break;
2198 }
2199
2200
2201 llvm::Value *Carry;
2202 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry);
2203 Builder.CreateStore(Sum, SumOutPtr);
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002204
2205 return RValue::get(Carry);
2206 }
Richard Smith6cbd65d2013-07-11 02:27:57 +00002207 case Builtin::BI__builtin_addressof:
John McCall7f416cc2015-09-08 08:05:57 +00002208 return RValue::get(EmitLValue(E->getArg(0)).getPointer());
Richard Smith760520b2014-06-03 23:27:44 +00002209 case Builtin::BI__builtin_operator_new:
2210 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2211 E->getArg(0), false);
2212 case Builtin::BI__builtin_operator_delete:
2213 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2214 E->getArg(0), true);
Nico Weber636fc092012-10-13 22:30:41 +00002215 case Builtin::BI__noop:
Reid Klecknered5d4ad2014-07-11 20:22:55 +00002216 // __noop always evaluates to an integer literal zero.
2217 return RValue::get(ConstantInt::get(IntTy, 0));
Peter Collingbournef7706832014-12-12 23:41:25 +00002218 case Builtin::BI__builtin_call_with_static_chain: {
2219 const CallExpr *Call = cast<CallExpr>(E->getArg(0));
2220 const Expr *Chain = E->getArg(1);
2221 return EmitCall(Call->getCallee()->getType(),
John McCallb92ab1a2016-10-26 23:46:34 +00002222 EmitCallee(Call->getCallee()), Call, ReturnValue,
2223 EmitScalarExpr(Chain));
Peter Collingbournef7706832014-12-12 23:41:25 +00002224 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002225 case Builtin::BI_InterlockedExchange8:
2226 case Builtin::BI_InterlockedExchange16:
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002227 case Builtin::BI_InterlockedExchange:
2228 case Builtin::BI_InterlockedExchangePointer:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002229 return RValue::get(
2230 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E));
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002231 case Builtin::BI_InterlockedCompareExchangePointer: {
2232 llvm::Type *RTy;
2233 llvm::IntegerType *IntType =
2234 IntegerType::get(getLLVMContext(),
2235 getContext().getTypeSize(E->getType()));
2236 llvm::Type *IntPtrType = IntType->getPointerTo();
2237
2238 llvm::Value *Destination =
2239 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType);
2240
2241 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
2242 RTy = Exchange->getType();
2243 Exchange = Builder.CreatePtrToInt(Exchange, IntType);
2244
2245 llvm::Value *Comparand =
2246 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
2247
JF Bastien92f4ef12016-04-06 17:26:42 +00002248 auto Result =
2249 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,
2250 AtomicOrdering::SequentiallyConsistent,
2251 AtomicOrdering::SequentiallyConsistent);
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002252 Result->setVolatile(true);
2253
2254 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
2255 0),
2256 RTy));
2257 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002258 case Builtin::BI_InterlockedCompareExchange8:
2259 case Builtin::BI_InterlockedCompareExchange16:
2260 case Builtin::BI_InterlockedCompareExchange:
2261 case Builtin::BI_InterlockedCompareExchange64: {
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002262 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg(
2263 EmitScalarExpr(E->getArg(0)),
2264 EmitScalarExpr(E->getArg(2)),
2265 EmitScalarExpr(E->getArg(1)),
JF Bastien92f4ef12016-04-06 17:26:42 +00002266 AtomicOrdering::SequentiallyConsistent,
2267 AtomicOrdering::SequentiallyConsistent);
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002268 CXI->setVolatile(true);
Tim Northoverb49b04b2014-06-13 14:24:59 +00002269 return RValue::get(Builder.CreateExtractValue(CXI, 0));
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002270 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002271 case Builtin::BI_InterlockedIncrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002272 case Builtin::BI_InterlockedIncrement:
2273 return RValue::get(
2274 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002275 case Builtin::BI_InterlockedDecrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002276 case Builtin::BI_InterlockedDecrement:
2277 return RValue::get(
2278 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002279 case Builtin::BI_InterlockedAnd8:
2280 case Builtin::BI_InterlockedAnd16:
2281 case Builtin::BI_InterlockedAnd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002282 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002283 case Builtin::BI_InterlockedExchangeAdd8:
2284 case Builtin::BI_InterlockedExchangeAdd16:
2285 case Builtin::BI_InterlockedExchangeAdd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002286 return RValue::get(
2287 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002288 case Builtin::BI_InterlockedExchangeSub8:
2289 case Builtin::BI_InterlockedExchangeSub16:
2290 case Builtin::BI_InterlockedExchangeSub:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002291 return RValue::get(
2292 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002293 case Builtin::BI_InterlockedOr8:
2294 case Builtin::BI_InterlockedOr16:
2295 case Builtin::BI_InterlockedOr:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002296 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002297 case Builtin::BI_InterlockedXor8:
2298 case Builtin::BI_InterlockedXor16:
2299 case Builtin::BI_InterlockedXor:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002300 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E));
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002301 case Builtin::BI_interlockedbittestandset:
2302 return RValue::get(
2303 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E));
Reid Kleckner1d59f992015-01-22 01:36:17 +00002304
2305 case Builtin::BI__exception_code:
2306 case Builtin::BI_exception_code:
2307 return RValue::get(EmitSEHExceptionCode());
2308 case Builtin::BI__exception_info:
2309 case Builtin::BI_exception_info:
2310 return RValue::get(EmitSEHExceptionInfo());
Reid Kleckneraca01db2015-02-04 22:37:07 +00002311 case Builtin::BI__abnormal_termination:
2312 case Builtin::BI_abnormal_termination:
2313 return RValue::get(EmitSEHAbnormalTermination());
David Majnemer310e3a82015-01-29 09:29:21 +00002314 case Builtin::BI_setjmpex: {
2315 if (getTarget().getTriple().isOSMSVCRT()) {
2316 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
Reid Klecknerde864822017-03-21 16:57:30 +00002317 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2318 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2319 llvm::Attribute::ReturnsTwice);
David Majnemer310e3a82015-01-29 09:29:21 +00002320 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction(
2321 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002322 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true);
David Majnemerc403a1c2015-03-20 17:03:35 +00002323 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2324 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002325 llvm::Value *FrameAddr =
2326 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2327 ConstantInt::get(Int32Ty, 0));
2328 llvm::Value *Args[] = {Buf, FrameAddr};
2329 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args);
2330 CS.setAttributes(ReturnsTwiceAttr);
2331 return RValue::get(CS.getInstruction());
2332 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002333 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002334 }
2335 case Builtin::BI_setjmp: {
2336 if (getTarget().getTriple().isOSMSVCRT()) {
Reid Klecknerde864822017-03-21 16:57:30 +00002337 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2338 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2339 llvm::Attribute::ReturnsTwice);
David Majnemerc403a1c2015-03-20 17:03:35 +00002340 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2341 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002342 llvm::CallSite CS;
2343 if (getTarget().getTriple().getArch() == llvm::Triple::x86) {
2344 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy};
2345 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction(
2346 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002347 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002348 llvm::Value *Count = ConstantInt::get(IntTy, 0);
2349 llvm::Value *Args[] = {Buf, Count};
2350 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args);
2351 } else {
2352 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
2353 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction(
2354 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002355 "_setjmp", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002356 llvm::Value *FrameAddr =
2357 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2358 ConstantInt::get(Int32Ty, 0));
2359 llvm::Value *Args[] = {Buf, FrameAddr};
2360 CS = EmitRuntimeCallOrInvoke(SetJmp, Args);
2361 }
2362 CS.setAttributes(ReturnsTwiceAttr);
2363 return RValue::get(CS.getInstruction());
2364 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002365 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002366 }
David Majnemerba3e5ec2015-03-13 18:26:17 +00002367
2368 case Builtin::BI__GetExceptionInfo: {
2369 if (llvm::GlobalVariable *GV =
2370 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType()))
2371 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy));
2372 break;
2373 }
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002374
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002375 case Builtin::BI__fastfail:
Reid Kleckner04f9f912017-02-09 18:31:06 +00002376 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E));
Reid Kleckner04f9f912017-02-09 18:31:06 +00002377
Gor Nishanov97e3b6d2016-10-03 22:44:48 +00002378 case Builtin::BI__builtin_coro_size: {
2379 auto & Context = getContext();
2380 auto SizeTy = Context.getSizeType();
2381 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
2382 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T);
2383 return RValue::get(Builder.CreateCall(F));
2384 }
2385
2386 case Builtin::BI__builtin_coro_id:
2387 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id);
2388 case Builtin::BI__builtin_coro_promise:
2389 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise);
2390 case Builtin::BI__builtin_coro_resume:
2391 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume);
2392 case Builtin::BI__builtin_coro_frame:
2393 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame);
2394 case Builtin::BI__builtin_coro_free:
2395 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free);
2396 case Builtin::BI__builtin_coro_destroy:
2397 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy);
2398 case Builtin::BI__builtin_coro_done:
2399 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done);
2400 case Builtin::BI__builtin_coro_alloc:
2401 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc);
2402 case Builtin::BI__builtin_coro_begin:
2403 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin);
2404 case Builtin::BI__builtin_coro_end:
2405 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end);
2406 case Builtin::BI__builtin_coro_suspend:
2407 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend);
2408 case Builtin::BI__builtin_coro_param:
2409 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param);
2410
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002411 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions
2412 case Builtin::BIread_pipe:
2413 case Builtin::BIwrite_pipe: {
2414 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2415 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002416 CGOpenCLRuntime OpenCLRT(CGM);
2417 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2418 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002419
2420 // Type of the generic packet parameter.
2421 unsigned GenericAS =
2422 getContext().getTargetAddressSpace(LangAS::opencl_generic);
2423 llvm::Type *I8PTy = llvm::PointerType::get(
2424 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS);
2425
2426 // Testing which overloaded version we should generate the call for.
2427 if (2U == E->getNumArgs()) {
2428 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2"
2429 : "__write_pipe_2";
2430 // Creating a generic function type to be able to call with any builtin or
2431 // user defined type.
Alexey Bader465c1892016-09-23 14:20:00 +00002432 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002433 llvm::FunctionType *FTy = llvm::FunctionType::get(
2434 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2435 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002436 return RValue::get(
2437 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2438 {Arg0, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002439 } else {
2440 assert(4 == E->getNumArgs() &&
2441 "Illegal number of parameters to pipe function");
2442 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4"
2443 : "__write_pipe_4";
2444
Alexey Bader465c1892016-09-23 14:20:00 +00002445 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy,
2446 Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002447 Value *Arg2 = EmitScalarExpr(E->getArg(2)),
2448 *Arg3 = EmitScalarExpr(E->getArg(3));
2449 llvm::FunctionType *FTy = llvm::FunctionType::get(
2450 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2451 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy);
2452 // We know the third argument is an integer type, but we may need to cast
2453 // it to i32.
2454 if (Arg2->getType() != Int32Ty)
2455 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty);
2456 return RValue::get(Builder.CreateCall(
Alexey Bader465c1892016-09-23 14:20:00 +00002457 CGM.CreateRuntimeFunction(FTy, Name),
2458 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002459 }
2460 }
2461 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write
2462 // functions
2463 case Builtin::BIreserve_read_pipe:
2464 case Builtin::BIreserve_write_pipe:
2465 case Builtin::BIwork_group_reserve_read_pipe:
2466 case Builtin::BIwork_group_reserve_write_pipe:
2467 case Builtin::BIsub_group_reserve_read_pipe:
2468 case Builtin::BIsub_group_reserve_write_pipe: {
2469 // Composing the mangled name for the function.
2470 const char *Name;
2471 if (BuiltinID == Builtin::BIreserve_read_pipe)
2472 Name = "__reserve_read_pipe";
2473 else if (BuiltinID == Builtin::BIreserve_write_pipe)
2474 Name = "__reserve_write_pipe";
2475 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe)
2476 Name = "__work_group_reserve_read_pipe";
2477 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe)
2478 Name = "__work_group_reserve_write_pipe";
2479 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe)
2480 Name = "__sub_group_reserve_read_pipe";
2481 else
2482 Name = "__sub_group_reserve_write_pipe";
2483
2484 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2485 *Arg1 = EmitScalarExpr(E->getArg(1));
2486 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002487 CGOpenCLRuntime OpenCLRT(CGM);
2488 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2489 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002490
2491 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002492 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002493 llvm::FunctionType *FTy = llvm::FunctionType::get(
2494 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2495 // We know the second argument is an integer type, but we may need to cast
2496 // it to i32.
2497 if (Arg1->getType() != Int32Ty)
2498 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty);
2499 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002500 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2501 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002502 }
Anastasia Stulova7f8d6dc2016-07-04 16:07:18 +00002503 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002504 // functions
2505 case Builtin::BIcommit_read_pipe:
2506 case Builtin::BIcommit_write_pipe:
2507 case Builtin::BIwork_group_commit_read_pipe:
2508 case Builtin::BIwork_group_commit_write_pipe:
2509 case Builtin::BIsub_group_commit_read_pipe:
2510 case Builtin::BIsub_group_commit_write_pipe: {
2511 const char *Name;
2512 if (BuiltinID == Builtin::BIcommit_read_pipe)
2513 Name = "__commit_read_pipe";
2514 else if (BuiltinID == Builtin::BIcommit_write_pipe)
2515 Name = "__commit_write_pipe";
2516 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe)
2517 Name = "__work_group_commit_read_pipe";
2518 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe)
2519 Name = "__work_group_commit_write_pipe";
2520 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe)
2521 Name = "__sub_group_commit_read_pipe";
2522 else
2523 Name = "__sub_group_commit_write_pipe";
2524
2525 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2526 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002527 CGOpenCLRuntime OpenCLRT(CGM);
2528 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2529 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002530
2531 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002532 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002533 llvm::FunctionType *FTy =
2534 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
2535 llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2536
2537 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002538 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2539 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002540 }
2541 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions
2542 case Builtin::BIget_pipe_num_packets:
2543 case Builtin::BIget_pipe_max_packets: {
2544 const char *Name;
2545 if (BuiltinID == Builtin::BIget_pipe_num_packets)
2546 Name = "__get_pipe_num_packets";
2547 else
2548 Name = "__get_pipe_max_packets";
2549
2550 // Building the generic function prototype.
2551 Value *Arg0 = EmitScalarExpr(E->getArg(0));
Alexey Bader465c1892016-09-23 14:20:00 +00002552 CGOpenCLRuntime OpenCLRT(CGM);
2553 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2554 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
2555 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002556 llvm::FunctionType *FTy = llvm::FunctionType::get(
2557 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2558
Alexey Bader465c1892016-09-23 14:20:00 +00002559 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2560 {Arg0, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002561 }
2562
Yaxun Liuf7449a12016-05-20 19:54:38 +00002563 // OpenCL v2.0 s6.13.9 - Address space qualifier functions.
2564 case Builtin::BIto_global:
2565 case Builtin::BIto_local:
2566 case Builtin::BIto_private: {
2567 auto Arg0 = EmitScalarExpr(E->getArg(0));
2568 auto NewArgT = llvm::PointerType::get(Int8Ty,
2569 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
2570 auto NewRetT = llvm::PointerType::get(Int8Ty,
2571 CGM.getContext().getTargetAddressSpace(
2572 E->getType()->getPointeeType().getAddressSpace()));
2573 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false);
2574 llvm::Value *NewArg;
2575 if (Arg0->getType()->getPointerAddressSpace() !=
2576 NewArgT->getPointerAddressSpace())
2577 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT);
2578 else
2579 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT);
Alexey Baderd81623262016-08-04 18:06:27 +00002580 auto NewName = std::string("__") + E->getDirectCallee()->getName().str();
2581 auto NewCall =
2582 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg});
Yaxun Liuf7449a12016-05-20 19:54:38 +00002583 return RValue::get(Builder.CreateBitOrPointerCast(NewCall,
2584 ConvertType(E->getType())));
2585 }
2586
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002587 // OpenCL v2.0, s6.13.17 - Enqueue kernel function.
2588 // It contains four different overload formats specified in Table 6.13.17.1.
2589 case Builtin::BIenqueue_kernel: {
2590 StringRef Name; // Generated function call name
2591 unsigned NumArgs = E->getNumArgs();
2592
2593 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002594 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2595 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002596
2597 llvm::Value *Queue = EmitScalarExpr(E->getArg(0));
2598 llvm::Value *Flags = EmitScalarExpr(E->getArg(1));
Anastasia Stulova58984e72017-02-16 12:27:47 +00002599 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2));
2600 llvm::Value *Range = NDRangeL.getAddress().getPointer();
2601 llvm::Type *RangeTy = NDRangeL.getAddress().getType();
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002602
2603 if (NumArgs == 4) {
2604 // The most basic form of the call with parameters:
2605 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void)
2606 Name = "__enqueue_kernel_basic";
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002607 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002608 llvm::FunctionType *FTy = llvm::FunctionType::get(
2609 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys, 4), false);
2610
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002611 llvm::Value *Block = Builder.CreatePointerCast(
2612 EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002613
Anastasia Stulova58984e72017-02-16 12:27:47 +00002614 AttrBuilder B;
2615 B.addAttribute(Attribute::ByVal);
Reid Klecknerde864822017-03-21 16:57:30 +00002616 llvm::AttributeList ByValAttrSet =
2617 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B);
Anastasia Stulova58984e72017-02-16 12:27:47 +00002618
2619 auto RTCall =
2620 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet),
2621 {Queue, Flags, Range, Block});
2622 RTCall->setAttributes(ByValAttrSet);
2623 return RValue::get(RTCall);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002624 }
2625 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature");
2626
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002627 // Create a temporary array to hold the sizes of local pointer arguments
2628 // for the block. \p First is the position of the first size argument.
2629 auto CreateArrayForSizeVar = [=](unsigned First) {
2630 auto *AT = llvm::ArrayType::get(SizeTy, NumArgs - First);
2631 auto *Arr = Builder.CreateAlloca(AT);
2632 llvm::Value *Ptr;
2633 // Each of the following arguments specifies the size of the corresponding
2634 // argument passed to the enqueued block.
2635 auto *Zero = llvm::ConstantInt::get(IntTy, 0);
2636 for (unsigned I = First; I < NumArgs; ++I) {
2637 auto *Index = llvm::ConstantInt::get(IntTy, I - First);
2638 auto *GEP = Builder.CreateGEP(Arr, {Zero, Index});
2639 if (I == First)
2640 Ptr = GEP;
2641 auto *V =
2642 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy);
2643 Builder.CreateAlignedStore(
2644 V, GEP, CGM.getDataLayout().getPrefTypeAlignment(SizeTy));
2645 }
2646 return Ptr;
2647 };
2648
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002649 // Could have events and/or vaargs.
2650 if (E->getArg(3)->getType()->isBlockPointerType()) {
2651 // No events passed, but has variadic arguments.
2652 Name = "__enqueue_kernel_vaargs";
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002653 auto *Block = Builder.CreatePointerCast(EmitScalarExpr(E->getArg(3)),
2654 GenericVoidPtrTy);
2655 auto *PtrToSizeArray = CreateArrayForSizeVar(4);
2656
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002657 // Create a vector of the arguments, as well as a constant value to
2658 // express to the runtime the number of variadic arguments.
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002659 std::vector<llvm::Value *> Args = {Queue,
2660 Flags,
2661 Range,
2662 Block,
2663 ConstantInt::get(IntTy, NumArgs - 4),
2664 PtrToSizeArray};
2665 std::vector<llvm::Type *> ArgTys = {QueueTy, IntTy,
2666 RangeTy, GenericVoidPtrTy,
2667 IntTy, PtrToSizeArray->getType()};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002668
2669 llvm::FunctionType *FTy = llvm::FunctionType::get(
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002670 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002671 return RValue::get(
2672 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2673 llvm::ArrayRef<llvm::Value *>(Args)));
2674 }
2675 // Any calls now have event arguments passed.
2676 if (NumArgs >= 7) {
2677 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy);
Anastasia Stulova2b461202016-11-14 15:34:01 +00002678 llvm::Type *EventPtrTy = EventTy->getPointerTo(
2679 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002680
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002681 llvm::Value *NumEvents =
2682 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002683 llvm::Value *EventList =
2684 E->getArg(4)->getType()->isArrayType()
2685 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer()
2686 : EmitScalarExpr(E->getArg(4));
2687 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5));
Anastasia Stulova2b461202016-11-14 15:34:01 +00002688 // Convert to generic address space.
2689 EventList = Builder.CreatePointerCast(EventList, EventPtrTy);
2690 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002691 llvm::Value *Block = Builder.CreatePointerCast(
2692 EmitScalarExpr(E->getArg(6)), GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002693
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002694 std::vector<llvm::Type *> ArgTys = {
2695 QueueTy, Int32Ty, RangeTy, Int32Ty,
2696 EventPtrTy, EventPtrTy, GenericVoidPtrTy};
Anastasia Stulova2b461202016-11-14 15:34:01 +00002697
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002698 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents,
2699 EventList, ClkEvent, Block};
2700
2701 if (NumArgs == 7) {
2702 // Has events but no variadics.
2703 Name = "__enqueue_kernel_basic_events";
2704 llvm::FunctionType *FTy = llvm::FunctionType::get(
2705 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2706 return RValue::get(
2707 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2708 llvm::ArrayRef<llvm::Value *>(Args)));
2709 }
2710 // Has event info and variadics
2711 // Pass the number of variadics to the runtime function too.
2712 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7));
2713 ArgTys.push_back(Int32Ty);
2714 Name = "__enqueue_kernel_events_vaargs";
2715
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002716 auto *PtrToSizeArray = CreateArrayForSizeVar(7);
2717 Args.push_back(PtrToSizeArray);
2718 ArgTys.push_back(PtrToSizeArray->getType());
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002719
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002720 llvm::FunctionType *FTy = llvm::FunctionType::get(
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002721 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002722 return RValue::get(
2723 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2724 llvm::ArrayRef<llvm::Value *>(Args)));
2725 }
Galina Kistanova0872d6c2017-06-03 06:30:46 +00002726 LLVM_FALLTHROUGH;
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002727 }
2728 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
2729 // parameter.
2730 case Builtin::BIget_kernel_work_group_size: {
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002731 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2732 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002733 Value *Arg = EmitScalarExpr(E->getArg(0));
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002734 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002735 return RValue::get(Builder.CreateCall(
2736 CGM.CreateRuntimeFunction(
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002737 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
2738 "__get_kernel_work_group_size_impl"),
2739 Arg));
2740 }
2741 case Builtin::BIget_kernel_preferred_work_group_size_multiple: {
2742 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2743 getContext().getTargetAddressSpace(LangAS::opencl_generic));
2744 Value *Arg = EmitScalarExpr(E->getArg(0));
2745 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
2746 return RValue::get(Builder.CreateCall(
2747 CGM.CreateRuntimeFunction(
2748 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002749 "__get_kernel_preferred_work_group_multiple_impl"),
2750 Arg));
2751 }
Joey Goulyfa76b492017-08-01 13:27:09 +00002752 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2753 case Builtin::BIget_kernel_sub_group_count_for_ndrange: {
2754 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2755 getContext().getTargetAddressSpace(LangAS::opencl_generic));
2756 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0));
2757 llvm::Value *NDRange = NDRangeL.getAddress().getPointer();
2758 Value *Block = EmitScalarExpr(E->getArg(1));
2759 Block = Builder.CreatePointerCast(Block, GenericVoidPtrTy);
2760 const char *Name =
2761 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange
2762 ? "__get_kernel_max_sub_group_size_for_ndrange_impl"
2763 : "__get_kernel_sub_group_count_for_ndrange_impl";
2764 return RValue::get(Builder.CreateCall(
2765 CGM.CreateRuntimeFunction(
2766 llvm::FunctionType::get(
2767 IntTy, {NDRange->getType(), GenericVoidPtrTy}, false),
2768 Name),
2769 {NDRange, Block}));
2770 }
Jan Vesely31ecb4b2017-09-07 19:39:10 +00002771
2772 case Builtin::BI__builtin_store_half:
2773 case Builtin::BI__builtin_store_halff: {
2774 Value *Val = EmitScalarExpr(E->getArg(0));
2775 Address Address = EmitPointerWithAlignment(E->getArg(1));
2776 Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy());
2777 return RValue::get(Builder.CreateStore(HalfVal, Address));
2778 }
2779 case Builtin::BI__builtin_load_half: {
2780 Address Address = EmitPointerWithAlignment(E->getArg(0));
2781 Value *HalfVal = Builder.CreateLoad(Address);
2782 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy()));
2783 }
2784 case Builtin::BI__builtin_load_halff: {
2785 Address Address = EmitPointerWithAlignment(E->getArg(0));
2786 Value *HalfVal = Builder.CreateLoad(Address);
2787 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy()));
2788 }
Justin Lebar3039a592016-01-23 21:28:14 +00002789 case Builtin::BIprintf:
Arpith Chacko Jacobcdda3daa2017-01-29 20:49:31 +00002790 if (getTarget().getTriple().isNVPTX())
2791 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue);
Matt Arsenault2d933982016-02-27 09:06:18 +00002792 break;
2793 case Builtin::BI__builtin_canonicalize:
2794 case Builtin::BI__builtin_canonicalizef:
2795 case Builtin::BI__builtin_canonicalizel:
2796 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize));
Marcin Koscielnickia46fade2016-06-16 13:41:54 +00002797
2798 case Builtin::BI__builtin_thread_pointer: {
2799 if (!getContext().getTargetInfo().isTLSSupported())
2800 CGM.ErrorUnsupported(E, "__builtin_thread_pointer");
2801 // Fall through - it's already mapped to the intrinsic by GCCBuiltin.
2802 break;
2803 }
Mehdi Amini06d367c2016-10-24 20:39:34 +00002804 case Builtin::BI__builtin_os_log_format: {
2805 assert(E->getNumArgs() >= 2 &&
2806 "__builtin_os_log_format takes at least 2 arguments");
2807 analyze_os_log::OSLogBufferLayout Layout;
2808 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);
2809 Address BufAddr = EmitPointerWithAlignment(E->getArg(0));
2810 // Ignore argument 1, the format string. It is not currently used.
2811 CharUnits Offset;
2812 Builder.CreateStore(
2813 Builder.getInt8(Layout.getSummaryByte()),
2814 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary"));
2815 Builder.CreateStore(
2816 Builder.getInt8(Layout.getNumArgsByte()),
2817 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs"));
2818
2819 llvm::SmallVector<llvm::Value *, 4> RetainableOperands;
2820 for (const auto &Item : Layout.Items) {
2821 Builder.CreateStore(
2822 Builder.getInt8(Item.getDescriptorByte()),
2823 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor"));
2824 Builder.CreateStore(
2825 Builder.getInt8(Item.getSizeByte()),
2826 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize"));
2827 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset);
2828 if (const Expr *TheExpr = Item.getExpr()) {
2829 Addr = Builder.CreateElementBitCast(
2830 Addr, ConvertTypeForMem(TheExpr->getType()));
2831 // Check if this is a retainable type.
2832 if (TheExpr->getType()->isObjCRetainableType()) {
2833 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar &&
2834 "Only scalar can be a ObjC retainable type");
2835 llvm::Value *SV = EmitScalarExpr(TheExpr, /*Ignore*/ false);
2836 RValue RV = RValue::get(SV);
2837 LValue LV = MakeAddrLValue(Addr, TheExpr->getType());
2838 EmitStoreThroughLValue(RV, LV);
2839 // Check if the object is constant, if not, save it in
2840 // RetainableOperands.
2841 if (!isa<Constant>(SV))
2842 RetainableOperands.push_back(SV);
2843 } else {
2844 EmitAnyExprToMem(TheExpr, Addr, Qualifiers(), /*isInit*/ true);
2845 }
2846 } else {
2847 Addr = Builder.CreateElementBitCast(Addr, Int32Ty);
2848 Builder.CreateStore(
2849 Builder.getInt32(Item.getConstValue().getQuantity()), Addr);
2850 }
2851 Offset += Item.size();
2852 }
2853
2854 // Push a clang.arc.use cleanup for each object in RetainableOperands. The
2855 // cleanup will cause the use to appear after the final log call, keeping
Nico Weber050af672017-05-05 17:16:58 +00002856 // the object valid while it's held in the log buffer. Note that if there's
Mehdi Amini06d367c2016-10-24 20:39:34 +00002857 // a release cleanup on the object, it will already be active; since
2858 // cleanups are emitted in reverse order, the use will occur before the
2859 // object is released.
2860 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount &&
2861 CGM.getCodeGenOpts().OptimizationLevel != 0)
2862 for (llvm::Value *object : RetainableOperands)
2863 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), object);
2864
2865 return RValue::get(BufAddr.getPointer());
2866 }
2867
2868 case Builtin::BI__builtin_os_log_format_buffer_size: {
2869 analyze_os_log::OSLogBufferLayout Layout;
2870 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);
2871 return RValue::get(ConstantInt::get(ConvertType(E->getType()),
2872 Layout.size().getQuantity()));
2873 }
Dean Michael Berris42af6512017-05-09 00:45:40 +00002874
2875 case Builtin::BI__xray_customevent: {
2876 if (!ShouldXRayInstrumentFunction())
2877 return RValue::getIgnored();
2878 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
2879 if (XRayAttr->neverXRayInstrument())
2880 return RValue::getIgnored();
2881 }
2882 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
2883 auto FTy = F->getFunctionType();
2884 auto Arg0 = E->getArg(0);
2885 auto Arg0Val = EmitScalarExpr(Arg0);
2886 auto Arg0Ty = Arg0->getType();
2887 auto PTy0 = FTy->getParamType(0);
2888 if (PTy0 != Arg0Val->getType()) {
2889 if (Arg0Ty->isArrayType())
2890 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer();
2891 else
2892 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0);
2893 }
2894 auto Arg1 = EmitScalarExpr(E->getArg(1));
2895 auto PTy1 = FTy->getParamType(1);
2896 if (PTy1 != Arg1->getType())
2897 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
2898 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
2899 }
Martin Storsjo022e7822017-07-17 20:49:45 +00002900
2901 case Builtin::BI__builtin_ms_va_start:
2902 case Builtin::BI__builtin_ms_va_end:
2903 return RValue::get(
2904 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(),
2905 BuiltinID == Builtin::BI__builtin_ms_va_start));
2906
2907 case Builtin::BI__builtin_ms_va_copy: {
2908 // Lower this manually. We can't reliably determine whether or not any
2909 // given va_copy() is for a Win64 va_list from the calling convention
2910 // alone, because it's legal to do this from a System V ABI function.
2911 // With opaque pointer types, we won't have enough information in LLVM
2912 // IR to determine this from the argument types, either. Best to do it
2913 // now, while we have enough information.
2914 Address DestAddr = EmitMSVAListRef(E->getArg(0));
2915 Address SrcAddr = EmitMSVAListRef(E->getArg(1));
2916
2917 llvm::Type *BPP = Int8PtrPtrTy;
2918
2919 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"),
2920 DestAddr.getAlignment());
2921 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"),
2922 SrcAddr.getAlignment());
2923
2924 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val");
2925 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr));
2926 }
Nate Begeman6c591322008-05-15 07:38:03 +00002927 }
Mike Stump11289f42009-09-09 15:08:12 +00002928
John McCall30e4efd2011-09-13 23:05:03 +00002929 // If this is an alias for a lib function (e.g. __builtin_sin), emit
2930 // the call using the normal call path, but using the unmangled
2931 // version of the function name.
2932 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
2933 return emitLibraryCall(*this, FD, E,
2934 CGM.getBuiltinLibFunction(FD, BuiltinID));
Jim Grosbachd3608f42012-09-21 00:18:27 +00002935
John McCall30e4efd2011-09-13 23:05:03 +00002936 // If this is a predefined lib function (e.g. malloc), emit the call
2937 // using exactly the normal call path.
2938 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
John McCallb92ab1a2016-10-26 23:46:34 +00002939 return emitLibraryCall(*this, FD, E,
2940 cast<llvm::Constant>(EmitScalarExpr(E->getCallee())));
Mike Stump11289f42009-09-09 15:08:12 +00002941
Eric Christopher15709992015-10-15 23:47:11 +00002942 // Check that a call to a target specific builtin has the correct target
2943 // features.
2944 // This is down here to avoid non-target specific builtins, however, if
2945 // generic builtins start to require generic target features then we
2946 // can move this up to the beginning of the function.
Eric Christopherc7e79db2015-11-12 00:44:04 +00002947 checkTargetFeatures(E, FD);
Eric Christopher15709992015-10-15 23:47:11 +00002948
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002949 // See if we have a target specific intrinsic.
Mehdi Amini7186a432016-10-11 19:04:24 +00002950 const char *Name = getContext().BuiltinInfo.getName(BuiltinID);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002951 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
Mehdi Aminib7fb1242016-10-01 01:16:22 +00002952 StringRef Prefix =
2953 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
2954 if (!Prefix.empty()) {
2955 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00002956 // NOTE we dont need to perform a compatibility flag check here since the
2957 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
2958 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
2959 if (IntrinsicID == Intrinsic::not_intrinsic)
Mehdi Aminib7fb1242016-10-01 01:16:22 +00002960 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00002961 }
Mike Stump11289f42009-09-09 15:08:12 +00002962
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002963 if (IntrinsicID != Intrinsic::not_intrinsic) {
2964 SmallVector<Value*, 16> Args;
Mike Stump11289f42009-09-09 15:08:12 +00002965
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002966 // Find out if any arguments are required to be integer constant
2967 // expressions.
2968 unsigned ICEArguments = 0;
2969 ASTContext::GetBuiltinTypeError Error;
2970 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
2971 assert(Error == ASTContext::GE_None && "Should not codegen an error");
2972
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002973 Function *F = CGM.getIntrinsic(IntrinsicID);
Chris Lattner2192fe52011-07-18 04:24:23 +00002974 llvm::FunctionType *FTy = F->getFunctionType();
Mike Stump11289f42009-09-09 15:08:12 +00002975
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002976 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002977 Value *ArgValue;
2978 // If this is a normal argument, just emit it as a scalar.
2979 if ((ICEArguments & (1 << i)) == 0) {
2980 ArgValue = EmitScalarExpr(E->getArg(i));
2981 } else {
Jim Grosbachd3608f42012-09-21 00:18:27 +00002982 // If this is required to be a constant, constant fold it so that we
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002983 // know that the generated intrinsic gets a ConstantInt.
2984 llvm::APSInt Result;
2985 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext());
2986 assert(IsConst && "Constant arg isn't actually constant?");
2987 (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00002988 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result);
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002989 }
Mike Stump11289f42009-09-09 15:08:12 +00002990
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002991 // If the intrinsic arg type is different from the builtin arg type
2992 // we need to do a bit cast.
Chris Lattner2192fe52011-07-18 04:24:23 +00002993 llvm::Type *PTy = FTy->getParamType(i);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002994 if (PTy != ArgValue->getType()) {
2995 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
2996 "Must be able to losslessly bit cast to param");
2997 ArgValue = Builder.CreateBitCast(ArgValue, PTy);
2998 }
Mike Stump11289f42009-09-09 15:08:12 +00002999
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003000 Args.push_back(ArgValue);
3001 }
Mike Stump11289f42009-09-09 15:08:12 +00003002
Jay Foad5bd375a2011-07-15 08:37:34 +00003003 Value *V = Builder.CreateCall(F, Args);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003004 QualType BuiltinRetType = E->getType();
Mike Stump11289f42009-09-09 15:08:12 +00003005
Chris Lattnerece04092012-02-07 00:39:47 +00003006 llvm::Type *RetTy = VoidTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00003007 if (!BuiltinRetType->isVoidType())
Chris Lattnerece04092012-02-07 00:39:47 +00003008 RetTy = ConvertType(BuiltinRetType);
Mike Stump11289f42009-09-09 15:08:12 +00003009
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003010 if (RetTy != V->getType()) {
3011 assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
3012 "Must be able to losslessly bit cast result type");
3013 V = Builder.CreateBitCast(V, RetTy);
3014 }
Mike Stump11289f42009-09-09 15:08:12 +00003015
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003016 return RValue::get(V);
3017 }
Mike Stump11289f42009-09-09 15:08:12 +00003018
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003019 // See if we have a target specific builtin that needs to be lowered.
Daniel Dunbareca513d2008-10-10 00:24:54 +00003020 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003021 return RValue::get(V);
Mike Stump11289f42009-09-09 15:08:12 +00003022
Daniel Dunbara7c8cf62008-08-16 00:56:44 +00003023 ErrorUnsupported(E, "builtin function");
Mike Stump11289f42009-09-09 15:08:12 +00003024
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003025 // Unknown builtin, for now just dump it out and return undef.
John McCall47fb9502013-03-07 21:37:08 +00003026 return GetUndefRValue(E->getType());
Mike Stump11289f42009-09-09 15:08:12 +00003027}
Anders Carlsson895af082007-12-09 23:17:02 +00003028
Artem Belevichb5bc9232015-09-22 17:23:22 +00003029static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
3030 unsigned BuiltinID, const CallExpr *E,
3031 llvm::Triple::ArchType Arch) {
3032 switch (Arch) {
Chris Lattner5cc15e02010-03-03 19:03:45 +00003033 case llvm::Triple::arm:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003034 case llvm::Triple::armeb:
Chris Lattner5cc15e02010-03-03 19:03:45 +00003035 case llvm::Triple::thumb:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003036 case llvm::Triple::thumbeb:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003037 return CGF->EmitARMBuiltinExpr(BuiltinID, E);
Tim Northover25e8a672014-05-24 12:51:25 +00003038 case llvm::Triple::aarch64:
3039 case llvm::Triple::aarch64_be:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003040 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003041 case llvm::Triple::x86:
3042 case llvm::Triple::x86_64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003043 return CGF->EmitX86BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003044 case llvm::Triple::ppc:
3045 case llvm::Triple::ppc64:
Bill Schmidt778d3872013-07-26 01:36:11 +00003046 case llvm::Triple::ppc64le:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003047 return CGF->EmitPPCBuiltinExpr(BuiltinID, E);
Matt Arsenault56f008d2014-06-24 20:45:01 +00003048 case llvm::Triple::r600:
Tom Stellardd8e38a32015-01-06 20:34:47 +00003049 case llvm::Triple::amdgcn:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003050 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00003051 case llvm::Triple::systemz:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003052 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00003053 case llvm::Triple::nvptx:
3054 case llvm::Triple::nvptx64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003055 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E);
Dan Gohmanc2853072015-09-03 22:51:53 +00003056 case llvm::Triple::wasm32:
3057 case llvm::Triple::wasm64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003058 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003059 default:
Craig Topper8a13c412014-05-21 05:09:00 +00003060 return nullptr;
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003061 }
Daniel Dunbareca513d2008-10-10 00:24:54 +00003062}
3063
Artem Belevichb5bc9232015-09-22 17:23:22 +00003064Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
3065 const CallExpr *E) {
3066 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3067 assert(getContext().getAuxTargetInfo() && "Missing aux target info");
3068 return EmitTargetArchBuiltinExpr(
3069 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E,
3070 getContext().getAuxTargetInfo()->getTriple().getArch());
3071 }
3072
3073 return EmitTargetArchBuiltinExpr(this, BuiltinID, E,
3074 getTarget().getTriple().getArch());
3075}
3076
Chris Lattnerece04092012-02-07 00:39:47 +00003077static llvm::VectorType *GetNeonType(CodeGenFunction *CGF,
Jiangning Liu036f16d2013-09-24 02:48:06 +00003078 NeonTypeFlags TypeFlags,
3079 bool V1Ty=false) {
NAKAMURA Takumidabda6b2011-11-08 03:27:04 +00003080 int IsQuad = TypeFlags.isQuad();
3081 switch (TypeFlags.getEltType()) {
Bob Wilson98bc98c2011-11-08 01:16:11 +00003082 case NeonTypeFlags::Int8:
3083 case NeonTypeFlags::Poly8:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003084 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003085 case NeonTypeFlags::Int16:
3086 case NeonTypeFlags::Poly16:
Abderrazek Zaafranif10ca932017-06-20 18:54:57 +00003087 case NeonTypeFlags::Float16:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003088 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003089 case NeonTypeFlags::Int32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003090 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003091 case NeonTypeFlags::Int64:
Kevin Qincaac85e2013-11-14 03:29:16 +00003092 case NeonTypeFlags::Poly64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003093 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad));
Kevin Qinfb79d7f2013-12-10 06:49:01 +00003094 case NeonTypeFlags::Poly128:
3095 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm.
3096 // There is a lot of i128 and f128 API missing.
3097 // so we use v16i8 to represent poly128 and get pattern matched.
3098 return llvm::VectorType::get(CGF->Int8Ty, 16);
Bob Wilson98bc98c2011-11-08 01:16:11 +00003099 case NeonTypeFlags::Float32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003100 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad));
Tim Northover2fe823a2013-08-01 09:23:19 +00003101 case NeonTypeFlags::Float64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003102 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad));
David Blaikief47fa302012-01-17 02:30:50 +00003103 }
Benjamin Kramer9b1dfe82013-09-26 16:36:08 +00003104 llvm_unreachable("Unknown vector element type!");
Nate Begeman5968eb22010-06-07 16:01:56 +00003105}
3106
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003107static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF,
3108 NeonTypeFlags IntTypeFlags) {
3109 int IsQuad = IntTypeFlags.isQuad();
3110 switch (IntTypeFlags.getEltType()) {
3111 case NeonTypeFlags::Int32:
3112 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad));
3113 case NeonTypeFlags::Int64:
3114 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad));
3115 default:
3116 llvm_unreachable("Type can't be converted to floating-point!");
3117 }
3118}
3119
Bob Wilson210f6dd2010-12-07 22:40:02 +00003120Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) {
Craig Topperf2f1a092016-07-08 02:17:35 +00003121 unsigned nElts = V->getType()->getVectorNumElements();
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003122 Value* SV = llvm::ConstantVector::getSplat(nElts, C);
Nate Begeman4a04b462010-06-10 00:17:56 +00003123 return Builder.CreateShuffleVector(V, V, SV, "lane");
3124}
3125
Nate Begemanae6b1d82010-06-08 06:03:01 +00003126Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops,
Bob Wilson482afae2010-12-08 22:37:56 +00003127 const char *name,
Nate Begeman91e1fea2010-06-14 05:21:25 +00003128 unsigned shift, bool rightshift) {
Nate Begemanae6b1d82010-06-08 06:03:01 +00003129 unsigned j = 0;
3130 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3131 ai != ae; ++ai, ++j)
Nate Begeman91e1fea2010-06-14 05:21:25 +00003132 if (shift > 0 && shift == j)
3133 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift);
3134 else
3135 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003136
Jay Foad5bd375a2011-07-15 08:37:34 +00003137 return Builder.CreateCall(F, Ops, name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003138}
3139
Jim Grosbachd3608f42012-09-21 00:18:27 +00003140Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty,
Nate Begeman8ed060b2010-06-11 22:57:12 +00003141 bool neg) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003142 int SV = cast<ConstantInt>(V)->getSExtValue();
Benjamin Kramerc385a802015-07-28 15:40:11 +00003143 return ConstantInt::get(Ty, neg ? -SV : SV);
Nate Begeman8ed060b2010-06-11 22:57:12 +00003144}
3145
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003146// \brief Right-shift a vector by a constant.
3147Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift,
3148 llvm::Type *Ty, bool usgn,
3149 const char *name) {
3150 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
3151
3152 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue();
3153 int EltSize = VTy->getScalarSizeInBits();
3154
3155 Vec = Builder.CreateBitCast(Vec, Ty);
3156
3157 // lshr/ashr are undefined when the shift amount is equal to the vector
3158 // element size.
3159 if (ShiftAmt == EltSize) {
3160 if (usgn) {
3161 // Right-shifting an unsigned value by its size yields 0.
Benjamin Kramerc385a802015-07-28 15:40:11 +00003162 return llvm::ConstantAggregateZero::get(VTy);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003163 } else {
3164 // Right-shifting a signed value by its size is equivalent
3165 // to a shift of size-1.
3166 --ShiftAmt;
3167 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt);
3168 }
3169 }
3170
3171 Shift = EmitNeonShiftVector(Shift, Ty, false);
3172 if (usgn)
3173 return Builder.CreateLShr(Vec, Shift, name);
3174 else
3175 return Builder.CreateAShr(Vec, Shift, name);
3176}
3177
Tim Northover2d837962014-02-21 11:57:20 +00003178enum {
3179 AddRetType = (1 << 0),
3180 Add1ArgType = (1 << 1),
3181 Add2ArgTypes = (1 << 2),
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003182
Tim Northover2d837962014-02-21 11:57:20 +00003183 VectorizeRetType = (1 << 3),
3184 VectorizeArgTypes = (1 << 4),
3185
3186 InventFloatType = (1 << 5),
Tim Northover8fe03d62014-02-21 11:57:24 +00003187 UnsignedAlts = (1 << 6),
Tim Northover2d837962014-02-21 11:57:20 +00003188
Tim Northovera2ee4332014-03-29 15:09:45 +00003189 Use64BitVectors = (1 << 7),
3190 Use128BitVectors = (1 << 8),
3191
Tim Northover2d837962014-02-21 11:57:20 +00003192 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes,
3193 VectorRet = AddRetType | VectorizeRetType,
3194 VectorRetGetArgs01 =
3195 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes,
3196 FpCmpzModifiers =
Tim Northovera0c95eb2014-02-21 12:16:59 +00003197 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003198};
3199
Benjamin Kramere003ca22015-10-28 13:54:16 +00003200namespace {
3201struct NeonIntrinsicInfo {
Ben Craigcd7e9f12015-12-14 21:54:11 +00003202 const char *NameHint;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003203 unsigned BuiltinID;
3204 unsigned LLVMIntrinsic;
Tim Northover8fe03d62014-02-21 11:57:24 +00003205 unsigned AltLLVMIntrinsic;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003206 unsigned TypeModifier;
3207
3208 bool operator<(unsigned RHSBuiltinID) const {
3209 return BuiltinID < RHSBuiltinID;
3210 }
Eric Christophered60b432015-11-11 02:04:08 +00003211 bool operator<(const NeonIntrinsicInfo &TE) const {
3212 return BuiltinID < TE.BuiltinID;
3213 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003214};
Benjamin Kramere003ca22015-10-28 13:54:16 +00003215} // end anonymous namespace
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003216
Tim Northover8fe03d62014-02-21 11:57:24 +00003217#define NEONMAP0(NameBase) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003218 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003219
Tim Northover8fe03d62014-02-21 11:57:24 +00003220#define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003221 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
3222 Intrinsic::LLVMIntrinsic, 0, TypeModifier }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003223
Tim Northover8fe03d62014-02-21 11:57:24 +00003224#define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003225 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
Tim Northover8fe03d62014-02-21 11:57:24 +00003226 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003227 TypeModifier }
Tim Northover8fe03d62014-02-21 11:57:24 +00003228
Craig Topper273dbc62015-10-18 05:29:26 +00003229static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = {
Tim Northover8fe03d62014-02-21 11:57:24 +00003230 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3231 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3232 NEONMAP1(vabs_v, arm_neon_vabs, 0),
3233 NEONMAP1(vabsq_v, arm_neon_vabs, 0),
3234 NEONMAP0(vaddhn_v),
3235 NEONMAP1(vaesdq_v, arm_neon_aesd, 0),
3236 NEONMAP1(vaeseq_v, arm_neon_aese, 0),
3237 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0),
3238 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0),
3239 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType),
3240 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType),
3241 NEONMAP1(vcage_v, arm_neon_vacge, 0),
3242 NEONMAP1(vcageq_v, arm_neon_vacge, 0),
3243 NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
3244 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
3245 NEONMAP1(vcale_v, arm_neon_vacge, 0),
3246 NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
3247 NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
3248 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
3249 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType),
3250 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType),
3251 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3252 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3253 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3254 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003255 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003256 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0),
3257 NEONMAP0(vcvt_f32_v),
3258 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3259 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3260 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3261 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3262 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3263 NEONMAP0(vcvt_s32_v),
3264 NEONMAP0(vcvt_s64_v),
3265 NEONMAP0(vcvt_u32_v),
3266 NEONMAP0(vcvt_u64_v),
3267 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
3268 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
3269 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
3270 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
3271 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
3272 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
3273 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
3274 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
3275 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
3276 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
3277 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
3278 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
3279 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
3280 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
3281 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
3282 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
3283 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
3284 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
3285 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
3286 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
3287 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
3288 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
3289 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
3290 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
3291 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
3292 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
3293 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
3294 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
3295 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
3296 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
3297 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
3298 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
3299 NEONMAP0(vcvtq_f32_v),
3300 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3301 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3302 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3303 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3304 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3305 NEONMAP0(vcvtq_s32_v),
3306 NEONMAP0(vcvtq_s64_v),
3307 NEONMAP0(vcvtq_u32_v),
3308 NEONMAP0(vcvtq_u64_v),
3309 NEONMAP0(vext_v),
3310 NEONMAP0(vextq_v),
3311 NEONMAP0(vfma_v),
3312 NEONMAP0(vfmaq_v),
3313 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3314 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3315 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3316 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3317 NEONMAP0(vld1_dup_v),
3318 NEONMAP1(vld1_v, arm_neon_vld1, 0),
3319 NEONMAP0(vld1q_dup_v),
3320 NEONMAP1(vld1q_v, arm_neon_vld1, 0),
3321 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
3322 NEONMAP1(vld2_v, arm_neon_vld2, 0),
3323 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
3324 NEONMAP1(vld2q_v, arm_neon_vld2, 0),
3325 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
3326 NEONMAP1(vld3_v, arm_neon_vld3, 0),
3327 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
3328 NEONMAP1(vld3q_v, arm_neon_vld3, 0),
3329 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
3330 NEONMAP1(vld4_v, arm_neon_vld4, 0),
3331 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
3332 NEONMAP1(vld4q_v, arm_neon_vld4, 0),
3333 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003334 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType),
3335 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003336 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
3337 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003338 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType),
3339 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003340 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
3341 NEONMAP0(vmovl_v),
3342 NEONMAP0(vmovn_v),
3343 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType),
3344 NEONMAP0(vmull_v),
3345 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType),
3346 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3347 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3348 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType),
3349 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3350 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3351 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType),
3352 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts),
3353 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts),
3354 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType),
3355 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType),
3356 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3357 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3358 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0),
3359 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0),
3360 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType),
3361 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType),
3362 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType),
3363 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts),
3364 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType),
3365 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType),
3366 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType),
3367 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType),
3368 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType),
3369 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3370 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3371 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3372 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
3373 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3374 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003375 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0),
3376 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003377 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3378 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3379 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType),
3380 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3381 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3382 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType),
3383 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType),
3384 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
3385 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003386 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType),
3387 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType),
3388 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType),
3389 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType),
3390 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType),
3391 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType),
3392 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType),
3393 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType),
3394 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType),
3395 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType),
3396 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType),
3397 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003398 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
3399 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003400 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
3401 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
Tim Northover8fe03d62014-02-21 11:57:24 +00003402 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3403 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3404 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType),
3405 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType),
3406 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType),
3407 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0),
3408 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0),
3409 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0),
3410 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0),
3411 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0),
3412 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0),
3413 NEONMAP0(vshl_n_v),
3414 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3415 NEONMAP0(vshll_n_v),
3416 NEONMAP0(vshlq_n_v),
3417 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3418 NEONMAP0(vshr_n_v),
3419 NEONMAP0(vshrn_n_v),
3420 NEONMAP0(vshrq_n_v),
3421 NEONMAP1(vst1_v, arm_neon_vst1, 0),
3422 NEONMAP1(vst1q_v, arm_neon_vst1, 0),
3423 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
3424 NEONMAP1(vst2_v, arm_neon_vst2, 0),
3425 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
3426 NEONMAP1(vst2q_v, arm_neon_vst2, 0),
3427 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
3428 NEONMAP1(vst3_v, arm_neon_vst3, 0),
3429 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
3430 NEONMAP1(vst3q_v, arm_neon_vst3, 0),
3431 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
3432 NEONMAP1(vst4_v, arm_neon_vst4, 0),
3433 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
3434 NEONMAP1(vst4q_v, arm_neon_vst4, 0),
3435 NEONMAP0(vsubhn_v),
3436 NEONMAP0(vtrn_v),
3437 NEONMAP0(vtrnq_v),
3438 NEONMAP0(vtst_v),
3439 NEONMAP0(vtstq_v),
3440 NEONMAP0(vuzp_v),
3441 NEONMAP0(vuzpq_v),
3442 NEONMAP0(vzip_v),
Tim Northovera0c95eb2014-02-21 12:16:59 +00003443 NEONMAP0(vzipq_v)
Tim Northover8fe03d62014-02-21 11:57:24 +00003444};
3445
Craig Topper273dbc62015-10-18 05:29:26 +00003446static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003447 NEONMAP1(vabs_v, aarch64_neon_abs, 0),
3448 NEONMAP1(vabsq_v, aarch64_neon_abs, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003449 NEONMAP0(vaddhn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003450 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0),
3451 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0),
3452 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0),
3453 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0),
3454 NEONMAP1(vcage_v, aarch64_neon_facge, 0),
3455 NEONMAP1(vcageq_v, aarch64_neon_facge, 0),
3456 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0),
3457 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0),
3458 NEONMAP1(vcale_v, aarch64_neon_facge, 0),
3459 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0),
3460 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0),
3461 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0),
3462 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType),
3463 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003464 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3465 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3466 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3467 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003468 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003469 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003470 NEONMAP0(vcvt_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003471 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3472 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3473 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3474 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3475 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3476 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003477 NEONMAP0(vcvtq_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003478 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3479 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3480 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3481 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3482 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3483 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
3484 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003485 NEONMAP0(vext_v),
3486 NEONMAP0(vextq_v),
3487 NEONMAP0(vfma_v),
3488 NEONMAP0(vfmaq_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003489 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3490 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3491 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
3492 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003493 NEONMAP0(vmovl_v),
3494 NEONMAP0(vmovn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003495 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType),
3496 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType),
3497 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType),
3498 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3499 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3500 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType),
3501 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType),
3502 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType),
3503 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3504 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3505 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0),
3506 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0),
3507 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType),
3508 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType),
3509 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType),
3510 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts),
3511 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType),
3512 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType),
3513 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType),
3514 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType),
3515 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType),
3516 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3517 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3518 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts),
3519 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
3520 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts),
3521 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003522 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0),
3523 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003524 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3525 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3526 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType),
3527 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3528 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3529 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType),
3530 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType),
3531 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3532 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3533 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
3534 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003535 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
3536 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
Tim Northover573cbee2014-05-24 12:52:07 +00003537 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3538 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3539 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType),
3540 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType),
3541 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType),
3542 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0),
3543 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0),
3544 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0),
3545 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0),
3546 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0),
3547 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003548 NEONMAP0(vshl_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003549 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003550 NEONMAP0(vshll_n_v),
3551 NEONMAP0(vshlq_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003552 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003553 NEONMAP0(vshr_n_v),
3554 NEONMAP0(vshrn_n_v),
3555 NEONMAP0(vshrq_n_v),
3556 NEONMAP0(vsubhn_v),
3557 NEONMAP0(vtst_v),
3558 NEONMAP0(vtstq_v),
3559};
3560
Craig Topper273dbc62015-10-18 05:29:26 +00003561static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003562 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType),
3563 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType),
3564 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType),
3565 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3566 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3567 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3568 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3569 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3570 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3571 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3572 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3573 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType),
3574 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3575 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType),
3576 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3577 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3578 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3579 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3580 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3581 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3582 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3583 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3584 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3585 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3586 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3587 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3588 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3589 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3590 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3591 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3592 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3593 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3594 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3595 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3596 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3597 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3598 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3599 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3600 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3601 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3602 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3603 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3604 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3605 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3606 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3607 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3608 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3609 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3610 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0),
3611 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3612 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3613 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3614 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3615 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3616 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3617 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3618 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3619 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3620 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3621 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3622 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3623 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3624 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3625 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3626 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3627 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3628 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3629 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3630 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3631 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0),
3632 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType),
3633 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType),
3634 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3635 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3636 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3637 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3638 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3639 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3640 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3641 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3642 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3643 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3644 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3645 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType),
3646 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3647 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType),
3648 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3649 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3650 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType),
3651 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType),
3652 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3653 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3654 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType),
3655 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType),
3656 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors),
3657 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType),
3658 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors),
3659 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0),
3660 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType),
3661 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType),
3662 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3663 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3664 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3665 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3666 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType),
3667 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3668 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3669 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3670 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType),
3671 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3672 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType),
3673 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors),
3674 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType),
3675 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3676 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3677 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType),
3678 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType),
3679 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3680 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3681 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType),
3682 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType),
3683 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType),
3684 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType),
3685 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3686 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3687 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3688 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3689 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType),
3690 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3691 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3692 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3693 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3694 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3695 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3696 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType),
3697 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType),
3698 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3699 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3700 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3701 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3702 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType),
3703 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType),
3704 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType),
3705 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType),
3706 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3707 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3708 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType),
3709 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType),
3710 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType),
3711 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3712 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3713 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3714 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3715 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType),
3716 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3717 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3718 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3719 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3720 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType),
3721 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType),
3722 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3723 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3724 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType),
3725 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType),
3726 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType),
3727 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType),
3728 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType),
3729 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType),
3730 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType),
3731 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType),
3732 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType),
3733 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType),
3734 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType),
3735 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType),
3736 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0),
3737 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0),
3738 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0),
3739 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0),
3740 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType),
3741 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType),
3742 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType),
3743 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType),
3744 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3745 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType),
3746 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3747 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType),
3748 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType),
3749 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType),
3750 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3751 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType),
3752 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3753 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003754};
3755
Tim Northover8fe03d62014-02-21 11:57:24 +00003756#undef NEONMAP0
3757#undef NEONMAP1
3758#undef NEONMAP2
3759
3760static bool NEONSIMDIntrinsicsProvenSorted = false;
Tim Northover8fe03d62014-02-21 11:57:24 +00003761
Tim Northover573cbee2014-05-24 12:52:07 +00003762static bool AArch64SIMDIntrinsicsProvenSorted = false;
3763static bool AArch64SISDIntrinsicsProvenSorted = false;
Tim Northovera2ee4332014-03-29 15:09:45 +00003764
3765
Tim Northover8fe03d62014-02-21 11:57:24 +00003766static const NeonIntrinsicInfo *
Craig Topper00bbdcf2014-06-28 23:22:23 +00003767findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
Tim Northover8fe03d62014-02-21 11:57:24 +00003768 unsigned BuiltinID, bool &MapProvenSorted) {
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003769
3770#ifndef NDEBUG
Tim Northover8fe03d62014-02-21 11:57:24 +00003771 if (!MapProvenSorted) {
Eric Christophered60b432015-11-11 02:04:08 +00003772 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap)));
Tim Northover8fe03d62014-02-21 11:57:24 +00003773 MapProvenSorted = true;
3774 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003775#endif
3776
Tim Northover8fe03d62014-02-21 11:57:24 +00003777 const NeonIntrinsicInfo *Builtin =
3778 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID);
3779
3780 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID)
3781 return Builtin;
3782
Craig Topper8a13c412014-05-21 05:09:00 +00003783 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003784}
3785
3786Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
3787 unsigned Modifier,
3788 llvm::Type *ArgType,
3789 const CallExpr *E) {
Tim Northovera2ee4332014-03-29 15:09:45 +00003790 int VectorSize = 0;
3791 if (Modifier & Use64BitVectors)
3792 VectorSize = 64;
3793 else if (Modifier & Use128BitVectors)
3794 VectorSize = 128;
3795
Tim Northover2d837962014-02-21 11:57:20 +00003796 // Return type.
3797 SmallVector<llvm::Type *, 3> Tys;
3798 if (Modifier & AddRetType) {
David Majnemerced8bdf2015-02-25 17:36:15 +00003799 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northover2d837962014-02-21 11:57:20 +00003800 if (Modifier & VectorizeRetType)
Tim Northovera2ee4332014-03-29 15:09:45 +00003801 Ty = llvm::VectorType::get(
3802 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1);
Tim Northover2d837962014-02-21 11:57:20 +00003803
3804 Tys.push_back(Ty);
3805 }
3806
3807 // Arguments.
Tim Northovera2ee4332014-03-29 15:09:45 +00003808 if (Modifier & VectorizeArgTypes) {
3809 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1;
3810 ArgType = llvm::VectorType::get(ArgType, Elts);
3811 }
Tim Northover2d837962014-02-21 11:57:20 +00003812
3813 if (Modifier & (Add1ArgType | Add2ArgTypes))
3814 Tys.push_back(ArgType);
3815
3816 if (Modifier & Add2ArgTypes)
3817 Tys.push_back(ArgType);
3818
3819 if (Modifier & InventFloatType)
3820 Tys.push_back(FloatTy);
3821
3822 return CGM.getIntrinsic(IntrinsicID, Tys);
3823}
3824
Tim Northovera2ee4332014-03-29 15:09:45 +00003825static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF,
3826 const NeonIntrinsicInfo &SISDInfo,
3827 SmallVectorImpl<Value *> &Ops,
3828 const CallExpr *E) {
Tim Northover0c68faa2014-03-31 15:47:09 +00003829 unsigned BuiltinID = SISDInfo.BuiltinID;
Tim Northovera2ee4332014-03-29 15:09:45 +00003830 unsigned int Int = SISDInfo.LLVMIntrinsic;
3831 unsigned Modifier = SISDInfo.TypeModifier;
3832 const char *s = SISDInfo.NameHint;
3833
Tim Northover0c68faa2014-03-31 15:47:09 +00003834 switch (BuiltinID) {
3835 case NEON::BI__builtin_neon_vcled_s64:
3836 case NEON::BI__builtin_neon_vcled_u64:
3837 case NEON::BI__builtin_neon_vcles_f32:
3838 case NEON::BI__builtin_neon_vcled_f64:
3839 case NEON::BI__builtin_neon_vcltd_s64:
3840 case NEON::BI__builtin_neon_vcltd_u64:
3841 case NEON::BI__builtin_neon_vclts_f32:
3842 case NEON::BI__builtin_neon_vcltd_f64:
3843 case NEON::BI__builtin_neon_vcales_f32:
3844 case NEON::BI__builtin_neon_vcaled_f64:
3845 case NEON::BI__builtin_neon_vcalts_f32:
3846 case NEON::BI__builtin_neon_vcaltd_f64:
3847 // Only one direction of comparisons actually exist, cmle is actually a cmge
3848 // with swapped operands. The table gives us the right intrinsic but we
3849 // still need to do the swap.
3850 std::swap(Ops[0], Ops[1]);
3851 break;
3852 }
3853
Tim Northovera2ee4332014-03-29 15:09:45 +00003854 assert(Int && "Generic code assumes a valid intrinsic");
3855
3856 // Determine the type(s) of this overloaded AArch64 intrinsic.
3857 const Expr *Arg = E->getArg(0);
3858 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType());
3859 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E);
3860
3861 int j = 0;
Michael J. Spencerdd597752014-05-31 00:22:12 +00003862 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00003863 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3864 ai != ae; ++ai, ++j) {
3865 llvm::Type *ArgTy = ai->getType();
3866 if (Ops[j]->getType()->getPrimitiveSizeInBits() ==
3867 ArgTy->getPrimitiveSizeInBits())
3868 continue;
3869
3870 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy());
3871 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate
3872 // it before inserting.
3873 Ops[j] =
3874 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType());
3875 Ops[j] =
3876 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0);
3877 }
3878
3879 Value *Result = CGF.EmitNeonCall(F, Ops, s);
3880 llvm::Type *ResultType = CGF.ConvertType(E->getType());
3881 if (ResultType->getPrimitiveSizeInBits() <
3882 Result->getType()->getPrimitiveSizeInBits())
3883 return CGF.Builder.CreateExtractElement(Result, C0);
3884
3885 return CGF.Builder.CreateBitCast(Result, ResultType, s);
3886}
Tim Northover8fe03d62014-02-21 11:57:24 +00003887
Tim Northover8fe03d62014-02-21 11:57:24 +00003888Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
3889 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic,
3890 const char *NameHint, unsigned Modifier, const CallExpr *E,
John McCall7f416cc2015-09-08 08:05:57 +00003891 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) {
Tim Northover8fe03d62014-02-21 11:57:24 +00003892 // Get the last argument, which specifies the vector type.
3893 llvm::APSInt NeonTypeConst;
3894 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
3895 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00003896 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003897
3898 // Determine the type of this overloaded NEON intrinsic.
3899 NeonTypeFlags Type(NeonTypeConst.getZExtValue());
3900 bool Usgn = Type.isUnsigned();
3901 bool Quad = Type.isQuad();
3902
3903 llvm::VectorType *VTy = GetNeonType(this, Type);
3904 llvm::Type *Ty = VTy;
3905 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00003906 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003907
John McCall7f416cc2015-09-08 08:05:57 +00003908 auto getAlignmentValue32 = [&](Address addr) -> Value* {
3909 return Builder.getInt32(addr.getAlignment().getQuantity());
3910 };
3911
Tim Northover8fe03d62014-02-21 11:57:24 +00003912 unsigned Int = LLVMIntrinsic;
3913 if ((Modifier & UnsignedAlts) && !Usgn)
3914 Int = AltLLVMIntrinsic;
3915
3916 switch (BuiltinID) {
3917 default: break;
3918 case NEON::BI__builtin_neon_vabs_v:
3919 case NEON::BI__builtin_neon_vabsq_v:
3920 if (VTy->getElementType()->isFloatingPointTy())
3921 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs");
3922 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs");
3923 case NEON::BI__builtin_neon_vaddhn_v: {
3924 llvm::VectorType *SrcTy =
3925 llvm::VectorType::getExtendedElementVectorType(VTy);
3926
3927 // %sum = add <4 x i32> %lhs, %rhs
3928 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
3929 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
3930 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn");
3931
3932 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00003933 Constant *ShiftAmt =
3934 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00003935 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn");
3936
3937 // %res = trunc <4 x i32> %high to <4 x i16>
3938 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn");
3939 }
3940 case NEON::BI__builtin_neon_vcale_v:
3941 case NEON::BI__builtin_neon_vcaleq_v:
3942 case NEON::BI__builtin_neon_vcalt_v:
3943 case NEON::BI__builtin_neon_vcaltq_v:
3944 std::swap(Ops[0], Ops[1]);
Galina Kistanova0872d6c2017-06-03 06:30:46 +00003945 LLVM_FALLTHROUGH;
Tim Northover8fe03d62014-02-21 11:57:24 +00003946 case NEON::BI__builtin_neon_vcage_v:
3947 case NEON::BI__builtin_neon_vcageq_v:
3948 case NEON::BI__builtin_neon_vcagt_v:
3949 case NEON::BI__builtin_neon_vcagtq_v: {
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003950 llvm::Type *VecFlt = llvm::VectorType::get(
3951 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy,
3952 VTy->getNumElements());
Tim Northover8fe03d62014-02-21 11:57:24 +00003953 llvm::Type *Tys[] = { VTy, VecFlt };
3954 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
3955 return EmitNeonCall(F, Ops, NameHint);
3956 }
3957 case NEON::BI__builtin_neon_vclz_v:
3958 case NEON::BI__builtin_neon_vclzq_v:
3959 // We generate target-independent intrinsic, which needs a second argument
3960 // for whether or not clz of zero is undefined; on ARM it isn't.
3961 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef()));
3962 break;
3963 case NEON::BI__builtin_neon_vcvt_f32_v:
3964 case NEON::BI__builtin_neon_vcvtq_f32_v:
3965 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
3966 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad));
3967 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
3968 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
3969 case NEON::BI__builtin_neon_vcvt_n_f32_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00003970 case NEON::BI__builtin_neon_vcvt_n_f64_v:
3971 case NEON::BI__builtin_neon_vcvtq_n_f32_v:
3972 case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003973 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty };
Tim Northover8fe03d62014-02-21 11:57:24 +00003974 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
3975 Function *F = CGM.getIntrinsic(Int, Tys);
3976 return EmitNeonCall(F, Ops, "vcvt_n");
3977 }
3978 case NEON::BI__builtin_neon_vcvt_n_s32_v:
3979 case NEON::BI__builtin_neon_vcvt_n_u32_v:
3980 case NEON::BI__builtin_neon_vcvt_n_s64_v:
3981 case NEON::BI__builtin_neon_vcvt_n_u64_v:
3982 case NEON::BI__builtin_neon_vcvtq_n_s32_v:
3983 case NEON::BI__builtin_neon_vcvtq_n_u32_v:
3984 case NEON::BI__builtin_neon_vcvtq_n_s64_v:
3985 case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003986 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00003987 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
3988 return EmitNeonCall(F, Ops, "vcvt_n");
3989 }
3990 case NEON::BI__builtin_neon_vcvt_s32_v:
3991 case NEON::BI__builtin_neon_vcvt_u32_v:
3992 case NEON::BI__builtin_neon_vcvt_s64_v:
3993 case NEON::BI__builtin_neon_vcvt_u64_v:
3994 case NEON::BI__builtin_neon_vcvtq_s32_v:
3995 case NEON::BI__builtin_neon_vcvtq_u32_v:
3996 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003997 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003998 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northover8fe03d62014-02-21 11:57:24 +00003999 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt")
4000 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
4001 }
4002 case NEON::BI__builtin_neon_vcvta_s32_v:
4003 case NEON::BI__builtin_neon_vcvta_s64_v:
4004 case NEON::BI__builtin_neon_vcvta_u32_v:
4005 case NEON::BI__builtin_neon_vcvta_u64_v:
4006 case NEON::BI__builtin_neon_vcvtaq_s32_v:
4007 case NEON::BI__builtin_neon_vcvtaq_s64_v:
4008 case NEON::BI__builtin_neon_vcvtaq_u32_v:
4009 case NEON::BI__builtin_neon_vcvtaq_u64_v:
4010 case NEON::BI__builtin_neon_vcvtn_s32_v:
4011 case NEON::BI__builtin_neon_vcvtn_s64_v:
4012 case NEON::BI__builtin_neon_vcvtn_u32_v:
4013 case NEON::BI__builtin_neon_vcvtn_u64_v:
4014 case NEON::BI__builtin_neon_vcvtnq_s32_v:
4015 case NEON::BI__builtin_neon_vcvtnq_s64_v:
4016 case NEON::BI__builtin_neon_vcvtnq_u32_v:
4017 case NEON::BI__builtin_neon_vcvtnq_u64_v:
4018 case NEON::BI__builtin_neon_vcvtp_s32_v:
4019 case NEON::BI__builtin_neon_vcvtp_s64_v:
4020 case NEON::BI__builtin_neon_vcvtp_u32_v:
4021 case NEON::BI__builtin_neon_vcvtp_u64_v:
4022 case NEON::BI__builtin_neon_vcvtpq_s32_v:
4023 case NEON::BI__builtin_neon_vcvtpq_s64_v:
4024 case NEON::BI__builtin_neon_vcvtpq_u32_v:
4025 case NEON::BI__builtin_neon_vcvtpq_u64_v:
4026 case NEON::BI__builtin_neon_vcvtm_s32_v:
4027 case NEON::BI__builtin_neon_vcvtm_s64_v:
4028 case NEON::BI__builtin_neon_vcvtm_u32_v:
4029 case NEON::BI__builtin_neon_vcvtm_u64_v:
4030 case NEON::BI__builtin_neon_vcvtmq_s32_v:
4031 case NEON::BI__builtin_neon_vcvtmq_s64_v:
4032 case NEON::BI__builtin_neon_vcvtmq_u32_v:
4033 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004034 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00004035 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
4036 }
4037 case NEON::BI__builtin_neon_vext_v:
4038 case NEON::BI__builtin_neon_vextq_v: {
4039 int CV = cast<ConstantInt>(Ops[2])->getSExtValue();
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004040 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004041 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00004042 Indices.push_back(i+CV);
Tim Northover8fe03d62014-02-21 11:57:24 +00004043
4044 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4045 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Craig Topper832caf02016-05-29 02:39:30 +00004046 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext");
Tim Northover8fe03d62014-02-21 11:57:24 +00004047 }
4048 case NEON::BI__builtin_neon_vfma_v:
4049 case NEON::BI__builtin_neon_vfmaq_v: {
4050 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
4051 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4052 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4053 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
4054
4055 // NEON intrinsic puts accumulator first, unlike the LLVM fma.
David Blaikie43f9bb72015-05-18 22:14:03 +00004056 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northover8fe03d62014-02-21 11:57:24 +00004057 }
4058 case NEON::BI__builtin_neon_vld1_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004059 case NEON::BI__builtin_neon_vld1q_v: {
4060 llvm::Type *Tys[] = {Ty, Int8PtrTy};
John McCall7f416cc2015-09-08 08:05:57 +00004061 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004062 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1");
4063 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004064 case NEON::BI__builtin_neon_vld2_v:
4065 case NEON::BI__builtin_neon_vld2q_v:
4066 case NEON::BI__builtin_neon_vld3_v:
4067 case NEON::BI__builtin_neon_vld3q_v:
4068 case NEON::BI__builtin_neon_vld4_v:
4069 case NEON::BI__builtin_neon_vld4q_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004070 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4071 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00004072 Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00004073 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004074 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4075 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004076 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004077 }
4078 case NEON::BI__builtin_neon_vld1_dup_v:
4079 case NEON::BI__builtin_neon_vld1q_dup_v: {
4080 Value *V = UndefValue::get(Ty);
4081 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00004082 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty);
4083 LoadInst *Ld = Builder.CreateLoad(PtrOp0);
Michael J. Spencerdd597752014-05-31 00:22:12 +00004084 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northover8fe03d62014-02-21 11:57:24 +00004085 Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
4086 return EmitNeonSplat(Ops[0], CI);
4087 }
4088 case NEON::BI__builtin_neon_vld2_lane_v:
4089 case NEON::BI__builtin_neon_vld2q_lane_v:
4090 case NEON::BI__builtin_neon_vld3_lane_v:
4091 case NEON::BI__builtin_neon_vld3q_lane_v:
4092 case NEON::BI__builtin_neon_vld4_lane_v:
4093 case NEON::BI__builtin_neon_vld4q_lane_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004094 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4095 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
Tim Northover8fe03d62014-02-21 11:57:24 +00004096 for (unsigned I = 2; I < Ops.size() - 1; ++I)
4097 Ops[I] = Builder.CreateBitCast(Ops[I], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004098 Ops.push_back(getAlignmentValue32(PtrOp1));
Tim Northover8fe03d62014-02-21 11:57:24 +00004099 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint);
4100 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4101 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004102 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004103 }
4104 case NEON::BI__builtin_neon_vmovl_v: {
4105 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy);
4106 Ops[0] = Builder.CreateBitCast(Ops[0], DTy);
4107 if (Usgn)
4108 return Builder.CreateZExt(Ops[0], Ty, "vmovl");
4109 return Builder.CreateSExt(Ops[0], Ty, "vmovl");
4110 }
4111 case NEON::BI__builtin_neon_vmovn_v: {
4112 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4113 Ops[0] = Builder.CreateBitCast(Ops[0], QTy);
4114 return Builder.CreateTrunc(Ops[0], Ty, "vmovn");
4115 }
4116 case NEON::BI__builtin_neon_vmull_v:
4117 // FIXME: the integer vmull operations could be emitted in terms of pure
4118 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of
4119 // hoisting the exts outside loops. Until global ISel comes along that can
4120 // see through such movement this leads to bad CodeGen. So we need an
4121 // intrinsic for now.
4122 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
4123 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
4124 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
4125 case NEON::BI__builtin_neon_vpadal_v:
4126 case NEON::BI__builtin_neon_vpadalq_v: {
4127 // The source operand type has twice as many elements of half the size.
4128 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4129 llvm::Type *EltTy =
4130 llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4131 llvm::Type *NarrowTy =
4132 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4133 llvm::Type *Tys[2] = { Ty, NarrowTy };
4134 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint);
4135 }
4136 case NEON::BI__builtin_neon_vpaddl_v:
4137 case NEON::BI__builtin_neon_vpaddlq_v: {
4138 // The source operand type has twice as many elements of half the size.
4139 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4140 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4141 llvm::Type *NarrowTy =
4142 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4143 llvm::Type *Tys[2] = { Ty, NarrowTy };
4144 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl");
4145 }
4146 case NEON::BI__builtin_neon_vqdmlal_v:
4147 case NEON::BI__builtin_neon_vqdmlsl_v: {
4148 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end());
Benjamin Kramerc385a802015-07-28 15:40:11 +00004149 Ops[1] =
4150 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal");
4151 Ops.resize(2);
4152 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004153 }
4154 case NEON::BI__builtin_neon_vqshl_n_v:
4155 case NEON::BI__builtin_neon_vqshlq_n_v:
4156 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n",
4157 1, false);
Yi Kong1083eb52014-07-29 09:25:17 +00004158 case NEON::BI__builtin_neon_vqshlu_n_v:
4159 case NEON::BI__builtin_neon_vqshluq_n_v:
4160 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n",
4161 1, false);
Tim Northover8fe03d62014-02-21 11:57:24 +00004162 case NEON::BI__builtin_neon_vrecpe_v:
4163 case NEON::BI__builtin_neon_vrecpeq_v:
4164 case NEON::BI__builtin_neon_vrsqrte_v:
4165 case NEON::BI__builtin_neon_vrsqrteq_v:
4166 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
4167 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint);
4168
Yi Kong1083eb52014-07-29 09:25:17 +00004169 case NEON::BI__builtin_neon_vrshr_n_v:
4170 case NEON::BI__builtin_neon_vrshrq_n_v:
4171 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n",
4172 1, true);
Tim Northover8fe03d62014-02-21 11:57:24 +00004173 case NEON::BI__builtin_neon_vshl_n_v:
4174 case NEON::BI__builtin_neon_vshlq_n_v:
4175 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
4176 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1],
4177 "vshl_n");
4178 case NEON::BI__builtin_neon_vshll_n_v: {
4179 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy);
4180 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4181 if (Usgn)
4182 Ops[0] = Builder.CreateZExt(Ops[0], VTy);
4183 else
4184 Ops[0] = Builder.CreateSExt(Ops[0], VTy);
4185 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false);
4186 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n");
4187 }
4188 case NEON::BI__builtin_neon_vshrn_n_v: {
4189 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4190 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4191 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false);
4192 if (Usgn)
4193 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]);
4194 else
4195 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]);
4196 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n");
4197 }
4198 case NEON::BI__builtin_neon_vshr_n_v:
4199 case NEON::BI__builtin_neon_vshrq_n_v:
4200 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n");
4201 case NEON::BI__builtin_neon_vst1_v:
4202 case NEON::BI__builtin_neon_vst1q_v:
4203 case NEON::BI__builtin_neon_vst2_v:
4204 case NEON::BI__builtin_neon_vst2q_v:
4205 case NEON::BI__builtin_neon_vst3_v:
4206 case NEON::BI__builtin_neon_vst3q_v:
4207 case NEON::BI__builtin_neon_vst4_v:
4208 case NEON::BI__builtin_neon_vst4q_v:
4209 case NEON::BI__builtin_neon_vst2_lane_v:
4210 case NEON::BI__builtin_neon_vst2q_lane_v:
4211 case NEON::BI__builtin_neon_vst3_lane_v:
4212 case NEON::BI__builtin_neon_vst3q_lane_v:
4213 case NEON::BI__builtin_neon_vst4_lane_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004214 case NEON::BI__builtin_neon_vst4q_lane_v: {
4215 llvm::Type *Tys[] = {Int8PtrTy, Ty};
John McCall7f416cc2015-09-08 08:05:57 +00004216 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004217 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
4218 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004219 case NEON::BI__builtin_neon_vsubhn_v: {
4220 llvm::VectorType *SrcTy =
4221 llvm::VectorType::getExtendedElementVectorType(VTy);
4222
4223 // %sum = add <4 x i32> %lhs, %rhs
4224 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4225 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
4226 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn");
4227
4228 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00004229 Constant *ShiftAmt =
4230 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00004231 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn");
4232
4233 // %res = trunc <4 x i32> %high to <4 x i16>
4234 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn");
4235 }
4236 case NEON::BI__builtin_neon_vtrn_v:
4237 case NEON::BI__builtin_neon_vtrnq_v: {
4238 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4239 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4240 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004241 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004242
4243 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004244 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004245 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004246 Indices.push_back(i+vi);
4247 Indices.push_back(i+e+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004248 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004249 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004250 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00004251 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004252 }
4253 return SV;
4254 }
4255 case NEON::BI__builtin_neon_vtst_v:
4256 case NEON::BI__builtin_neon_vtstq_v: {
4257 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4258 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4259 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
4260 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
4261 ConstantAggregateZero::get(Ty));
4262 return Builder.CreateSExt(Ops[0], Ty, "vtst");
4263 }
4264 case NEON::BI__builtin_neon_vuzp_v:
4265 case NEON::BI__builtin_neon_vuzpq_v: {
4266 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4267 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4268 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004269 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004270
4271 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004272 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004273 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00004274 Indices.push_back(2*i+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004275
David Blaikiefb901c7a2015-04-04 15:12:29 +00004276 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004277 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00004278 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004279 }
4280 return SV;
4281 }
4282 case NEON::BI__builtin_neon_vzip_v:
4283 case NEON::BI__builtin_neon_vzipq_v: {
4284 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4285 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4286 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004287 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004288
4289 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004290 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004291 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004292 Indices.push_back((i + vi*e) >> 1);
4293 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northover8fe03d62014-02-21 11:57:24 +00004294 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004295 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004296 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00004297 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004298 }
4299 return SV;
4300 }
4301 }
4302
4303 assert(Int && "Expected valid intrinsic number");
4304
4305 // Determine the type(s) of this overloaded AArch64 intrinsic.
4306 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E);
4307
4308 Value *Result = EmitNeonCall(F, Ops, NameHint);
4309 llvm::Type *ResultType = ConvertType(E->getType());
4310 // AArch64 intrinsic one-element vector type cast to
4311 // scalar type expected by the builtin
4312 return Builder.CreateBitCast(Result, ResultType, NameHint);
4313}
4314
Kevin Qin1718af62013-11-14 02:45:18 +00004315Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr(
4316 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp,
4317 const CmpInst::Predicate Ip, const Twine &Name) {
Tim Northovera2ee4332014-03-29 15:09:45 +00004318 llvm::Type *OTy = Op->getType();
4319
4320 // FIXME: this is utterly horrific. We should not be looking at previous
4321 // codegen context to find out what needs doing. Unfortunately TableGen
4322 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32
4323 // (etc).
4324 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op))
4325 OTy = BI->getOperand(0)->getType();
4326
Kevin Qin1718af62013-11-14 02:45:18 +00004327 Op = Builder.CreateBitCast(Op, OTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00004328 if (OTy->getScalarType()->isFloatingPointTy()) {
4329 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004330 } else {
Tim Northovera2ee4332014-03-29 15:09:45 +00004331 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004332 }
Hao Liuf96fd372013-12-23 02:44:00 +00004333 return Builder.CreateSExt(Op, Ty, Name);
Kevin Qin1718af62013-11-14 02:45:18 +00004334}
4335
Jiangning Liu18b707c2013-11-14 01:57:55 +00004336static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops,
4337 Value *ExtOp, Value *IndexOp,
4338 llvm::Type *ResTy, unsigned IntID,
4339 const char *Name) {
4340 SmallVector<Value *, 2> TblOps;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004341 if (ExtOp)
4342 TblOps.push_back(ExtOp);
4343
4344 // Build a vector containing sequential number like (0, 1, 2, ..., 15)
4345 SmallVector<uint32_t, 16> Indices;
4346 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType());
4347 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) {
Craig Topper832caf02016-05-29 02:39:30 +00004348 Indices.push_back(2*i);
4349 Indices.push_back(2*i+1);
Jiangning Liu18b707c2013-11-14 01:57:55 +00004350 }
Jiangning Liu18b707c2013-11-14 01:57:55 +00004351
4352 int PairPos = 0, End = Ops.size() - 1;
4353 while (PairPos < End) {
4354 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004355 Ops[PairPos+1], Indices,
4356 Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004357 PairPos += 2;
4358 }
4359
4360 // If there's an odd number of 64-bit lookup table, fill the high 64-bit
4361 // of the 128-bit lookup table with zero.
4362 if (PairPos == End) {
4363 Value *ZeroTbl = ConstantAggregateZero::get(TblTy);
4364 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004365 ZeroTbl, Indices, Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004366 }
4367
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004368 Function *TblF;
4369 TblOps.push_back(IndexOp);
4370 TblF = CGF.CGM.getIntrinsic(IntID, ResTy);
4371
4372 return CGF.EmitNeonCall(TblF, TblOps, Name);
4373}
4374
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004375Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) {
Benjamin Kramerc385a802015-07-28 15:40:11 +00004376 unsigned Value;
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004377 switch (BuiltinID) {
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004378 default:
4379 return nullptr;
Yi Kong4d5e23f2014-07-14 15:20:09 +00004380 case ARM::BI__builtin_arm_nop:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004381 Value = 0;
4382 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004383 case ARM::BI__builtin_arm_yield:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004384 case ARM::BI__yield:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004385 Value = 1;
4386 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004387 case ARM::BI__builtin_arm_wfe:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004388 case ARM::BI__wfe:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004389 Value = 2;
4390 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004391 case ARM::BI__builtin_arm_wfi:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004392 case ARM::BI__wfi:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004393 Value = 3;
4394 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004395 case ARM::BI__builtin_arm_sev:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004396 case ARM::BI__sev:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004397 Value = 4;
4398 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004399 case ARM::BI__builtin_arm_sevl:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004400 case ARM::BI__sevl:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004401 Value = 5;
4402 break;
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004403 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00004404
4405 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint),
4406 llvm::ConstantInt::get(Int32Ty, Value));
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004407}
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004408
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004409// Generates the IR for the read/write special register builtin,
4410// ValueType is the type of the value that is to be written or read,
4411// RegisterType is the type of the register being written to or read from.
4412static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF,
4413 const CallExpr *E,
4414 llvm::Type *RegisterType,
Matt Arsenault64665bc2016-06-28 00:13:17 +00004415 llvm::Type *ValueType,
4416 bool IsRead,
4417 StringRef SysReg = "") {
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004418 // write and register intrinsics only support 32 and 64 bit operations.
4419 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64))
4420 && "Unsupported size for register.");
4421
4422 CodeGen::CGBuilderTy &Builder = CGF.Builder;
4423 CodeGen::CodeGenModule &CGM = CGF.CGM;
4424 LLVMContext &Context = CGM.getLLVMContext();
4425
Matt Arsenault64665bc2016-06-28 00:13:17 +00004426 if (SysReg.empty()) {
4427 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts();
Zachary Turner26dab122016-12-13 17:10:16 +00004428 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString();
Matt Arsenault64665bc2016-06-28 00:13:17 +00004429 }
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004430
4431 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) };
4432 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4433 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4434
4435 llvm::Type *Types[] = { RegisterType };
4436
4437 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32);
4438 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64))
4439 && "Can't fit 64-bit value in 32-bit register");
4440
4441 if (IsRead) {
4442 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
4443 llvm::Value *Call = Builder.CreateCall(F, Metadata);
4444
4445 if (MixedTypes)
4446 // Read into 64 bit register and then truncate result to 32 bit.
4447 return Builder.CreateTrunc(Call, ValueType);
4448
4449 if (ValueType->isPointerTy())
4450 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*).
4451 return Builder.CreateIntToPtr(Call, ValueType);
4452
4453 return Call;
4454 }
4455
4456 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
4457 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1));
4458 if (MixedTypes) {
4459 // Extend 32 bit write value to 64 bit to pass to write.
4460 ArgValue = Builder.CreateZExt(ArgValue, RegisterType);
4461 return Builder.CreateCall(F, { Metadata, ArgValue });
4462 }
4463
4464 if (ValueType->isPointerTy()) {
4465 // Have VoidPtrTy ArgValue but want to return an i32/i64.
4466 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType);
4467 return Builder.CreateCall(F, { Metadata, ArgValue });
4468 }
4469
4470 return Builder.CreateCall(F, { Metadata, ArgValue });
4471}
4472
Bob Wilson63c93142015-06-24 06:05:20 +00004473/// Return true if BuiltinID is an overloaded Neon intrinsic with an extra
4474/// argument that specifies the vector type.
4475static bool HasExtraNeonArgument(unsigned BuiltinID) {
4476 switch (BuiltinID) {
4477 default: break;
4478 case NEON::BI__builtin_neon_vget_lane_i8:
4479 case NEON::BI__builtin_neon_vget_lane_i16:
4480 case NEON::BI__builtin_neon_vget_lane_i32:
4481 case NEON::BI__builtin_neon_vget_lane_i64:
4482 case NEON::BI__builtin_neon_vget_lane_f32:
4483 case NEON::BI__builtin_neon_vgetq_lane_i8:
4484 case NEON::BI__builtin_neon_vgetq_lane_i16:
4485 case NEON::BI__builtin_neon_vgetq_lane_i32:
4486 case NEON::BI__builtin_neon_vgetq_lane_i64:
4487 case NEON::BI__builtin_neon_vgetq_lane_f32:
4488 case NEON::BI__builtin_neon_vset_lane_i8:
4489 case NEON::BI__builtin_neon_vset_lane_i16:
4490 case NEON::BI__builtin_neon_vset_lane_i32:
4491 case NEON::BI__builtin_neon_vset_lane_i64:
4492 case NEON::BI__builtin_neon_vset_lane_f32:
4493 case NEON::BI__builtin_neon_vsetq_lane_i8:
4494 case NEON::BI__builtin_neon_vsetq_lane_i16:
4495 case NEON::BI__builtin_neon_vsetq_lane_i32:
4496 case NEON::BI__builtin_neon_vsetq_lane_i64:
4497 case NEON::BI__builtin_neon_vsetq_lane_f32:
4498 case NEON::BI__builtin_neon_vsha1h_u32:
4499 case NEON::BI__builtin_neon_vsha1cq_u32:
4500 case NEON::BI__builtin_neon_vsha1pq_u32:
4501 case NEON::BI__builtin_neon_vsha1mq_u32:
4502 case ARM::BI_MoveToCoprocessor:
4503 case ARM::BI_MoveToCoprocessor2:
4504 return false;
4505 }
4506 return true;
4507}
4508
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004509Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
4510 const CallExpr *E) {
4511 if (auto Hint = GetValueForARMHint(BuiltinID))
4512 return Hint;
Saleem Abdulrasool38ed6de2014-05-02 06:53:57 +00004513
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004514 if (BuiltinID == ARM::BI__emit) {
4515 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb;
4516 llvm::FunctionType *FTy =
4517 llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
4518
4519 APSInt Value;
4520 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
4521 llvm_unreachable("Sema will ensure that the parameter is constant");
4522
4523 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
4524
4525 llvm::InlineAsm *Emit =
4526 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "",
4527 /*SideEffects=*/true)
4528 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "",
4529 /*SideEffects=*/true);
4530
David Blaikie4ba525b2015-07-14 17:27:39 +00004531 return Builder.CreateCall(Emit);
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004532 }
4533
Yi Kong1d268af2014-08-26 12:48:06 +00004534 if (BuiltinID == ARM::BI__builtin_arm_dbg) {
4535 Value *Option = EmitScalarExpr(E->getArg(0));
4536 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
4537 }
4538
Yi Kong26d104a2014-08-13 19:18:14 +00004539 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
4540 Value *Address = EmitScalarExpr(E->getArg(0));
4541 Value *RW = EmitScalarExpr(E->getArg(1));
4542 Value *IsData = EmitScalarExpr(E->getArg(2));
4543
4544 // Locality is not supported on ARM target
4545 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3);
4546
4547 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00004548 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Kong26d104a2014-08-13 19:18:14 +00004549 }
4550
Jim Grosbach171ec342014-06-16 21:55:58 +00004551 if (BuiltinID == ARM::BI__builtin_arm_rbit) {
Chad Rosierc22abb32017-01-10 18:55:11 +00004552 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
4553 return Builder.CreateCall(
4554 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach171ec342014-06-16 21:55:58 +00004555 }
4556
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004557 if (BuiltinID == ARM::BI__clear_cache) {
Rafael Espindola2219fc52013-05-14 12:45:47 +00004558 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
Rafael Espindolaa54062e2010-06-07 17:26:50 +00004559 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00004560 Value *Ops[2];
Rafael Espindola2219fc52013-05-14 12:45:47 +00004561 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00004562 Ops[i] = EmitScalarExpr(E->getArg(i));
Chris Lattner2192fe52011-07-18 04:24:23 +00004563 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
4564 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004565 StringRef Name = FD->getName();
John McCall882987f2013-02-28 19:01:20 +00004566 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
Chris Lattner5cc15e02010-03-03 19:03:45 +00004567 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004568
Ranjeet Singhca2b3e7b2016-06-17 00:59:41 +00004569 if (BuiltinID == ARM::BI__builtin_arm_mcrr ||
4570 BuiltinID == ARM::BI__builtin_arm_mcrr2) {
4571 Function *F;
4572
4573 switch (BuiltinID) {
4574 default: llvm_unreachable("unexpected builtin");
4575 case ARM::BI__builtin_arm_mcrr:
4576 F = CGM.getIntrinsic(Intrinsic::arm_mcrr);
4577 break;
4578 case ARM::BI__builtin_arm_mcrr2:
4579 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2);
4580 break;
4581 }
4582
4583 // MCRR{2} instruction has 5 operands but
4584 // the intrinsic has 4 because Rt and Rt2
4585 // are represented as a single unsigned 64
4586 // bit integer in the intrinsic definition
4587 // but internally it's represented as 2 32
4588 // bit integers.
4589
4590 Value *Coproc = EmitScalarExpr(E->getArg(0));
4591 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4592 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2));
4593 Value *CRm = EmitScalarExpr(E->getArg(3));
4594
4595 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4596 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty);
4597 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1);
4598 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty);
4599
4600 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm});
4601 }
4602
4603 if (BuiltinID == ARM::BI__builtin_arm_mrrc ||
4604 BuiltinID == ARM::BI__builtin_arm_mrrc2) {
4605 Function *F;
4606
4607 switch (BuiltinID) {
4608 default: llvm_unreachable("unexpected builtin");
4609 case ARM::BI__builtin_arm_mrrc:
4610 F = CGM.getIntrinsic(Intrinsic::arm_mrrc);
4611 break;
4612 case ARM::BI__builtin_arm_mrrc2:
4613 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2);
4614 break;
4615 }
4616
4617 Value *Coproc = EmitScalarExpr(E->getArg(0));
4618 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4619 Value *CRm = EmitScalarExpr(E->getArg(2));
4620 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm});
4621
4622 // Returns an unsigned 64 bit integer, represented
4623 // as two 32 bit integers.
4624
4625 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1);
4626 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0);
4627 Rt = Builder.CreateZExt(Rt, Int64Ty);
4628 Rt1 = Builder.CreateZExt(Rt1, Int64Ty);
4629
4630 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32);
4631 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true);
4632 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1);
4633
4634 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType()));
4635 }
4636
Tim Northover6aacd492013-07-16 09:47:53 +00004637 if (BuiltinID == ARM::BI__builtin_arm_ldrexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004638 ((BuiltinID == ARM::BI__builtin_arm_ldrex ||
4639 BuiltinID == ARM::BI__builtin_arm_ldaex) &&
Saleem Abdulrasoole700cab2014-07-05 20:10:05 +00004640 getContext().getTypeSize(E->getType()) == 64) ||
4641 BuiltinID == ARM::BI__ldrexd) {
4642 Function *F;
4643
4644 switch (BuiltinID) {
4645 default: llvm_unreachable("unexpected builtin");
4646 case ARM::BI__builtin_arm_ldaex:
4647 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd);
4648 break;
4649 case ARM::BI__builtin_arm_ldrexd:
4650 case ARM::BI__builtin_arm_ldrex:
4651 case ARM::BI__ldrexd:
4652 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
4653 break;
4654 }
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004655
4656 Value *LdPtr = EmitScalarExpr(E->getArg(0));
Tim Northover6aacd492013-07-16 09:47:53 +00004657 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
4658 "ldrexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004659
4660 Value *Val0 = Builder.CreateExtractValue(Val, 1);
4661 Value *Val1 = Builder.CreateExtractValue(Val, 0);
4662 Val0 = Builder.CreateZExt(Val0, Int64Ty);
4663 Val1 = Builder.CreateZExt(Val1, Int64Ty);
4664
4665 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32);
4666 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
Tim Northover6aacd492013-07-16 09:47:53 +00004667 Val = Builder.CreateOr(Val, Val1);
4668 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004669 }
4670
Tim Northover3acd6bd2014-07-02 12:56:02 +00004671 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
4672 BuiltinID == ARM::BI__builtin_arm_ldaex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004673 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
4674
4675 QualType Ty = E->getType();
4676 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004677 llvm::Type *PtrTy = llvm::IntegerType::get(
4678 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
4679 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004680
Tim Northover3acd6bd2014-07-02 12:56:02 +00004681 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
4682 ? Intrinsic::arm_ldaex
4683 : Intrinsic::arm_ldrex,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004684 PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004685 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
4686
4687 if (RealResTy->isPointerTy())
4688 return Builder.CreateIntToPtr(Val, RealResTy);
4689 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004690 llvm::Type *IntResTy = llvm::IntegerType::get(
4691 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northover6aacd492013-07-16 09:47:53 +00004692 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
4693 return Builder.CreateBitCast(Val, RealResTy);
4694 }
4695 }
4696
4697 if (BuiltinID == ARM::BI__builtin_arm_strexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004698 ((BuiltinID == ARM::BI__builtin_arm_stlex ||
4699 BuiltinID == ARM::BI__builtin_arm_strex) &&
Tim Northover6aacd492013-07-16 09:47:53 +00004700 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00004701 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4702 ? Intrinsic::arm_stlexd
4703 : Intrinsic::arm_strexd);
Serge Guelton1d993272017-05-09 19:31:30 +00004704 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty);
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004705
John McCall7f416cc2015-09-08 08:05:57 +00004706 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004707 Value *Val = EmitScalarExpr(E->getArg(0));
4708 Builder.CreateStore(Val, Tmp);
4709
John McCall7f416cc2015-09-08 08:05:57 +00004710 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004711 Val = Builder.CreateLoad(LdPtr);
4712
4713 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
4714 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
Tim Northover6aacd492013-07-16 09:47:53 +00004715 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00004716 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004717 }
4718
Tim Northover3acd6bd2014-07-02 12:56:02 +00004719 if (BuiltinID == ARM::BI__builtin_arm_strex ||
4720 BuiltinID == ARM::BI__builtin_arm_stlex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004721 Value *StoreVal = EmitScalarExpr(E->getArg(0));
4722 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
4723
4724 QualType Ty = E->getArg(0)->getType();
4725 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
4726 getContext().getTypeSize(Ty));
4727 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
4728
4729 if (StoreVal->getType()->isPointerTy())
4730 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty);
4731 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004732 llvm::Type *IntTy = llvm::IntegerType::get(
4733 getLLVMContext(),
4734 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
4735 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004736 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
4737 }
4738
Tim Northover3acd6bd2014-07-02 12:56:02 +00004739 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4740 ? Intrinsic::arm_stlex
4741 : Intrinsic::arm_strex,
4742 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00004743 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex");
Tim Northover6aacd492013-07-16 09:47:53 +00004744 }
4745
Martin Storsjoed95a082016-09-30 19:13:46 +00004746 switch (BuiltinID) {
4747 case ARM::BI__iso_volatile_load8:
4748 case ARM::BI__iso_volatile_load16:
4749 case ARM::BI__iso_volatile_load32:
4750 case ARM::BI__iso_volatile_load64: {
4751 Value *Ptr = EmitScalarExpr(E->getArg(0));
4752 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4753 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy);
4754 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4755 LoadSize.getQuantity() * 8);
4756 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4757 llvm::LoadInst *Load =
4758 Builder.CreateAlignedLoad(Ptr, LoadSize);
4759 Load->setVolatile(true);
4760 return Load;
4761 }
4762 case ARM::BI__iso_volatile_store8:
4763 case ARM::BI__iso_volatile_store16:
4764 case ARM::BI__iso_volatile_store32:
4765 case ARM::BI__iso_volatile_store64: {
4766 Value *Ptr = EmitScalarExpr(E->getArg(0));
4767 Value *Value = EmitScalarExpr(E->getArg(1));
4768 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4769 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
4770 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4771 StoreSize.getQuantity() * 8);
4772 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4773 llvm::StoreInst *Store =
4774 Builder.CreateAlignedStore(Value, Ptr,
4775 StoreSize);
4776 Store->setVolatile(true);
4777 return Store;
4778 }
4779 }
4780
Tim Northover6aacd492013-07-16 09:47:53 +00004781 if (BuiltinID == ARM::BI__builtin_arm_clrex) {
4782 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00004783 return Builder.CreateCall(F);
Tim Northover6aacd492013-07-16 09:47:53 +00004784 }
4785
Joey Gouly1e8637b2013-09-18 10:07:09 +00004786 // CRC32
4787 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
4788 switch (BuiltinID) {
4789 case ARM::BI__builtin_arm_crc32b:
4790 CRCIntrinsicID = Intrinsic::arm_crc32b; break;
4791 case ARM::BI__builtin_arm_crc32cb:
4792 CRCIntrinsicID = Intrinsic::arm_crc32cb; break;
4793 case ARM::BI__builtin_arm_crc32h:
4794 CRCIntrinsicID = Intrinsic::arm_crc32h; break;
4795 case ARM::BI__builtin_arm_crc32ch:
4796 CRCIntrinsicID = Intrinsic::arm_crc32ch; break;
4797 case ARM::BI__builtin_arm_crc32w:
4798 case ARM::BI__builtin_arm_crc32d:
4799 CRCIntrinsicID = Intrinsic::arm_crc32w; break;
4800 case ARM::BI__builtin_arm_crc32cw:
4801 case ARM::BI__builtin_arm_crc32cd:
4802 CRCIntrinsicID = Intrinsic::arm_crc32cw; break;
4803 }
4804
4805 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
4806 Value *Arg0 = EmitScalarExpr(E->getArg(0));
4807 Value *Arg1 = EmitScalarExpr(E->getArg(1));
4808
4809 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w
4810 // intrinsics, hence we need different codegen for these cases.
4811 if (BuiltinID == ARM::BI__builtin_arm_crc32d ||
4812 BuiltinID == ARM::BI__builtin_arm_crc32cd) {
4813 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4814 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty);
4815 Value *Arg1b = Builder.CreateLShr(Arg1, C1);
4816 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty);
4817
4818 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004819 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a});
4820 return Builder.CreateCall(F, {Res, Arg1b});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004821 } else {
4822 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty);
4823
4824 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004825 return Builder.CreateCall(F, {Arg0, Arg1});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004826 }
4827 }
4828
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004829 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
4830 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4831 BuiltinID == ARM::BI__builtin_arm_rsrp ||
4832 BuiltinID == ARM::BI__builtin_arm_wsr ||
4833 BuiltinID == ARM::BI__builtin_arm_wsr64 ||
4834 BuiltinID == ARM::BI__builtin_arm_wsrp) {
4835
4836 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr ||
4837 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4838 BuiltinID == ARM::BI__builtin_arm_rsrp;
4839
4840 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp ||
4841 BuiltinID == ARM::BI__builtin_arm_wsrp;
4842
4843 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4844 BuiltinID == ARM::BI__builtin_arm_wsr64;
4845
4846 llvm::Type *ValueType;
4847 llvm::Type *RegisterType;
4848 if (IsPointerBuiltin) {
4849 ValueType = VoidPtrTy;
4850 RegisterType = Int32Ty;
4851 } else if (Is64Bit) {
4852 ValueType = RegisterType = Int64Ty;
4853 } else {
4854 ValueType = RegisterType = Int32Ty;
4855 }
4856
4857 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
4858 }
4859
Ahmed Bougacha94df7302015-06-04 01:43:41 +00004860 // Find out if any arguments are required to be integer constant
4861 // expressions.
4862 unsigned ICEArguments = 0;
4863 ASTContext::GetBuiltinTypeError Error;
4864 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
4865 assert(Error == ASTContext::GE_None && "Should not codegen an error");
4866
John McCall7f416cc2015-09-08 08:05:57 +00004867 auto getAlignmentValue32 = [&](Address addr) -> Value* {
4868 return Builder.getInt32(addr.getAlignment().getQuantity());
4869 };
4870
4871 Address PtrOp0 = Address::invalid();
4872 Address PtrOp1 = Address::invalid();
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004873 SmallVector<Value*, 4> Ops;
Bob Wilson63c93142015-06-24 06:05:20 +00004874 bool HasExtraArg = HasExtraNeonArgument(BuiltinID);
4875 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0);
4876 for (unsigned i = 0, e = NumArgs; i != e; i++) {
Eli Friedmana5dd5682012-08-23 03:10:17 +00004877 if (i == 0) {
4878 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00004879 case NEON::BI__builtin_neon_vld1_v:
4880 case NEON::BI__builtin_neon_vld1q_v:
4881 case NEON::BI__builtin_neon_vld1q_lane_v:
4882 case NEON::BI__builtin_neon_vld1_lane_v:
4883 case NEON::BI__builtin_neon_vld1_dup_v:
4884 case NEON::BI__builtin_neon_vld1q_dup_v:
4885 case NEON::BI__builtin_neon_vst1_v:
4886 case NEON::BI__builtin_neon_vst1q_v:
4887 case NEON::BI__builtin_neon_vst1q_lane_v:
4888 case NEON::BI__builtin_neon_vst1_lane_v:
4889 case NEON::BI__builtin_neon_vst2_v:
4890 case NEON::BI__builtin_neon_vst2q_v:
4891 case NEON::BI__builtin_neon_vst2_lane_v:
4892 case NEON::BI__builtin_neon_vst2q_lane_v:
4893 case NEON::BI__builtin_neon_vst3_v:
4894 case NEON::BI__builtin_neon_vst3q_v:
4895 case NEON::BI__builtin_neon_vst3_lane_v:
4896 case NEON::BI__builtin_neon_vst3q_lane_v:
4897 case NEON::BI__builtin_neon_vst4_v:
4898 case NEON::BI__builtin_neon_vst4q_v:
4899 case NEON::BI__builtin_neon_vst4_lane_v:
4900 case NEON::BI__builtin_neon_vst4q_lane_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00004901 // Get the alignment for the argument in addition to the value;
4902 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00004903 PtrOp0 = EmitPointerWithAlignment(E->getArg(0));
4904 Ops.push_back(PtrOp0.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00004905 continue;
4906 }
4907 }
4908 if (i == 1) {
4909 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00004910 case NEON::BI__builtin_neon_vld2_v:
4911 case NEON::BI__builtin_neon_vld2q_v:
4912 case NEON::BI__builtin_neon_vld3_v:
4913 case NEON::BI__builtin_neon_vld3q_v:
4914 case NEON::BI__builtin_neon_vld4_v:
4915 case NEON::BI__builtin_neon_vld4q_v:
4916 case NEON::BI__builtin_neon_vld2_lane_v:
4917 case NEON::BI__builtin_neon_vld2q_lane_v:
4918 case NEON::BI__builtin_neon_vld3_lane_v:
4919 case NEON::BI__builtin_neon_vld3q_lane_v:
4920 case NEON::BI__builtin_neon_vld4_lane_v:
4921 case NEON::BI__builtin_neon_vld4q_lane_v:
4922 case NEON::BI__builtin_neon_vld2_dup_v:
4923 case NEON::BI__builtin_neon_vld3_dup_v:
4924 case NEON::BI__builtin_neon_vld4_dup_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00004925 // Get the alignment for the argument in addition to the value;
4926 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00004927 PtrOp1 = EmitPointerWithAlignment(E->getArg(1));
4928 Ops.push_back(PtrOp1.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00004929 continue;
4930 }
4931 }
Ahmed Bougacha94df7302015-06-04 01:43:41 +00004932
4933 if ((ICEArguments & (1 << i)) == 0) {
4934 Ops.push_back(EmitScalarExpr(E->getArg(i)));
4935 } else {
4936 // If this is required to be a constant, constant fold it so that we know
4937 // that the generated intrinsic gets a ConstantInt.
4938 llvm::APSInt Result;
4939 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
4940 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
4941 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
4942 }
Eli Friedmana5dd5682012-08-23 03:10:17 +00004943 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004944
Bob Wilson445c24f2011-08-13 05:03:46 +00004945 switch (BuiltinID) {
4946 default: break;
Bob Wilson63c93142015-06-24 06:05:20 +00004947
Tim Northoverc322f832014-01-30 14:47:51 +00004948 case NEON::BI__builtin_neon_vget_lane_i8:
4949 case NEON::BI__builtin_neon_vget_lane_i16:
4950 case NEON::BI__builtin_neon_vget_lane_i32:
4951 case NEON::BI__builtin_neon_vget_lane_i64:
4952 case NEON::BI__builtin_neon_vget_lane_f32:
4953 case NEON::BI__builtin_neon_vgetq_lane_i8:
4954 case NEON::BI__builtin_neon_vgetq_lane_i16:
4955 case NEON::BI__builtin_neon_vgetq_lane_i32:
4956 case NEON::BI__builtin_neon_vgetq_lane_i64:
4957 case NEON::BI__builtin_neon_vgetq_lane_f32:
Bob Wilson63c93142015-06-24 06:05:20 +00004958 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane");
4959
Tim Northoverc322f832014-01-30 14:47:51 +00004960 case NEON::BI__builtin_neon_vset_lane_i8:
4961 case NEON::BI__builtin_neon_vset_lane_i16:
4962 case NEON::BI__builtin_neon_vset_lane_i32:
4963 case NEON::BI__builtin_neon_vset_lane_i64:
4964 case NEON::BI__builtin_neon_vset_lane_f32:
4965 case NEON::BI__builtin_neon_vsetq_lane_i8:
4966 case NEON::BI__builtin_neon_vsetq_lane_i16:
4967 case NEON::BI__builtin_neon_vsetq_lane_i32:
4968 case NEON::BI__builtin_neon_vsetq_lane_i64:
4969 case NEON::BI__builtin_neon_vsetq_lane_f32:
Bob Wilson445c24f2011-08-13 05:03:46 +00004970 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
Tim Northover02e38602014-02-03 17:28:04 +00004971
Tim Northover02e38602014-02-03 17:28:04 +00004972 case NEON::BI__builtin_neon_vsha1h_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004973 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops,
4974 "vsha1h");
4975 case NEON::BI__builtin_neon_vsha1cq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004976 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops,
4977 "vsha1h");
4978 case NEON::BI__builtin_neon_vsha1pq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004979 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops,
4980 "vsha1h");
4981 case NEON::BI__builtin_neon_vsha1mq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004982 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops,
4983 "vsha1h");
Bob Wilson63c93142015-06-24 06:05:20 +00004984
4985 // The ARM _MoveToCoprocessor builtins put the input register value as
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004986 // the first argument, but the LLVM intrinsic expects it as the third one.
4987 case ARM::BI_MoveToCoprocessor:
4988 case ARM::BI_MoveToCoprocessor2: {
4989 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ?
4990 Intrinsic::arm_mcr : Intrinsic::arm_mcr2);
4991 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0],
4992 Ops[3], Ops[4], Ops[5]});
Bob Wilson63c93142015-06-24 06:05:20 +00004993 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00004994 case ARM::BI_BitScanForward:
4995 case ARM::BI_BitScanForward64:
4996 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
4997 case ARM::BI_BitScanReverse:
4998 case ARM::BI_BitScanReverse64:
4999 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00005000
5001 case ARM::BI_InterlockedAnd64:
5002 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
5003 case ARM::BI_InterlockedExchange64:
5004 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
5005 case ARM::BI_InterlockedExchangeAdd64:
5006 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
5007 case ARM::BI_InterlockedExchangeSub64:
5008 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
5009 case ARM::BI_InterlockedOr64:
5010 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
5011 case ARM::BI_InterlockedXor64:
5012 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
5013 case ARM::BI_InterlockedDecrement64:
5014 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
5015 case ARM::BI_InterlockedIncrement64:
5016 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
Bob Wilson445c24f2011-08-13 05:03:46 +00005017 }
5018
5019 // Get the last argument, which specifies the vector type.
Bob Wilson63c93142015-06-24 06:05:20 +00005020 assert(HasExtraArg);
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005021 llvm::APSInt Result;
5022 const Expr *Arg = E->getArg(E->getNumArgs()-1);
5023 if (!Arg->isIntegerConstantExpr(Result, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00005024 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005025
Nate Begemanf568b072010-08-03 21:32:34 +00005026 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f ||
5027 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) {
5028 // Determine the overloaded type of this builtin.
Chris Lattnera5f58b02011-07-09 17:41:47 +00005029 llvm::Type *Ty;
Nate Begemanf568b072010-08-03 21:32:34 +00005030 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f)
Chris Lattnerece04092012-02-07 00:39:47 +00005031 Ty = FloatTy;
Nate Begemanf568b072010-08-03 21:32:34 +00005032 else
Chris Lattnerece04092012-02-07 00:39:47 +00005033 Ty = DoubleTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00005034
Nate Begemanf568b072010-08-03 21:32:34 +00005035 // Determine whether this is an unsigned conversion or not.
5036 bool usgn = Result.getZExtValue() == 1;
5037 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
5038
5039 // Call the appropriate intrinsic.
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005040 Function *F = CGM.getIntrinsic(Int, Ty);
Jay Foad5bd375a2011-07-15 08:37:34 +00005041 return Builder.CreateCall(F, Ops, "vcvtr");
Nate Begemanf568b072010-08-03 21:32:34 +00005042 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00005043
Nate Begemanf568b072010-08-03 21:32:34 +00005044 // Determine the type of this overloaded NEON intrinsic.
Bob Wilson98bc98c2011-11-08 01:16:11 +00005045 NeonTypeFlags Type(Result.getZExtValue());
5046 bool usgn = Type.isUnsigned();
Bob Wilson4fa993f2010-12-03 17:10:22 +00005047 bool rightShift = false;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005048
Chris Lattnerece04092012-02-07 00:39:47 +00005049 llvm::VectorType *VTy = GetNeonType(this, Type);
Chris Lattnera5f58b02011-07-09 17:41:47 +00005050 llvm::Type *Ty = VTy;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005051 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00005052 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005053
Tim Northoverac85c342014-01-30 14:47:57 +00005054 // Many NEON builtins have identical semantics and uses in ARM and
5055 // AArch64. Emit these in a single function.
Craig Topper5fc8fc22014-08-27 06:28:36 +00005056 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap);
Tim Northover8fe03d62014-02-21 11:57:24 +00005057 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
5058 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
5059 if (Builtin)
5060 return EmitCommonNeonBuiltinExpr(
5061 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00005062 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1);
Tim Northoverac85c342014-01-30 14:47:57 +00005063
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005064 unsigned Int;
5065 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00005066 default: return nullptr;
Tim Northoverc322f832014-01-30 14:47:51 +00005067 case NEON::BI__builtin_neon_vld1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005068 // Handle 64-bit integer elements as a special case. Use shuffles of
5069 // one-element vectors to avoid poor code for i64 in the backend.
5070 if (VTy->getElementType()->isIntegerTy(64)) {
5071 // Extract the other lane.
5072 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00005073 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue();
Bob Wilson2605fef2012-08-14 17:27:04 +00005074 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane));
5075 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
5076 // Load the value as a one-element vector.
5077 Ty = llvm::VectorType::get(VTy->getElementType(), 1);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005078 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5079 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005080 Value *Align = getAlignmentValue32(PtrOp0);
David Blaikie43f9bb72015-05-18 22:14:03 +00005081 Value *Ld = Builder.CreateCall(F, {Ops[0], Align});
Bob Wilson2605fef2012-08-14 17:27:04 +00005082 // Combine them.
Benjamin Kramerc385a802015-07-28 15:40:11 +00005083 uint32_t Indices[] = {1 - Lane, Lane};
5084 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices);
Bob Wilson2605fef2012-08-14 17:27:04 +00005085 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane");
5086 }
5087 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005088 case NEON::BI__builtin_neon_vld1_lane_v: {
Nate Begemaned48c852010-06-20 23:05:28 +00005089 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Steven Wu0d22f2d2015-09-09 01:37:18 +00005090 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00005091 Value *Ld = Builder.CreateLoad(PtrOp0);
Bob Wilson49708d42012-02-04 23:58:08 +00005092 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
5093 }
Tim Northoverc322f832014-01-30 14:47:51 +00005094 case NEON::BI__builtin_neon_vld2_dup_v:
5095 case NEON::BI__builtin_neon_vld3_dup_v:
5096 case NEON::BI__builtin_neon_vld4_dup_v: {
Bob Wilson0348af62010-12-10 22:54:58 +00005097 // Handle 64-bit elements as a special-case. There is no "dup" needed.
5098 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) {
5099 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005100 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005101 Int = Intrinsic::arm_neon_vld2;
Bob Wilson0348af62010-12-10 22:54:58 +00005102 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005103 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005104 Int = Intrinsic::arm_neon_vld3;
Bob Wilson0348af62010-12-10 22:54:58 +00005105 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005106 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005107 Int = Intrinsic::arm_neon_vld4;
Bob Wilson0348af62010-12-10 22:54:58 +00005108 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005109 default: llvm_unreachable("unknown vld_dup intrinsic?");
Bob Wilson0348af62010-12-10 22:54:58 +00005110 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005111 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5112 Function *F = CGM.getIntrinsic(Int, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005113 llvm::Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00005114 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup");
Bob Wilson0348af62010-12-10 22:54:58 +00005115 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5116 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005117 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Bob Wilson0348af62010-12-10 22:54:58 +00005118 }
Nate Begemaned48c852010-06-20 23:05:28 +00005119 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005120 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005121 Int = Intrinsic::arm_neon_vld2lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005122 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005123 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005124 Int = Intrinsic::arm_neon_vld3lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005125 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005126 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005127 Int = Intrinsic::arm_neon_vld4lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005128 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005129 default: llvm_unreachable("unknown vld_dup intrinsic?");
Nate Begemaned48c852010-06-20 23:05:28 +00005130 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005131 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5132 Function *F = CGM.getIntrinsic(Int, Tys);
Chris Lattner2192fe52011-07-18 04:24:23 +00005133 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType());
Jim Grosbachd3608f42012-09-21 00:18:27 +00005134
Nate Begemaned48c852010-06-20 23:05:28 +00005135 SmallVector<Value*, 6> Args;
5136 Args.push_back(Ops[1]);
5137 Args.append(STy->getNumElements(), UndefValue::get(Ty));
5138
Chris Lattner5e016ae2010-06-27 07:15:29 +00005139 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Nate Begemaned48c852010-06-20 23:05:28 +00005140 Args.push_back(CI);
John McCall7f416cc2015-09-08 08:05:57 +00005141 Args.push_back(getAlignmentValue32(PtrOp1));
Jim Grosbachd3608f42012-09-21 00:18:27 +00005142
Jay Foad5bd375a2011-07-15 08:37:34 +00005143 Ops[1] = Builder.CreateCall(F, Args, "vld_dup");
Nate Begemaned48c852010-06-20 23:05:28 +00005144 // splat lane 0 to all elts in each vector of the result.
5145 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5146 Value *Val = Builder.CreateExtractValue(Ops[1], i);
5147 Value *Elt = Builder.CreateBitCast(Val, Ty);
5148 Elt = EmitNeonSplat(Elt, CI);
5149 Elt = Builder.CreateBitCast(Elt, Val->getType());
5150 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i);
5151 }
5152 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5153 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005154 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begemaned48c852010-06-20 23:05:28 +00005155 }
Tim Northoverc322f832014-01-30 14:47:51 +00005156 case NEON::BI__builtin_neon_vqrshrn_n_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005157 Int =
5158 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005159 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005160 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005161 case NEON::BI__builtin_neon_vqrshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005162 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005163 Ops, "vqrshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005164 case NEON::BI__builtin_neon_vqshrn_n_v:
Nate Begeman91e1fea2010-06-14 05:21:25 +00005165 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005166 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005167 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005168 case NEON::BI__builtin_neon_vqshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005169 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005170 Ops, "vqshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005171 case NEON::BI__builtin_neon_vrecpe_v:
5172 case NEON::BI__builtin_neon_vrecpeq_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005173 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005174 Ops, "vrecpe");
Tim Northoverc322f832014-01-30 14:47:51 +00005175 case NEON::BI__builtin_neon_vrshrn_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005176 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005177 Ops, "vrshrn_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005178 case NEON::BI__builtin_neon_vrsra_n_v:
5179 case NEON::BI__builtin_neon_vrsraq_n_v:
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005180 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
5181 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5182 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true);
5183 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
David Blaikie43f9bb72015-05-18 22:14:03 +00005184 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]});
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005185 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005186 case NEON::BI__builtin_neon_vsri_n_v:
5187 case NEON::BI__builtin_neon_vsriq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005188 rightShift = true;
Galina Kistanova0872d6c2017-06-03 06:30:46 +00005189 LLVM_FALLTHROUGH;
Tim Northoverc322f832014-01-30 14:47:51 +00005190 case NEON::BI__builtin_neon_vsli_n_v:
5191 case NEON::BI__builtin_neon_vsliq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005192 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005193 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005194 Ops, "vsli_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005195 case NEON::BI__builtin_neon_vsra_n_v:
5196 case NEON::BI__builtin_neon_vsraq_n_v:
Nate Begeman8ed060b2010-06-11 22:57:12 +00005197 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00005198 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
Nate Begeman8ed060b2010-06-11 22:57:12 +00005199 return Builder.CreateAdd(Ops[0], Ops[1]);
Tim Northoverc322f832014-01-30 14:47:51 +00005200 case NEON::BI__builtin_neon_vst1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005201 // Handle 64-bit integer elements as a special case. Use a shuffle to get
5202 // a one-element vector and avoid poor code for i64 in the backend.
5203 if (VTy->getElementType()->isIntegerTy(64)) {
5204 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5205 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2]));
5206 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
John McCall7f416cc2015-09-08 08:05:57 +00005207 Ops[2] = getAlignmentValue32(PtrOp0);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005208 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()};
Bob Wilson2605fef2012-08-14 17:27:04 +00005209 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005210 Tys), Ops);
Bob Wilson2605fef2012-08-14 17:27:04 +00005211 }
5212 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005213 case NEON::BI__builtin_neon_vst1_lane_v: {
Nate Begeman8ed060b2010-06-11 22:57:12 +00005214 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5215 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
5216 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00005217 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty));
Bob Wilson49708d42012-02-04 23:58:08 +00005218 return St;
5219 }
Tim Northoverc322f832014-01-30 14:47:51 +00005220 case NEON::BI__builtin_neon_vtbl1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005221 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),
5222 Ops, "vtbl1");
Tim Northoverc322f832014-01-30 14:47:51 +00005223 case NEON::BI__builtin_neon_vtbl2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005224 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2),
5225 Ops, "vtbl2");
Tim Northoverc322f832014-01-30 14:47:51 +00005226 case NEON::BI__builtin_neon_vtbl3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005227 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3),
5228 Ops, "vtbl3");
Tim Northoverc322f832014-01-30 14:47:51 +00005229 case NEON::BI__builtin_neon_vtbl4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005230 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4),
5231 Ops, "vtbl4");
Tim Northoverc322f832014-01-30 14:47:51 +00005232 case NEON::BI__builtin_neon_vtbx1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005233 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1),
5234 Ops, "vtbx1");
Tim Northoverc322f832014-01-30 14:47:51 +00005235 case NEON::BI__builtin_neon_vtbx2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005236 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2),
5237 Ops, "vtbx2");
Tim Northoverc322f832014-01-30 14:47:51 +00005238 case NEON::BI__builtin_neon_vtbx3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005239 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3),
5240 Ops, "vtbx3");
Tim Northoverc322f832014-01-30 14:47:51 +00005241 case NEON::BI__builtin_neon_vtbx4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005242 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4),
5243 Ops, "vtbx4");
Chris Lattner5cc15e02010-03-03 19:03:45 +00005244 }
5245}
5246
Tim Northover573cbee2014-05-24 12:52:07 +00005247static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID,
Tim Northovera2ee4332014-03-29 15:09:45 +00005248 const CallExpr *E,
5249 SmallVectorImpl<Value *> &Ops) {
5250 unsigned int Int = 0;
Craig Topper8a13c412014-05-21 05:09:00 +00005251 const char *s = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005252
Tim Northovera2ee4332014-03-29 15:09:45 +00005253 switch (BuiltinID) {
5254 default:
Craig Topper8a13c412014-05-21 05:09:00 +00005255 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005256 case NEON::BI__builtin_neon_vtbl1_v:
5257 case NEON::BI__builtin_neon_vqtbl1_v:
5258 case NEON::BI__builtin_neon_vqtbl1q_v:
5259 case NEON::BI__builtin_neon_vtbl2_v:
5260 case NEON::BI__builtin_neon_vqtbl2_v:
5261 case NEON::BI__builtin_neon_vqtbl2q_v:
5262 case NEON::BI__builtin_neon_vtbl3_v:
5263 case NEON::BI__builtin_neon_vqtbl3_v:
5264 case NEON::BI__builtin_neon_vqtbl3q_v:
5265 case NEON::BI__builtin_neon_vtbl4_v:
5266 case NEON::BI__builtin_neon_vqtbl4_v:
5267 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005268 break;
5269 case NEON::BI__builtin_neon_vtbx1_v:
5270 case NEON::BI__builtin_neon_vqtbx1_v:
5271 case NEON::BI__builtin_neon_vqtbx1q_v:
5272 case NEON::BI__builtin_neon_vtbx2_v:
5273 case NEON::BI__builtin_neon_vqtbx2_v:
5274 case NEON::BI__builtin_neon_vqtbx2q_v:
5275 case NEON::BI__builtin_neon_vtbx3_v:
5276 case NEON::BI__builtin_neon_vqtbx3_v:
5277 case NEON::BI__builtin_neon_vqtbx3q_v:
5278 case NEON::BI__builtin_neon_vtbx4_v:
5279 case NEON::BI__builtin_neon_vqtbx4_v:
5280 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005281 break;
5282 }
5283
5284 assert(E->getNumArgs() >= 3);
5285
5286 // Get the last argument, which specifies the vector type.
5287 llvm::APSInt Result;
5288 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
5289 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00005290 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005291
5292 // Determine the type of this overloaded NEON intrinsic.
5293 NeonTypeFlags Type(Result.getZExtValue());
Benjamin Kramerc385a802015-07-28 15:40:11 +00005294 llvm::VectorType *Ty = GetNeonType(&CGF, Type);
Tim Northovera2ee4332014-03-29 15:09:45 +00005295 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00005296 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005297
Tim Northovera2ee4332014-03-29 15:09:45 +00005298 CodeGen::CGBuilderTy &Builder = CGF.Builder;
5299
5300 // AArch64 scalar builtins are not overloaded, they do not have an extra
5301 // argument that specifies the vector type, need to handle each case.
Tim Northovera2ee4332014-03-29 15:09:45 +00005302 switch (BuiltinID) {
5303 case NEON::BI__builtin_neon_vtbl1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005304 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr,
5305 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1,
5306 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005307 }
5308 case NEON::BI__builtin_neon_vtbl2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005309 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr,
5310 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1,
5311 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005312 }
5313 case NEON::BI__builtin_neon_vtbl3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005314 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr,
5315 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2,
5316 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005317 }
5318 case NEON::BI__builtin_neon_vtbl4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005319 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr,
5320 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2,
5321 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005322 }
5323 case NEON::BI__builtin_neon_vtbx1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005324 Value *TblRes =
5325 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2],
5326 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005327
Benjamin Kramerc385a802015-07-28 15:40:11 +00005328 llvm::Constant *EightV = ConstantInt::get(Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00005329 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV);
5330 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5331
5332 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5333 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5334 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5335 }
5336 case NEON::BI__builtin_neon_vtbx2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005337 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0],
5338 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1,
5339 "vtbx1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005340 }
5341 case NEON::BI__builtin_neon_vtbx3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005342 Value *TblRes =
5343 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4],
5344 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005345
Benjamin Kramerc385a802015-07-28 15:40:11 +00005346 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24);
Tim Northovera2ee4332014-03-29 15:09:45 +00005347 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4],
5348 TwentyFourV);
5349 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5350
5351 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5352 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5353 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5354 }
5355 case NEON::BI__builtin_neon_vtbx4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005356 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0],
5357 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2,
5358 "vtbx2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005359 }
5360 case NEON::BI__builtin_neon_vqtbl1_v:
5361 case NEON::BI__builtin_neon_vqtbl1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005362 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005363 case NEON::BI__builtin_neon_vqtbl2_v:
5364 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00005365 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005366 case NEON::BI__builtin_neon_vqtbl3_v:
5367 case NEON::BI__builtin_neon_vqtbl3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005368 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005369 case NEON::BI__builtin_neon_vqtbl4_v:
5370 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005371 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005372 case NEON::BI__builtin_neon_vqtbx1_v:
5373 case NEON::BI__builtin_neon_vqtbx1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005374 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005375 case NEON::BI__builtin_neon_vqtbx2_v:
5376 case NEON::BI__builtin_neon_vqtbx2q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005377 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005378 case NEON::BI__builtin_neon_vqtbx3_v:
5379 case NEON::BI__builtin_neon_vqtbx3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005380 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005381 case NEON::BI__builtin_neon_vqtbx4_v:
5382 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005383 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005384 }
5385 }
5386
5387 if (!Int)
Craig Topper8a13c412014-05-21 05:09:00 +00005388 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005389
5390 Function *F = CGF.CGM.getIntrinsic(Int, Ty);
5391 return CGF.EmitNeonCall(F, Ops, s);
5392}
5393
5394Value *CodeGenFunction::vectorWrapScalar16(Value *Op) {
5395 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
5396 Op = Builder.CreateBitCast(Op, Int16Ty);
5397 Value *V = UndefValue::get(VTy);
Michael J. Spencerdd597752014-05-31 00:22:12 +00005398 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00005399 Op = Builder.CreateInsertElement(V, Op, CI);
5400 return Op;
5401}
5402
Tim Northover573cbee2014-05-24 12:52:07 +00005403Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
5404 const CallExpr *E) {
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005405 unsigned HintID = static_cast<unsigned>(-1);
5406 switch (BuiltinID) {
5407 default: break;
Yi Kong4d5e23f2014-07-14 15:20:09 +00005408 case AArch64::BI__builtin_arm_nop:
5409 HintID = 0;
5410 break;
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005411 case AArch64::BI__builtin_arm_yield:
5412 HintID = 1;
5413 break;
5414 case AArch64::BI__builtin_arm_wfe:
5415 HintID = 2;
5416 break;
5417 case AArch64::BI__builtin_arm_wfi:
5418 HintID = 3;
5419 break;
5420 case AArch64::BI__builtin_arm_sev:
5421 HintID = 4;
5422 break;
5423 case AArch64::BI__builtin_arm_sevl:
5424 HintID = 5;
5425 break;
5426 }
5427
5428 if (HintID != static_cast<unsigned>(-1)) {
5429 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint);
5430 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
5431 }
5432
Yi Konga5548432014-08-13 19:18:20 +00005433 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
5434 Value *Address = EmitScalarExpr(E->getArg(0));
5435 Value *RW = EmitScalarExpr(E->getArg(1));
5436 Value *CacheLevel = EmitScalarExpr(E->getArg(2));
5437 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3));
5438 Value *IsData = EmitScalarExpr(E->getArg(4));
5439
5440 Value *Locality = nullptr;
5441 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) {
5442 // Temporal fetch, needs to convert cache level to locality.
5443 Locality = llvm::ConstantInt::get(Int32Ty,
5444 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3);
5445 } else {
5446 // Streaming fetch.
5447 Locality = llvm::ConstantInt::get(Int32Ty, 0);
5448 }
5449
5450 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify
5451 // PLDL3STRM or PLDL2STRM.
5452 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00005453 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Konga5548432014-08-13 19:18:20 +00005454 }
5455
Jim Grosbach79140822014-06-16 21:56:02 +00005456 if (BuiltinID == AArch64::BI__builtin_arm_rbit) {
5457 assert((getContext().getTypeSize(E->getType()) == 32) &&
5458 "rbit of unusual size!");
5459 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5460 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005461 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005462 }
5463 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) {
5464 assert((getContext().getTypeSize(E->getType()) == 64) &&
5465 "rbit of unusual size!");
5466 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5467 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005468 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005469 }
5470
Tim Northover573cbee2014-05-24 12:52:07 +00005471 if (BuiltinID == AArch64::BI__clear_cache) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005472 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
5473 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00005474 Value *Ops[2];
Tim Northovera2ee4332014-03-29 15:09:45 +00005475 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00005476 Ops[i] = EmitScalarExpr(E->getArg(i));
Tim Northovera2ee4332014-03-29 15:09:45 +00005477 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
5478 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
5479 StringRef Name = FD->getName();
5480 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
5481 }
5482
Tim Northover3acd6bd2014-07-02 12:56:02 +00005483 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5484 BuiltinID == AArch64::BI__builtin_arm_ldaex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005485 getContext().getTypeSize(E->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005486 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5487 ? Intrinsic::aarch64_ldaxp
5488 : Intrinsic::aarch64_ldxp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005489
5490 Value *LdPtr = EmitScalarExpr(E->getArg(0));
5491 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
5492 "ldxp");
5493
5494 Value *Val0 = Builder.CreateExtractValue(Val, 1);
5495 Value *Val1 = Builder.CreateExtractValue(Val, 0);
5496 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
5497 Val0 = Builder.CreateZExt(Val0, Int128Ty);
5498 Val1 = Builder.CreateZExt(Val1, Int128Ty);
5499
5500 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
5501 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
5502 Val = Builder.CreateOr(Val, Val1);
5503 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Tim Northover3acd6bd2014-07-02 12:56:02 +00005504 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5505 BuiltinID == AArch64::BI__builtin_arm_ldaex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005506 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
5507
5508 QualType Ty = E->getType();
5509 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005510 llvm::Type *PtrTy = llvm::IntegerType::get(
5511 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
5512 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005513
Tim Northover3acd6bd2014-07-02 12:56:02 +00005514 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5515 ? Intrinsic::aarch64_ldaxr
5516 : Intrinsic::aarch64_ldxr,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005517 PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005518 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
5519
5520 if (RealResTy->isPointerTy())
5521 return Builder.CreateIntToPtr(Val, RealResTy);
5522
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005523 llvm::Type *IntResTy = llvm::IntegerType::get(
5524 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northovera2ee4332014-03-29 15:09:45 +00005525 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
5526 return Builder.CreateBitCast(Val, RealResTy);
5527 }
5528
Tim Northover3acd6bd2014-07-02 12:56:02 +00005529 if ((BuiltinID == AArch64::BI__builtin_arm_strex ||
5530 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005531 getContext().getTypeSize(E->getArg(0)->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005532 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5533 ? Intrinsic::aarch64_stlxp
5534 : Intrinsic::aarch64_stxp);
Serge Guelton1d993272017-05-09 19:31:30 +00005535 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005536
John McCall7f416cc2015-09-08 08:05:57 +00005537 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
5538 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true);
Tim Northovera2ee4332014-03-29 15:09:45 +00005539
John McCall7f416cc2015-09-08 08:05:57 +00005540 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy));
5541 llvm::Value *Val = Builder.CreateLoad(Tmp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005542
5543 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
5544 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
5545 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)),
5546 Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00005547 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp");
5548 }
5549
5550 if (BuiltinID == AArch64::BI__builtin_arm_strex ||
5551 BuiltinID == AArch64::BI__builtin_arm_stlex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005552 Value *StoreVal = EmitScalarExpr(E->getArg(0));
5553 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
5554
5555 QualType Ty = E->getArg(0)->getType();
5556 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
5557 getContext().getTypeSize(Ty));
5558 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
5559
5560 if (StoreVal->getType()->isPointerTy())
5561 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty);
5562 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005563 llvm::Type *IntTy = llvm::IntegerType::get(
5564 getLLVMContext(),
5565 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
5566 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005567 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
5568 }
5569
Tim Northover3acd6bd2014-07-02 12:56:02 +00005570 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5571 ? Intrinsic::aarch64_stlxr
5572 : Intrinsic::aarch64_stxr,
5573 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00005574 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
Tim Northovera2ee4332014-03-29 15:09:45 +00005575 }
5576
Tim Northover573cbee2014-05-24 12:52:07 +00005577 if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
5578 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00005579 return Builder.CreateCall(F);
Tim Northovera2ee4332014-03-29 15:09:45 +00005580 }
5581
5582 // CRC32
5583 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
5584 switch (BuiltinID) {
Tim Northover573cbee2014-05-24 12:52:07 +00005585 case AArch64::BI__builtin_arm_crc32b:
5586 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break;
5587 case AArch64::BI__builtin_arm_crc32cb:
5588 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break;
5589 case AArch64::BI__builtin_arm_crc32h:
5590 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break;
5591 case AArch64::BI__builtin_arm_crc32ch:
5592 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break;
5593 case AArch64::BI__builtin_arm_crc32w:
5594 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break;
5595 case AArch64::BI__builtin_arm_crc32cw:
5596 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break;
5597 case AArch64::BI__builtin_arm_crc32d:
5598 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break;
5599 case AArch64::BI__builtin_arm_crc32cd:
5600 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005601 }
5602
5603 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
5604 Value *Arg0 = EmitScalarExpr(E->getArg(0));
5605 Value *Arg1 = EmitScalarExpr(E->getArg(1));
5606 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
5607
5608 llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
5609 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy);
5610
David Blaikie43f9bb72015-05-18 22:14:03 +00005611 return Builder.CreateCall(F, {Arg0, Arg1});
Tim Northovera2ee4332014-03-29 15:09:45 +00005612 }
5613
Luke Cheeseman59b2d832015-06-15 17:51:01 +00005614 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
5615 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5616 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5617 BuiltinID == AArch64::BI__builtin_arm_wsr ||
5618 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
5619 BuiltinID == AArch64::BI__builtin_arm_wsrp) {
5620
5621 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr ||
5622 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5623 BuiltinID == AArch64::BI__builtin_arm_rsrp;
5624
5625 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5626 BuiltinID == AArch64::BI__builtin_arm_wsrp;
5627
5628 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr &&
5629 BuiltinID != AArch64::BI__builtin_arm_wsr;
5630
5631 llvm::Type *ValueType;
5632 llvm::Type *RegisterType = Int64Ty;
5633 if (IsPointerBuiltin) {
5634 ValueType = VoidPtrTy;
5635 } else if (Is64Bit) {
5636 ValueType = Int64Ty;
5637 } else {
5638 ValueType = Int32Ty;
5639 }
5640
5641 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
5642 }
5643
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005644 // Find out if any arguments are required to be integer constant
5645 // expressions.
5646 unsigned ICEArguments = 0;
5647 ASTContext::GetBuiltinTypeError Error;
5648 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
5649 assert(Error == ASTContext::GE_None && "Should not codegen an error");
5650
Tim Northovera2ee4332014-03-29 15:09:45 +00005651 llvm::SmallVector<Value*, 4> Ops;
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005652 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
5653 if ((ICEArguments & (1 << i)) == 0) {
5654 Ops.push_back(EmitScalarExpr(E->getArg(i)));
5655 } else {
5656 // If this is required to be a constant, constant fold it so that we know
5657 // that the generated intrinsic gets a ConstantInt.
5658 llvm::APSInt Result;
5659 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
5660 assert(IsConst && "Constant arg isn't actually constant?");
5661 (void)IsConst;
5662 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
5663 }
5664 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005665
Craig Topper5fc8fc22014-08-27 06:28:36 +00005666 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
Tim Northovera2ee4332014-03-29 15:09:45 +00005667 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
Tim Northover573cbee2014-05-24 12:52:07 +00005668 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00005669
5670 if (Builtin) {
5671 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1)));
5672 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E);
5673 assert(Result && "SISD intrinsic should have been handled");
5674 return Result;
5675 }
5676
5677 llvm::APSInt Result;
5678 const Expr *Arg = E->getArg(E->getNumArgs()-1);
5679 NeonTypeFlags Type(0);
5680 if (Arg->isIntegerConstantExpr(Result, getContext()))
5681 // Determine the type of this overloaded NEON intrinsic.
5682 Type = NeonTypeFlags(Result.getZExtValue());
5683
5684 bool usgn = Type.isUnsigned();
5685 bool quad = Type.isQuad();
5686
5687 // Handle non-overloaded intrinsics first.
5688 switch (BuiltinID) {
5689 default: break;
Tim Northoverb17f9a42014-04-01 12:23:08 +00005690 case NEON::BI__builtin_neon_vldrq_p128: {
Peter Collingbourneb367c562016-11-28 22:30:21 +00005691 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128);
5692 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005693 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy);
Peter Collingbourneb367c562016-11-28 22:30:21 +00005694 return Builder.CreateAlignedLoad(Int128Ty, Ptr,
5695 CharUnits::fromQuantity(16));
Tim Northoverb17f9a42014-04-01 12:23:08 +00005696 }
5697 case NEON::BI__builtin_neon_vstrq_p128: {
5698 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128);
5699 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy);
John McCall7f416cc2015-09-08 08:05:57 +00005700 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005701 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005702 case NEON::BI__builtin_neon_vcvts_u32_f32:
5703 case NEON::BI__builtin_neon_vcvtd_u64_f64:
5704 usgn = true;
5705 // FALL THROUGH
5706 case NEON::BI__builtin_neon_vcvts_s32_f32:
5707 case NEON::BI__builtin_neon_vcvtd_s64_f64: {
5708 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5709 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5710 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5711 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5712 Ops[0] = Builder.CreateBitCast(Ops[0], FTy);
5713 if (usgn)
5714 return Builder.CreateFPToUI(Ops[0], InTy);
5715 return Builder.CreateFPToSI(Ops[0], InTy);
5716 }
5717 case NEON::BI__builtin_neon_vcvts_f32_u32:
5718 case NEON::BI__builtin_neon_vcvtd_f64_u64:
5719 usgn = true;
5720 // FALL THROUGH
5721 case NEON::BI__builtin_neon_vcvts_f32_s32:
5722 case NEON::BI__builtin_neon_vcvtd_f64_s64: {
5723 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5724 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5725 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5726 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5727 Ops[0] = Builder.CreateBitCast(Ops[0], InTy);
5728 if (usgn)
5729 return Builder.CreateUIToFP(Ops[0], FTy);
5730 return Builder.CreateSIToFP(Ops[0], FTy);
5731 }
5732 case NEON::BI__builtin_neon_vpaddd_s64: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005733 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005734 Value *Vec = EmitScalarExpr(E->getArg(0));
5735 // The vector is v2f64, so make sure it's bitcast to that.
5736 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005737 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5738 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005739 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5740 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5741 // Pairwise addition of a v2f64 into a scalar f64.
5742 return Builder.CreateAdd(Op0, Op1, "vpaddd");
5743 }
5744 case NEON::BI__builtin_neon_vpaddd_f64: {
5745 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005746 llvm::VectorType::get(DoubleTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005747 Value *Vec = EmitScalarExpr(E->getArg(0));
5748 // The vector is v2f64, so make sure it's bitcast to that.
5749 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005750 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5751 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005752 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5753 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5754 // Pairwise addition of a v2f64 into a scalar f64.
5755 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5756 }
5757 case NEON::BI__builtin_neon_vpadds_f32: {
5758 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005759 llvm::VectorType::get(FloatTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005760 Value *Vec = EmitScalarExpr(E->getArg(0));
5761 // The vector is v2f32, so make sure it's bitcast to that.
5762 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005763 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5764 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005765 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5766 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5767 // Pairwise addition of a v2f32 into a scalar f32.
5768 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5769 }
5770 case NEON::BI__builtin_neon_vceqzd_s64:
5771 case NEON::BI__builtin_neon_vceqzd_f64:
5772 case NEON::BI__builtin_neon_vceqzs_f32:
5773 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5774 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005775 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5776 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005777 case NEON::BI__builtin_neon_vcgezd_s64:
5778 case NEON::BI__builtin_neon_vcgezd_f64:
5779 case NEON::BI__builtin_neon_vcgezs_f32:
5780 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5781 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005782 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5783 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005784 case NEON::BI__builtin_neon_vclezd_s64:
5785 case NEON::BI__builtin_neon_vclezd_f64:
5786 case NEON::BI__builtin_neon_vclezs_f32:
5787 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5788 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005789 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5790 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005791 case NEON::BI__builtin_neon_vcgtzd_s64:
5792 case NEON::BI__builtin_neon_vcgtzd_f64:
5793 case NEON::BI__builtin_neon_vcgtzs_f32:
5794 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5795 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005796 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5797 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005798 case NEON::BI__builtin_neon_vcltzd_s64:
5799 case NEON::BI__builtin_neon_vcltzd_f64:
5800 case NEON::BI__builtin_neon_vcltzs_f32:
5801 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5802 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005803 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5804 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005805
5806 case NEON::BI__builtin_neon_vceqzd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00005807 Ops.push_back(EmitScalarExpr(E->getArg(0)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00005808 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5809 Ops[0] =
5810 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty));
5811 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005812 }
5813 case NEON::BI__builtin_neon_vceqd_f64:
5814 case NEON::BI__builtin_neon_vcled_f64:
5815 case NEON::BI__builtin_neon_vcltd_f64:
5816 case NEON::BI__builtin_neon_vcged_f64:
5817 case NEON::BI__builtin_neon_vcgtd_f64: {
5818 llvm::CmpInst::Predicate P;
5819 switch (BuiltinID) {
5820 default: llvm_unreachable("missing builtin ID in switch!");
5821 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break;
5822 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break;
5823 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break;
5824 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break;
5825 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break;
5826 }
5827 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5828 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
5829 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
5830 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5831 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd");
5832 }
5833 case NEON::BI__builtin_neon_vceqs_f32:
5834 case NEON::BI__builtin_neon_vcles_f32:
5835 case NEON::BI__builtin_neon_vclts_f32:
5836 case NEON::BI__builtin_neon_vcges_f32:
5837 case NEON::BI__builtin_neon_vcgts_f32: {
5838 llvm::CmpInst::Predicate P;
5839 switch (BuiltinID) {
5840 default: llvm_unreachable("missing builtin ID in switch!");
5841 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break;
5842 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break;
5843 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break;
5844 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break;
5845 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break;
5846 }
5847 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5848 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
5849 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy);
5850 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5851 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd");
5852 }
5853 case NEON::BI__builtin_neon_vceqd_s64:
5854 case NEON::BI__builtin_neon_vceqd_u64:
5855 case NEON::BI__builtin_neon_vcgtd_s64:
5856 case NEON::BI__builtin_neon_vcgtd_u64:
5857 case NEON::BI__builtin_neon_vcltd_s64:
5858 case NEON::BI__builtin_neon_vcltd_u64:
5859 case NEON::BI__builtin_neon_vcged_u64:
5860 case NEON::BI__builtin_neon_vcged_s64:
5861 case NEON::BI__builtin_neon_vcled_u64:
5862 case NEON::BI__builtin_neon_vcled_s64: {
5863 llvm::CmpInst::Predicate P;
5864 switch (BuiltinID) {
5865 default: llvm_unreachable("missing builtin ID in switch!");
5866 case NEON::BI__builtin_neon_vceqd_s64:
5867 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break;
5868 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break;
5869 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break;
5870 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break;
5871 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break;
5872 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break;
5873 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break;
5874 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break;
5875 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break;
5876 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005877 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Tim Northover0c68faa2014-03-31 15:47:09 +00005878 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5879 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005880 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]);
Tim Northover0c68faa2014-03-31 15:47:09 +00005881 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005882 }
5883 case NEON::BI__builtin_neon_vtstd_s64:
5884 case NEON::BI__builtin_neon_vtstd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00005885 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00005886 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5887 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005888 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
5889 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
Benjamin Kramerc385a802015-07-28 15:40:11 +00005890 llvm::Constant::getNullValue(Int64Ty));
5891 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005892 }
5893 case NEON::BI__builtin_neon_vset_lane_i8:
5894 case NEON::BI__builtin_neon_vset_lane_i16:
5895 case NEON::BI__builtin_neon_vset_lane_i32:
5896 case NEON::BI__builtin_neon_vset_lane_i64:
5897 case NEON::BI__builtin_neon_vset_lane_f32:
5898 case NEON::BI__builtin_neon_vsetq_lane_i8:
5899 case NEON::BI__builtin_neon_vsetq_lane_i16:
5900 case NEON::BI__builtin_neon_vsetq_lane_i32:
5901 case NEON::BI__builtin_neon_vsetq_lane_i64:
5902 case NEON::BI__builtin_neon_vsetq_lane_f32:
5903 Ops.push_back(EmitScalarExpr(E->getArg(2)));
5904 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
5905 case NEON::BI__builtin_neon_vset_lane_f64:
5906 // The vector type needs a cast for the v1f64 variant.
5907 Ops[1] = Builder.CreateBitCast(Ops[1],
5908 llvm::VectorType::get(DoubleTy, 1));
5909 Ops.push_back(EmitScalarExpr(E->getArg(2)));
5910 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
5911 case NEON::BI__builtin_neon_vsetq_lane_f64:
5912 // The vector type needs a cast for the v2f64 variant.
5913 Ops[1] = Builder.CreateBitCast(Ops[1],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005914 llvm::VectorType::get(DoubleTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005915 Ops.push_back(EmitScalarExpr(E->getArg(2)));
5916 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
5917
5918 case NEON::BI__builtin_neon_vget_lane_i8:
5919 case NEON::BI__builtin_neon_vdupb_lane_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005920 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00005921 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5922 "vget_lane");
5923 case NEON::BI__builtin_neon_vgetq_lane_i8:
5924 case NEON::BI__builtin_neon_vdupb_laneq_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005925 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16));
Tim Northovera2ee4332014-03-29 15:09:45 +00005926 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5927 "vgetq_lane");
5928 case NEON::BI__builtin_neon_vget_lane_i16:
5929 case NEON::BI__builtin_neon_vduph_lane_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005930 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00005931 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5932 "vget_lane");
5933 case NEON::BI__builtin_neon_vgetq_lane_i16:
5934 case NEON::BI__builtin_neon_vduph_laneq_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005935 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00005936 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5937 "vgetq_lane");
5938 case NEON::BI__builtin_neon_vget_lane_i32:
5939 case NEON::BI__builtin_neon_vdups_lane_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005940 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005941 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5942 "vget_lane");
5943 case NEON::BI__builtin_neon_vdups_lane_f32:
5944 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005945 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005946 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5947 "vdups_lane");
5948 case NEON::BI__builtin_neon_vgetq_lane_i32:
5949 case NEON::BI__builtin_neon_vdups_laneq_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005950 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00005951 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5952 "vgetq_lane");
5953 case NEON::BI__builtin_neon_vget_lane_i64:
5954 case NEON::BI__builtin_neon_vdupd_lane_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005955 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00005956 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5957 "vget_lane");
5958 case NEON::BI__builtin_neon_vdupd_lane_f64:
5959 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005960 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00005961 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5962 "vdupd_lane");
5963 case NEON::BI__builtin_neon_vgetq_lane_i64:
5964 case NEON::BI__builtin_neon_vdupd_laneq_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005965 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005966 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5967 "vgetq_lane");
5968 case NEON::BI__builtin_neon_vget_lane_f32:
5969 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005970 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005971 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5972 "vget_lane");
5973 case NEON::BI__builtin_neon_vget_lane_f64:
5974 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005975 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00005976 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5977 "vget_lane");
5978 case NEON::BI__builtin_neon_vgetq_lane_f32:
5979 case NEON::BI__builtin_neon_vdups_laneq_f32:
5980 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005981 llvm::VectorType::get(FloatTy, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00005982 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5983 "vgetq_lane");
5984 case NEON::BI__builtin_neon_vgetq_lane_f64:
5985 case NEON::BI__builtin_neon_vdupd_laneq_f64:
5986 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005987 llvm::VectorType::get(DoubleTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005988 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5989 "vgetq_lane");
5990 case NEON::BI__builtin_neon_vaddd_s64:
5991 case NEON::BI__builtin_neon_vaddd_u64:
5992 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd");
5993 case NEON::BI__builtin_neon_vsubd_s64:
5994 case NEON::BI__builtin_neon_vsubd_u64:
5995 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd");
5996 case NEON::BI__builtin_neon_vqdmlalh_s16:
5997 case NEON::BI__builtin_neon_vqdmlslh_s16: {
5998 SmallVector<Value *, 2> ProductOps;
5999 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
6000 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2))));
6001 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00006002 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006003 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00006004 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006005 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
6006
6007 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
Tim Northover573cbee2014-05-24 12:52:07 +00006008 ? Intrinsic::aarch64_neon_sqadd
6009 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006010 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl");
6011 }
6012 case NEON::BI__builtin_neon_vqshlud_n_s64: {
6013 Ops.push_back(EmitScalarExpr(E->getArg(1)));
6014 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Tim Northover573cbee2014-05-24 12:52:07 +00006015 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty),
Hao Liua19a2e22014-04-28 07:36:12 +00006016 Ops, "vqshlu_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006017 }
6018 case NEON::BI__builtin_neon_vqshld_n_u64:
6019 case NEON::BI__builtin_neon_vqshld_n_s64: {
6020 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006021 ? Intrinsic::aarch64_neon_uqshl
6022 : Intrinsic::aarch64_neon_sqshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006023 Ops.push_back(EmitScalarExpr(E->getArg(1)));
6024 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Hao Liua19a2e22014-04-28 07:36:12 +00006025 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006026 }
6027 case NEON::BI__builtin_neon_vrshrd_n_u64:
6028 case NEON::BI__builtin_neon_vrshrd_n_s64: {
6029 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006030 ? Intrinsic::aarch64_neon_urshl
6031 : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006032 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Hao Liua19a2e22014-04-28 07:36:12 +00006033 int SV = cast<ConstantInt>(Ops[1])->getSExtValue();
6034 Ops[1] = ConstantInt::get(Int64Ty, -SV);
6035 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006036 }
6037 case NEON::BI__builtin_neon_vrsrad_n_u64:
6038 case NEON::BI__builtin_neon_vrsrad_n_s64: {
6039 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006040 ? Intrinsic::aarch64_neon_urshl
6041 : Intrinsic::aarch64_neon_srshl;
Tim Northover0c68faa2014-03-31 15:47:09 +00006042 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
6043 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2))));
David Blaikie43f9bb72015-05-18 22:14:03 +00006044 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty),
6045 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)});
Tim Northover0c68faa2014-03-31 15:47:09 +00006046 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00006047 }
6048 case NEON::BI__builtin_neon_vshld_n_s64:
6049 case NEON::BI__builtin_neon_vshld_n_u64: {
6050 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
6051 return Builder.CreateShl(
Hao Liu9f9492b2014-05-14 08:59:30 +00006052 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006053 }
6054 case NEON::BI__builtin_neon_vshrd_n_s64: {
6055 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
6056 return Builder.CreateAShr(
6057 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
6058 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00006059 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006060 }
6061 case NEON::BI__builtin_neon_vshrd_n_u64: {
6062 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006063 uint64_t ShiftAmt = Amt->getZExtValue();
6064 // Right-shifting an unsigned value by its size yields 0.
6065 if (ShiftAmt == 64)
6066 return ConstantInt::get(Int64Ty, 0);
6067 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt),
6068 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006069 }
6070 case NEON::BI__builtin_neon_vsrad_n_s64: {
6071 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
6072 Ops[1] = Builder.CreateAShr(
6073 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
6074 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00006075 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006076 return Builder.CreateAdd(Ops[0], Ops[1]);
6077 }
6078 case NEON::BI__builtin_neon_vsrad_n_u64: {
6079 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006080 uint64_t ShiftAmt = Amt->getZExtValue();
6081 // Right-shifting an unsigned value by its size yields 0.
6082 // As Op + 0 = Op, return Ops[0] directly.
6083 if (ShiftAmt == 64)
6084 return Ops[0];
6085 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt),
6086 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006087 return Builder.CreateAdd(Ops[0], Ops[1]);
6088 }
6089 case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
6090 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
6091 case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
6092 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
6093 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6094 "lane");
6095 SmallVector<Value *, 2> ProductOps;
6096 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
6097 ProductOps.push_back(vectorWrapScalar16(Ops[2]));
6098 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00006099 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006100 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00006101 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006102 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
6103 Ops.pop_back();
6104
6105 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
6106 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
Tim Northover573cbee2014-05-24 12:52:07 +00006107 ? Intrinsic::aarch64_neon_sqadd
6108 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006109 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl");
6110 }
6111 case NEON::BI__builtin_neon_vqdmlals_s32:
6112 case NEON::BI__builtin_neon_vqdmlsls_s32: {
6113 SmallVector<Value *, 2> ProductOps;
6114 ProductOps.push_back(Ops[1]);
6115 ProductOps.push_back(EmitScalarExpr(E->getArg(2)));
6116 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006117 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006118 ProductOps, "vqdmlXl");
6119
6120 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
Tim Northover573cbee2014-05-24 12:52:07 +00006121 ? Intrinsic::aarch64_neon_sqadd
6122 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006123 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl");
6124 }
6125 case NEON::BI__builtin_neon_vqdmlals_lane_s32:
6126 case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
6127 case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
6128 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
6129 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6130 "lane");
6131 SmallVector<Value *, 2> ProductOps;
6132 ProductOps.push_back(Ops[1]);
6133 ProductOps.push_back(Ops[2]);
6134 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006135 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006136 ProductOps, "vqdmlXl");
6137 Ops.pop_back();
6138
6139 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
6140 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
Tim Northover573cbee2014-05-24 12:52:07 +00006141 ? Intrinsic::aarch64_neon_sqadd
6142 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006143 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl");
6144 }
6145 }
6146
6147 llvm::VectorType *VTy = GetNeonType(this, Type);
6148 llvm::Type *Ty = VTy;
6149 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00006150 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006151
Tim Northover573cbee2014-05-24 12:52:07 +00006152 // Not all intrinsics handled by the common case work for AArch64 yet, so only
Tim Northovera2ee4332014-03-29 15:09:45 +00006153 // defer to common code if it's been added to our special map.
Tim Northover573cbee2014-05-24 12:52:07 +00006154 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID,
6155 AArch64SIMDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00006156
6157 if (Builtin)
6158 return EmitCommonNeonBuiltinExpr(
6159 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00006160 Builtin->NameHint, Builtin->TypeModifier, E, Ops,
6161 /*never use addresses*/ Address::invalid(), Address::invalid());
Tim Northovera2ee4332014-03-29 15:09:45 +00006162
Tim Northover573cbee2014-05-24 12:52:07 +00006163 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops))
Tim Northovera2ee4332014-03-29 15:09:45 +00006164 return V;
6165
6166 unsigned Int;
6167 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00006168 default: return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006169 case NEON::BI__builtin_neon_vbsl_v:
6170 case NEON::BI__builtin_neon_vbslq_v: {
6171 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
6172 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl");
6173 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl");
6174 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl");
6175
6176 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl");
6177 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl");
6178 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl");
6179 return Builder.CreateBitCast(Ops[0], Ty);
6180 }
6181 case NEON::BI__builtin_neon_vfma_lane_v:
6182 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types
6183 // The ARM builtins (and instructions) have the addend as the first
6184 // operand, but the 'fma' intrinsics have it last. Swap it around here.
6185 Value *Addend = Ops[0];
6186 Value *Multiplicand = Ops[1];
6187 Value *LaneSource = Ops[2];
6188 Ops[0] = Multiplicand;
6189 Ops[1] = LaneSource;
6190 Ops[2] = Addend;
6191
6192 // Now adjust things to handle the lane access.
6193 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ?
6194 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) :
6195 VTy;
6196 llvm::Constant *cst = cast<Constant>(Ops[3]);
6197 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst);
6198 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy);
6199 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane");
6200
6201 Ops.pop_back();
6202 Int = Intrinsic::fma;
6203 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla");
6204 }
6205 case NEON::BI__builtin_neon_vfma_laneq_v: {
6206 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
6207 // v1f64 fma should be mapped to Neon scalar f64 fma
6208 if (VTy && VTy->getElementType() == DoubleTy) {
6209 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6210 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
6211 llvm::Type *VTy = GetNeonType(this,
6212 NeonTypeFlags(NeonTypeFlags::Float64, false, true));
6213 Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
6214 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
6215 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00006216 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006217 return Builder.CreateBitCast(Result, Ty);
6218 }
6219 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6220 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6221 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6222
6223 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(),
6224 VTy->getNumElements() * 2);
6225 Ops[2] = Builder.CreateBitCast(Ops[2], STy);
6226 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(),
6227 cast<ConstantInt>(Ops[3]));
6228 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane");
6229
David Blaikie43f9bb72015-05-18 22:14:03 +00006230 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006231 }
6232 case NEON::BI__builtin_neon_vfmaq_laneq_v: {
6233 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6234 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6235 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6236
6237 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
6238 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3]));
David Blaikie43f9bb72015-05-18 22:14:03 +00006239 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006240 }
6241 case NEON::BI__builtin_neon_vfmas_lane_f32:
6242 case NEON::BI__builtin_neon_vfmas_laneq_f32:
6243 case NEON::BI__builtin_neon_vfmad_lane_f64:
6244 case NEON::BI__builtin_neon_vfmad_laneq_f64: {
6245 Ops.push_back(EmitScalarExpr(E->getArg(3)));
David Majnemerced8bdf2015-02-25 17:36:15 +00006246 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northovera2ee4332014-03-29 15:09:45 +00006247 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6248 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
David Blaikie43f9bb72015-05-18 22:14:03 +00006249 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006250 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006251 case NEON::BI__builtin_neon_vmull_v:
6252 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006253 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
6254 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull;
Tim Northovera2ee4332014-03-29 15:09:45 +00006255 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
6256 case NEON::BI__builtin_neon_vmax_v:
6257 case NEON::BI__builtin_neon_vmaxq_v:
6258 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006259 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax;
6260 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax;
Tim Northovera2ee4332014-03-29 15:09:45 +00006261 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax");
6262 case NEON::BI__builtin_neon_vmin_v:
6263 case NEON::BI__builtin_neon_vminq_v:
6264 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006265 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin;
6266 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin;
Tim Northovera2ee4332014-03-29 15:09:45 +00006267 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin");
6268 case NEON::BI__builtin_neon_vabd_v:
6269 case NEON::BI__builtin_neon_vabdq_v:
6270 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006271 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
6272 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd;
Tim Northovera2ee4332014-03-29 15:09:45 +00006273 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd");
6274 case NEON::BI__builtin_neon_vpadal_v:
6275 case NEON::BI__builtin_neon_vpadalq_v: {
6276 unsigned ArgElts = VTy->getNumElements();
6277 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType());
6278 unsigned BitWidth = EltTy->getBitWidth();
6279 llvm::Type *ArgTy = llvm::VectorType::get(
6280 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts);
6281 llvm::Type* Tys[2] = { VTy, ArgTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006282 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006283 SmallVector<llvm::Value*, 1> TmpOps;
6284 TmpOps.push_back(Ops[1]);
6285 Function *F = CGM.getIntrinsic(Int, Tys);
6286 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal");
6287 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType());
6288 return Builder.CreateAdd(tmp, addend);
6289 }
6290 case NEON::BI__builtin_neon_vpmin_v:
6291 case NEON::BI__builtin_neon_vpminq_v:
6292 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006293 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
6294 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006295 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin");
6296 case NEON::BI__builtin_neon_vpmax_v:
6297 case NEON::BI__builtin_neon_vpmaxq_v:
6298 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006299 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
6300 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006301 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax");
6302 case NEON::BI__builtin_neon_vminnm_v:
6303 case NEON::BI__builtin_neon_vminnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006304 Int = Intrinsic::aarch64_neon_fminnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006305 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm");
6306 case NEON::BI__builtin_neon_vmaxnm_v:
6307 case NEON::BI__builtin_neon_vmaxnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006308 Int = Intrinsic::aarch64_neon_fmaxnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006309 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm");
6310 case NEON::BI__builtin_neon_vrecpss_f32: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006311 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006312 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006313 Ops, "vrecps");
6314 }
6315 case NEON::BI__builtin_neon_vrecpsd_f64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006316 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006317 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006318 Ops, "vrecps");
6319 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006320 case NEON::BI__builtin_neon_vqshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006321 Int = Intrinsic::aarch64_neon_sqshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006322 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n");
6323 case NEON::BI__builtin_neon_vqrshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006324 Int = Intrinsic::aarch64_neon_sqrshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006325 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n");
6326 case NEON::BI__builtin_neon_vqshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006327 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006328 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n");
6329 case NEON::BI__builtin_neon_vrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006330 Int = Intrinsic::aarch64_neon_rshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006331 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n");
6332 case NEON::BI__builtin_neon_vqrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006333 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006334 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n");
6335 case NEON::BI__builtin_neon_vrnda_v:
6336 case NEON::BI__builtin_neon_vrndaq_v: {
6337 Int = Intrinsic::round;
6338 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda");
6339 }
6340 case NEON::BI__builtin_neon_vrndi_v:
6341 case NEON::BI__builtin_neon_vrndiq_v: {
6342 Int = Intrinsic::nearbyint;
6343 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi");
6344 }
6345 case NEON::BI__builtin_neon_vrndm_v:
6346 case NEON::BI__builtin_neon_vrndmq_v: {
6347 Int = Intrinsic::floor;
6348 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm");
6349 }
6350 case NEON::BI__builtin_neon_vrndn_v:
6351 case NEON::BI__builtin_neon_vrndnq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006352 Int = Intrinsic::aarch64_neon_frintn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006353 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn");
6354 }
6355 case NEON::BI__builtin_neon_vrndp_v:
6356 case NEON::BI__builtin_neon_vrndpq_v: {
6357 Int = Intrinsic::ceil;
6358 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp");
6359 }
6360 case NEON::BI__builtin_neon_vrndx_v:
6361 case NEON::BI__builtin_neon_vrndxq_v: {
6362 Int = Intrinsic::rint;
6363 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx");
6364 }
6365 case NEON::BI__builtin_neon_vrnd_v:
6366 case NEON::BI__builtin_neon_vrndq_v: {
6367 Int = Intrinsic::trunc;
6368 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz");
6369 }
6370 case NEON::BI__builtin_neon_vceqz_v:
6371 case NEON::BI__builtin_neon_vceqzq_v:
6372 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ,
6373 ICmpInst::ICMP_EQ, "vceqz");
6374 case NEON::BI__builtin_neon_vcgez_v:
6375 case NEON::BI__builtin_neon_vcgezq_v:
6376 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE,
6377 ICmpInst::ICMP_SGE, "vcgez");
6378 case NEON::BI__builtin_neon_vclez_v:
6379 case NEON::BI__builtin_neon_vclezq_v:
6380 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE,
6381 ICmpInst::ICMP_SLE, "vclez");
6382 case NEON::BI__builtin_neon_vcgtz_v:
6383 case NEON::BI__builtin_neon_vcgtzq_v:
6384 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT,
6385 ICmpInst::ICMP_SGT, "vcgtz");
6386 case NEON::BI__builtin_neon_vcltz_v:
6387 case NEON::BI__builtin_neon_vcltzq_v:
6388 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT,
6389 ICmpInst::ICMP_SLT, "vcltz");
6390 case NEON::BI__builtin_neon_vcvt_f64_v:
6391 case NEON::BI__builtin_neon_vcvtq_f64_v:
6392 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6393 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad));
6394 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
6395 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
6396 case NEON::BI__builtin_neon_vcvt_f64_f32: {
6397 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad &&
6398 "unexpected vcvt_f64_f32 builtin");
6399 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false);
6400 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6401
6402 return Builder.CreateFPExt(Ops[0], Ty, "vcvt");
6403 }
6404 case NEON::BI__builtin_neon_vcvt_f32_f64: {
6405 assert(Type.getEltType() == NeonTypeFlags::Float32 &&
6406 "unexpected vcvt_f32_f64 builtin");
6407 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true);
6408 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6409
6410 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt");
6411 }
6412 case NEON::BI__builtin_neon_vcvt_s32_v:
6413 case NEON::BI__builtin_neon_vcvt_u32_v:
6414 case NEON::BI__builtin_neon_vcvt_s64_v:
6415 case NEON::BI__builtin_neon_vcvt_u64_v:
6416 case NEON::BI__builtin_neon_vcvtq_s32_v:
6417 case NEON::BI__builtin_neon_vcvtq_u32_v:
6418 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00006419 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006420 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northovera2ee4332014-03-29 15:09:45 +00006421 if (usgn)
6422 return Builder.CreateFPToUI(Ops[0], Ty);
6423 return Builder.CreateFPToSI(Ops[0], Ty);
6424 }
6425 case NEON::BI__builtin_neon_vcvta_s32_v:
6426 case NEON::BI__builtin_neon_vcvtaq_s32_v:
6427 case NEON::BI__builtin_neon_vcvta_u32_v:
6428 case NEON::BI__builtin_neon_vcvtaq_u32_v:
6429 case NEON::BI__builtin_neon_vcvta_s64_v:
6430 case NEON::BI__builtin_neon_vcvtaq_s64_v:
6431 case NEON::BI__builtin_neon_vcvta_u64_v:
6432 case NEON::BI__builtin_neon_vcvtaq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006433 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006434 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006435 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta");
6436 }
6437 case NEON::BI__builtin_neon_vcvtm_s32_v:
6438 case NEON::BI__builtin_neon_vcvtmq_s32_v:
6439 case NEON::BI__builtin_neon_vcvtm_u32_v:
6440 case NEON::BI__builtin_neon_vcvtmq_u32_v:
6441 case NEON::BI__builtin_neon_vcvtm_s64_v:
6442 case NEON::BI__builtin_neon_vcvtmq_s64_v:
6443 case NEON::BI__builtin_neon_vcvtm_u64_v:
6444 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006445 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006446 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006447 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm");
6448 }
6449 case NEON::BI__builtin_neon_vcvtn_s32_v:
6450 case NEON::BI__builtin_neon_vcvtnq_s32_v:
6451 case NEON::BI__builtin_neon_vcvtn_u32_v:
6452 case NEON::BI__builtin_neon_vcvtnq_u32_v:
6453 case NEON::BI__builtin_neon_vcvtn_s64_v:
6454 case NEON::BI__builtin_neon_vcvtnq_s64_v:
6455 case NEON::BI__builtin_neon_vcvtn_u64_v:
6456 case NEON::BI__builtin_neon_vcvtnq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006457 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006458 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006459 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn");
6460 }
6461 case NEON::BI__builtin_neon_vcvtp_s32_v:
6462 case NEON::BI__builtin_neon_vcvtpq_s32_v:
6463 case NEON::BI__builtin_neon_vcvtp_u32_v:
6464 case NEON::BI__builtin_neon_vcvtpq_u32_v:
6465 case NEON::BI__builtin_neon_vcvtp_s64_v:
6466 case NEON::BI__builtin_neon_vcvtpq_s64_v:
6467 case NEON::BI__builtin_neon_vcvtp_u64_v:
6468 case NEON::BI__builtin_neon_vcvtpq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006469 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006470 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006471 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp");
6472 }
6473 case NEON::BI__builtin_neon_vmulx_v:
6474 case NEON::BI__builtin_neon_vmulxq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006475 Int = Intrinsic::aarch64_neon_fmulx;
Tim Northovera2ee4332014-03-29 15:09:45 +00006476 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx");
6477 }
6478 case NEON::BI__builtin_neon_vmul_lane_v:
6479 case NEON::BI__builtin_neon_vmul_laneq_v: {
6480 // v1f64 vmul_lane should be mapped to Neon scalar mul lane
6481 bool Quad = false;
6482 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
6483 Quad = true;
6484 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6485 llvm::Type *VTy = GetNeonType(this,
6486 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad));
6487 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
6488 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract");
6489 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]);
6490 return Builder.CreateBitCast(Result, Ty);
6491 }
Tim Northover0c68faa2014-03-31 15:47:09 +00006492 case NEON::BI__builtin_neon_vnegd_s64:
6493 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd");
Tim Northovera2ee4332014-03-29 15:09:45 +00006494 case NEON::BI__builtin_neon_vpmaxnm_v:
6495 case NEON::BI__builtin_neon_vpmaxnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006496 Int = Intrinsic::aarch64_neon_fmaxnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006497 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm");
6498 }
6499 case NEON::BI__builtin_neon_vpminnm_v:
6500 case NEON::BI__builtin_neon_vpminnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006501 Int = Intrinsic::aarch64_neon_fminnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006502 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm");
6503 }
6504 case NEON::BI__builtin_neon_vsqrt_v:
6505 case NEON::BI__builtin_neon_vsqrtq_v: {
6506 Int = Intrinsic::sqrt;
6507 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6508 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt");
6509 }
6510 case NEON::BI__builtin_neon_vrbit_v:
6511 case NEON::BI__builtin_neon_vrbitq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006512 Int = Intrinsic::aarch64_neon_rbit;
Tim Northovera2ee4332014-03-29 15:09:45 +00006513 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit");
6514 }
6515 case NEON::BI__builtin_neon_vaddv_u8:
6516 // FIXME: These are handled by the AArch64 scalar code.
6517 usgn = true;
6518 // FALLTHROUGH
6519 case NEON::BI__builtin_neon_vaddv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006520 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006521 Ty = Int32Ty;
6522 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006523 llvm::Type *Tys[2] = { Ty, VTy };
6524 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6525 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006526 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006527 }
6528 case NEON::BI__builtin_neon_vaddv_u16:
6529 usgn = true;
6530 // FALLTHROUGH
6531 case NEON::BI__builtin_neon_vaddv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006532 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006533 Ty = Int32Ty;
6534 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006535 llvm::Type *Tys[2] = { Ty, VTy };
6536 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6537 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006538 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006539 }
6540 case NEON::BI__builtin_neon_vaddvq_u8:
6541 usgn = true;
6542 // FALLTHROUGH
6543 case NEON::BI__builtin_neon_vaddvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006544 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006545 Ty = Int32Ty;
6546 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006547 llvm::Type *Tys[2] = { Ty, VTy };
6548 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6549 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006550 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006551 }
6552 case NEON::BI__builtin_neon_vaddvq_u16:
6553 usgn = true;
6554 // FALLTHROUGH
6555 case NEON::BI__builtin_neon_vaddvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006556 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006557 Ty = Int32Ty;
6558 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006559 llvm::Type *Tys[2] = { Ty, VTy };
6560 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6561 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006562 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006563 }
6564 case NEON::BI__builtin_neon_vmaxv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006565 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006566 Ty = Int32Ty;
6567 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006568 llvm::Type *Tys[2] = { Ty, VTy };
6569 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6570 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006571 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006572 }
6573 case NEON::BI__builtin_neon_vmaxv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006574 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006575 Ty = Int32Ty;
6576 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006577 llvm::Type *Tys[2] = { Ty, VTy };
6578 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6579 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006580 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006581 }
6582 case NEON::BI__builtin_neon_vmaxvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006583 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006584 Ty = Int32Ty;
6585 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006586 llvm::Type *Tys[2] = { Ty, VTy };
6587 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6588 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006589 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006590 }
6591 case NEON::BI__builtin_neon_vmaxvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006592 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006593 Ty = Int32Ty;
6594 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006595 llvm::Type *Tys[2] = { Ty, VTy };
6596 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6597 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006598 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006599 }
6600 case NEON::BI__builtin_neon_vmaxv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006601 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006602 Ty = Int32Ty;
6603 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006604 llvm::Type *Tys[2] = { Ty, VTy };
6605 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6606 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006607 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006608 }
6609 case NEON::BI__builtin_neon_vmaxv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006610 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006611 Ty = Int32Ty;
6612 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006613 llvm::Type *Tys[2] = { Ty, VTy };
6614 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6615 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006616 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006617 }
6618 case NEON::BI__builtin_neon_vmaxvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006619 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006620 Ty = Int32Ty;
6621 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006622 llvm::Type *Tys[2] = { Ty, VTy };
6623 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6624 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006625 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006626 }
6627 case NEON::BI__builtin_neon_vmaxvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006628 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006629 Ty = Int32Ty;
6630 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006631 llvm::Type *Tys[2] = { Ty, VTy };
6632 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6633 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006634 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006635 }
6636 case NEON::BI__builtin_neon_vminv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006637 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006638 Ty = Int32Ty;
6639 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006640 llvm::Type *Tys[2] = { Ty, VTy };
6641 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6642 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006643 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006644 }
6645 case NEON::BI__builtin_neon_vminv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006646 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006647 Ty = Int32Ty;
6648 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006649 llvm::Type *Tys[2] = { Ty, VTy };
6650 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6651 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006652 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006653 }
6654 case NEON::BI__builtin_neon_vminvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006655 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006656 Ty = Int32Ty;
6657 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006658 llvm::Type *Tys[2] = { Ty, VTy };
6659 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6660 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006661 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006662 }
6663 case NEON::BI__builtin_neon_vminvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006664 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006665 Ty = Int32Ty;
6666 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006667 llvm::Type *Tys[2] = { Ty, VTy };
6668 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6669 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006670 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006671 }
6672 case NEON::BI__builtin_neon_vminv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006673 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006674 Ty = Int32Ty;
6675 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006676 llvm::Type *Tys[2] = { Ty, VTy };
6677 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6678 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006679 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006680 }
6681 case NEON::BI__builtin_neon_vminv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006682 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006683 Ty = Int32Ty;
6684 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006685 llvm::Type *Tys[2] = { Ty, VTy };
6686 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6687 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006688 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006689 }
6690 case NEON::BI__builtin_neon_vminvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006691 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006692 Ty = Int32Ty;
6693 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006694 llvm::Type *Tys[2] = { Ty, VTy };
6695 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6696 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006697 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006698 }
6699 case NEON::BI__builtin_neon_vminvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006700 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006701 Ty = Int32Ty;
6702 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006703 llvm::Type *Tys[2] = { Ty, VTy };
6704 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6705 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006706 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006707 }
6708 case NEON::BI__builtin_neon_vmul_n_f64: {
6709 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6710 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy);
6711 return Builder.CreateFMul(Ops[0], RHS);
6712 }
6713 case NEON::BI__builtin_neon_vaddlv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006714 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006715 Ty = Int32Ty;
6716 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006717 llvm::Type *Tys[2] = { Ty, VTy };
6718 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6719 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006720 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006721 }
6722 case NEON::BI__builtin_neon_vaddlv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006723 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006724 Ty = Int32Ty;
6725 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006726 llvm::Type *Tys[2] = { Ty, VTy };
6727 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6728 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6729 }
6730 case NEON::BI__builtin_neon_vaddlvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006731 Int = Intrinsic::aarch64_neon_uaddlv;
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, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006737 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006738 }
6739 case NEON::BI__builtin_neon_vaddlvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006740 Int = Intrinsic::aarch64_neon_uaddlv;
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 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6746 }
6747 case NEON::BI__builtin_neon_vaddlv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006748 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006749 Ty = Int32Ty;
6750 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006751 llvm::Type *Tys[2] = { Ty, VTy };
6752 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6753 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006754 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006755 }
6756 case NEON::BI__builtin_neon_vaddlv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006757 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006758 Ty = Int32Ty;
6759 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006760 llvm::Type *Tys[2] = { Ty, VTy };
6761 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6762 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6763 }
6764 case NEON::BI__builtin_neon_vaddlvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006765 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006766 Ty = Int32Ty;
6767 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006768 llvm::Type *Tys[2] = { Ty, VTy };
6769 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6770 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006771 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006772 }
6773 case NEON::BI__builtin_neon_vaddlvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006774 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006775 Ty = Int32Ty;
6776 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006777 llvm::Type *Tys[2] = { Ty, VTy };
6778 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6779 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6780 }
6781 case NEON::BI__builtin_neon_vsri_n_v:
6782 case NEON::BI__builtin_neon_vsriq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006783 Int = Intrinsic::aarch64_neon_vsri;
Tim Northovera2ee4332014-03-29 15:09:45 +00006784 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6785 return EmitNeonCall(Intrin, Ops, "vsri_n");
6786 }
6787 case NEON::BI__builtin_neon_vsli_n_v:
6788 case NEON::BI__builtin_neon_vsliq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006789 Int = Intrinsic::aarch64_neon_vsli;
Tim Northovera2ee4332014-03-29 15:09:45 +00006790 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6791 return EmitNeonCall(Intrin, Ops, "vsli_n");
6792 }
6793 case NEON::BI__builtin_neon_vsra_n_v:
6794 case NEON::BI__builtin_neon_vsraq_n_v:
6795 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6796 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
6797 return Builder.CreateAdd(Ops[0], Ops[1]);
6798 case NEON::BI__builtin_neon_vrsra_n_v:
6799 case NEON::BI__builtin_neon_vrsraq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006800 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006801 SmallVector<llvm::Value*,2> TmpOps;
6802 TmpOps.push_back(Ops[1]);
6803 TmpOps.push_back(Ops[2]);
6804 Function* F = CGM.getIntrinsic(Int, Ty);
6805 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true);
6806 Ops[0] = Builder.CreateBitCast(Ops[0], VTy);
6807 return Builder.CreateAdd(Ops[0], tmp);
6808 }
6809 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence
6810 // of an Align parameter here.
6811 case NEON::BI__builtin_neon_vld1_x2_v:
6812 case NEON::BI__builtin_neon_vld1q_x2_v:
6813 case NEON::BI__builtin_neon_vld1_x3_v:
6814 case NEON::BI__builtin_neon_vld1q_x3_v:
6815 case NEON::BI__builtin_neon_vld1_x4_v:
6816 case NEON::BI__builtin_neon_vld1q_x4_v: {
6817 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6818 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6819 llvm::Type *Tys[2] = { VTy, PTy };
6820 unsigned Int;
6821 switch (BuiltinID) {
6822 case NEON::BI__builtin_neon_vld1_x2_v:
6823 case NEON::BI__builtin_neon_vld1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006824 Int = Intrinsic::aarch64_neon_ld1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006825 break;
6826 case NEON::BI__builtin_neon_vld1_x3_v:
6827 case NEON::BI__builtin_neon_vld1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006828 Int = Intrinsic::aarch64_neon_ld1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006829 break;
6830 case NEON::BI__builtin_neon_vld1_x4_v:
6831 case NEON::BI__builtin_neon_vld1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006832 Int = Intrinsic::aarch64_neon_ld1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006833 break;
6834 }
6835 Function *F = CGM.getIntrinsic(Int, Tys);
6836 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN");
6837 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6838 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006839 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006840 }
6841 case NEON::BI__builtin_neon_vst1_x2_v:
6842 case NEON::BI__builtin_neon_vst1q_x2_v:
6843 case NEON::BI__builtin_neon_vst1_x3_v:
6844 case NEON::BI__builtin_neon_vst1q_x3_v:
6845 case NEON::BI__builtin_neon_vst1_x4_v:
6846 case NEON::BI__builtin_neon_vst1q_x4_v: {
6847 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6848 llvm::Type *Tys[2] = { VTy, PTy };
6849 unsigned Int;
6850 switch (BuiltinID) {
6851 case NEON::BI__builtin_neon_vst1_x2_v:
6852 case NEON::BI__builtin_neon_vst1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006853 Int = Intrinsic::aarch64_neon_st1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006854 break;
6855 case NEON::BI__builtin_neon_vst1_x3_v:
6856 case NEON::BI__builtin_neon_vst1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006857 Int = Intrinsic::aarch64_neon_st1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006858 break;
6859 case NEON::BI__builtin_neon_vst1_x4_v:
6860 case NEON::BI__builtin_neon_vst1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006861 Int = Intrinsic::aarch64_neon_st1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006862 break;
6863 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00006864 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6865 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
Tim Northovera2ee4332014-03-29 15:09:45 +00006866 }
6867 case NEON::BI__builtin_neon_vld1_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00006868 case NEON::BI__builtin_neon_vld1q_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006869 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
Peter Collingbourneb367c562016-11-28 22:30:21 +00006870 auto Alignment = CharUnits::fromQuantity(
6871 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16);
6872 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment);
6873 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006874 case NEON::BI__builtin_neon_vst1_v:
6875 case NEON::BI__builtin_neon_vst1q_v:
6876 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
6877 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
John McCall7f416cc2015-09-08 08:05:57 +00006878 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006879 case NEON::BI__builtin_neon_vld1_lane_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00006880 case NEON::BI__builtin_neon_vld1q_lane_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006881 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6882 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
6883 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00006884 auto Alignment = CharUnits::fromQuantity(
6885 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16);
6886 Ops[0] =
6887 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Tim Northovera2ee4332014-03-29 15:09:45 +00006888 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane");
Peter Collingbourneb367c562016-11-28 22:30:21 +00006889 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006890 case NEON::BI__builtin_neon_vld1_dup_v:
6891 case NEON::BI__builtin_neon_vld1q_dup_v: {
6892 Value *V = UndefValue::get(Ty);
6893 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
6894 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00006895 auto Alignment = CharUnits::fromQuantity(
6896 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16);
6897 Ops[0] =
6898 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Michael J. Spencer5ce26682014-06-02 19:48:59 +00006899 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006900 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI);
6901 return EmitNeonSplat(Ops[0], CI);
6902 }
6903 case NEON::BI__builtin_neon_vst1_lane_v:
6904 case NEON::BI__builtin_neon_vst1q_lane_v:
6905 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6906 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
6907 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00006908 return Builder.CreateDefaultAlignedStore(Ops[1],
6909 Builder.CreateBitCast(Ops[0], Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00006910 case NEON::BI__builtin_neon_vld2_v:
6911 case NEON::BI__builtin_neon_vld2q_v: {
6912 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
6913 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6914 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006915 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006916 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
6917 Ops[0] = Builder.CreateBitCast(Ops[0],
6918 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006919 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006920 }
6921 case NEON::BI__builtin_neon_vld3_v:
6922 case NEON::BI__builtin_neon_vld3q_v: {
6923 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
6924 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6925 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006926 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006927 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
6928 Ops[0] = Builder.CreateBitCast(Ops[0],
6929 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006930 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006931 }
6932 case NEON::BI__builtin_neon_vld4_v:
6933 case NEON::BI__builtin_neon_vld4q_v: {
6934 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
6935 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6936 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006937 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006938 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
6939 Ops[0] = Builder.CreateBitCast(Ops[0],
6940 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006941 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006942 }
Tim Northover74b2def2014-04-01 10:37:47 +00006943 case NEON::BI__builtin_neon_vld2_dup_v:
6944 case NEON::BI__builtin_neon_vld2q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006945 llvm::Type *PTy =
6946 llvm::PointerType::getUnqual(VTy->getElementType());
6947 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6948 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006949 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006950 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
6951 Ops[0] = Builder.CreateBitCast(Ops[0],
6952 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006953 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006954 }
Tim Northover74b2def2014-04-01 10:37:47 +00006955 case NEON::BI__builtin_neon_vld3_dup_v:
6956 case NEON::BI__builtin_neon_vld3q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006957 llvm::Type *PTy =
6958 llvm::PointerType::getUnqual(VTy->getElementType());
6959 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6960 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006961 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006962 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
6963 Ops[0] = Builder.CreateBitCast(Ops[0],
6964 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006965 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006966 }
Tim Northover74b2def2014-04-01 10:37:47 +00006967 case NEON::BI__builtin_neon_vld4_dup_v:
6968 case NEON::BI__builtin_neon_vld4q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006969 llvm::Type *PTy =
6970 llvm::PointerType::getUnqual(VTy->getElementType());
6971 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6972 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006973 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006974 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
6975 Ops[0] = Builder.CreateBitCast(Ops[0],
6976 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006977 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006978 }
6979 case NEON::BI__builtin_neon_vld2_lane_v:
6980 case NEON::BI__builtin_neon_vld2q_lane_v: {
6981 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006982 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006983 Ops.push_back(Ops[1]);
6984 Ops.erase(Ops.begin()+1);
6985 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6986 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00006987 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00006988 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00006989 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6990 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006991 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006992 }
6993 case NEON::BI__builtin_neon_vld3_lane_v:
6994 case NEON::BI__builtin_neon_vld3q_lane_v: {
6995 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006996 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006997 Ops.push_back(Ops[1]);
6998 Ops.erase(Ops.begin()+1);
6999 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7000 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
7001 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007002 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007003 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007004 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7005 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007006 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007007 }
7008 case NEON::BI__builtin_neon_vld4_lane_v:
7009 case NEON::BI__builtin_neon_vld4q_lane_v: {
7010 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007011 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007012 Ops.push_back(Ops[1]);
7013 Ops.erase(Ops.begin()+1);
7014 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7015 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
7016 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
7017 Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007018 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007019 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007020 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7021 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007022 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007023 }
7024 case NEON::BI__builtin_neon_vst2_v:
7025 case NEON::BI__builtin_neon_vst2q_v: {
7026 Ops.push_back(Ops[0]);
7027 Ops.erase(Ops.begin());
7028 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007029 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007030 Ops, "");
7031 }
7032 case NEON::BI__builtin_neon_vst2_lane_v:
7033 case NEON::BI__builtin_neon_vst2q_lane_v: {
7034 Ops.push_back(Ops[0]);
7035 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007036 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007037 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007038 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007039 Ops, "");
7040 }
7041 case NEON::BI__builtin_neon_vst3_v:
7042 case NEON::BI__builtin_neon_vst3q_v: {
7043 Ops.push_back(Ops[0]);
7044 Ops.erase(Ops.begin());
7045 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007046 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007047 Ops, "");
7048 }
7049 case NEON::BI__builtin_neon_vst3_lane_v:
7050 case NEON::BI__builtin_neon_vst3q_lane_v: {
7051 Ops.push_back(Ops[0]);
7052 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007053 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007054 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007055 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007056 Ops, "");
7057 }
7058 case NEON::BI__builtin_neon_vst4_v:
7059 case NEON::BI__builtin_neon_vst4q_v: {
7060 Ops.push_back(Ops[0]);
7061 Ops.erase(Ops.begin());
7062 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007063 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007064 Ops, "");
7065 }
7066 case NEON::BI__builtin_neon_vst4_lane_v:
7067 case NEON::BI__builtin_neon_vst4q_lane_v: {
7068 Ops.push_back(Ops[0]);
7069 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007070 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007071 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007072 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007073 Ops, "");
7074 }
7075 case NEON::BI__builtin_neon_vtrn_v:
7076 case NEON::BI__builtin_neon_vtrnq_v: {
7077 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7078 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7079 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007080 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007081
7082 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007083 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007084 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007085 Indices.push_back(i+vi);
7086 Indices.push_back(i+e+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007087 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007088 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007089 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00007090 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007091 }
7092 return SV;
7093 }
7094 case NEON::BI__builtin_neon_vuzp_v:
7095 case NEON::BI__builtin_neon_vuzpq_v: {
7096 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7097 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7098 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007099 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007100
7101 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007102 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007103 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00007104 Indices.push_back(2*i+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007105
David Blaikiefb901c7a2015-04-04 15:12:29 +00007106 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007107 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00007108 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007109 }
7110 return SV;
7111 }
7112 case NEON::BI__builtin_neon_vzip_v:
7113 case NEON::BI__builtin_neon_vzipq_v: {
7114 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7115 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7116 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007117 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007118
7119 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007120 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007121 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007122 Indices.push_back((i + vi*e) >> 1);
7123 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northovera2ee4332014-03-29 15:09:45 +00007124 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007125 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007126 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00007127 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007128 }
7129 return SV;
7130 }
7131 case NEON::BI__builtin_neon_vqtbl1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007132 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007133 Ops, "vtbl1");
7134 }
7135 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007136 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007137 Ops, "vtbl2");
7138 }
7139 case NEON::BI__builtin_neon_vqtbl3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007140 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007141 Ops, "vtbl3");
7142 }
7143 case NEON::BI__builtin_neon_vqtbl4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007144 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007145 Ops, "vtbl4");
7146 }
7147 case NEON::BI__builtin_neon_vqtbx1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007148 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007149 Ops, "vtbx1");
7150 }
7151 case NEON::BI__builtin_neon_vqtbx2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007152 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007153 Ops, "vtbx2");
7154 }
7155 case NEON::BI__builtin_neon_vqtbx3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007156 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007157 Ops, "vtbx3");
7158 }
7159 case NEON::BI__builtin_neon_vqtbx4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007160 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007161 Ops, "vtbx4");
7162 }
7163 case NEON::BI__builtin_neon_vsqadd_v:
7164 case NEON::BI__builtin_neon_vsqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007165 Int = Intrinsic::aarch64_neon_usqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007166 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd");
7167 }
7168 case NEON::BI__builtin_neon_vuqadd_v:
7169 case NEON::BI__builtin_neon_vuqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007170 Int = Intrinsic::aarch64_neon_suqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007171 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
7172 }
7173 }
7174}
7175
Bill Wendling65b2a962010-10-09 08:47:25 +00007176llvm::Value *CodeGenFunction::
Bill Wendlingf1a3fca2012-02-22 09:30:11 +00007177BuildVector(ArrayRef<llvm::Value*> Ops) {
Bill Wendling65b2a962010-10-09 08:47:25 +00007178 assert((Ops.size() & (Ops.size() - 1)) == 0 &&
7179 "Not a power-of-two sized vector!");
7180 bool AllConstants = true;
7181 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i)
7182 AllConstants &= isa<Constant>(Ops[i]);
7183
7184 // If this is a constant vector, create a ConstantVector.
7185 if (AllConstants) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007186 SmallVector<llvm::Constant*, 16> CstOps;
Bill Wendling65b2a962010-10-09 08:47:25 +00007187 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
7188 CstOps.push_back(cast<Constant>(Ops[i]));
7189 return llvm::ConstantVector::get(CstOps);
7190 }
7191
7192 // Otherwise, insertelement the values to build the vector.
7193 Value *Result =
7194 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size()));
7195
7196 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007197 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i));
Bill Wendling65b2a962010-10-09 08:47:25 +00007198
7199 return Result;
7200}
7201
Igor Bregeraadb8762016-06-08 13:59:20 +00007202// Convert the mask from an integer type to a vector of i1.
7203static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask,
7204 unsigned NumElts) {
7205
7206 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(),
7207 cast<IntegerType>(Mask->getType())->getBitWidth());
7208 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy);
7209
7210 // If we have less than 8 elements, then the starting mask was an i8 and
7211 // we need to extract down to the right number of elements.
7212 if (NumElts < 8) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007213 uint32_t Indices[4];
Igor Bregeraadb8762016-06-08 13:59:20 +00007214 for (unsigned i = 0; i != NumElts; ++i)
7215 Indices[i] = i;
7216 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec,
7217 makeArrayRef(Indices, NumElts),
7218 "extract");
7219 }
7220 return MaskVec;
7221}
7222
Craig Topper6e891fb2016-05-31 01:50:10 +00007223static Value *EmitX86MaskedStore(CodeGenFunction &CGF,
7224 SmallVectorImpl<Value *> &Ops,
7225 unsigned Align) {
7226 // Cast the pointer to right type.
7227 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7228 llvm::PointerType::getUnqual(Ops[1]->getType()));
7229
7230 // If the mask is all ones just emit a regular store.
7231 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7232 if (C->isAllOnesValue())
7233 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align);
7234
Igor Bregeraadb8762016-06-08 13:59:20 +00007235 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7236 Ops[1]->getType()->getVectorNumElements());
Craig Topper6e891fb2016-05-31 01:50:10 +00007237
Igor Bregeraadb8762016-06-08 13:59:20 +00007238 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec);
Craig Topper6e891fb2016-05-31 01:50:10 +00007239}
7240
Craig Topper4b060e32016-05-31 06:58:07 +00007241static Value *EmitX86MaskedLoad(CodeGenFunction &CGF,
7242 SmallVectorImpl<Value *> &Ops, unsigned Align) {
7243 // Cast the pointer to right type.
7244 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7245 llvm::PointerType::getUnqual(Ops[1]->getType()));
7246
7247 // If the mask is all ones just emit a regular store.
7248 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7249 if (C->isAllOnesValue())
7250 return CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7251
Igor Bregeraadb8762016-06-08 13:59:20 +00007252 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7253 Ops[1]->getType()->getVectorNumElements());
Craig Topper4b060e32016-05-31 06:58:07 +00007254
Igor Bregeraadb8762016-06-08 13:59:20 +00007255 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]);
7256}
Craig Topper4b060e32016-05-31 06:58:07 +00007257
Simon Pilgrim2d851732016-07-22 13:58:56 +00007258static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF,
7259 SmallVectorImpl<Value *> &Ops,
7260 llvm::Type *DstTy,
7261 unsigned SrcSizeInBits,
7262 unsigned Align) {
7263 // Load the subvector.
7264 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7265
7266 // Create broadcast mask.
7267 unsigned NumDstElts = DstTy->getVectorNumElements();
7268 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits();
7269
7270 SmallVector<uint32_t, 8> Mask;
7271 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts)
7272 for (unsigned j = 0; j != NumSrcElts; ++j)
7273 Mask.push_back(j);
7274
7275 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst");
7276}
7277
Igor Bregeraadb8762016-06-08 13:59:20 +00007278static Value *EmitX86Select(CodeGenFunction &CGF,
Craig Topperc1442972016-06-09 05:15:00 +00007279 Value *Mask, Value *Op0, Value *Op1) {
Igor Bregeraadb8762016-06-08 13:59:20 +00007280
7281 // If the mask is all ones just return first argument.
Craig Topperc1442972016-06-09 05:15:00 +00007282 if (const auto *C = dyn_cast<Constant>(Mask))
Igor Bregeraadb8762016-06-08 13:59:20 +00007283 if (C->isAllOnesValue())
Craig Topperc1442972016-06-09 05:15:00 +00007284 return Op0;
Igor Bregeraadb8762016-06-08 13:59:20 +00007285
Craig Topperc1442972016-06-09 05:15:00 +00007286 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements());
Igor Bregeraadb8762016-06-08 13:59:20 +00007287
Craig Topperc1442972016-06-09 05:15:00 +00007288 return CGF.Builder.CreateSelect(Mask, Op0, Op1);
Craig Topper4b060e32016-05-31 06:58:07 +00007289}
7290
Craig Topperd1691c72016-06-22 04:47:58 +00007291static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC,
7292 bool Signed, SmallVectorImpl<Value *> &Ops) {
Craig Toppera54c21e2016-06-15 14:06:34 +00007293 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topperd1691c72016-06-22 04:47:58 +00007294 Value *Cmp;
Craig Toppera54c21e2016-06-15 14:06:34 +00007295
Craig Topperd1691c72016-06-22 04:47:58 +00007296 if (CC == 3) {
7297 Cmp = Constant::getNullValue(
7298 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7299 } else if (CC == 7) {
7300 Cmp = Constant::getAllOnesValue(
7301 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7302 } else {
7303 ICmpInst::Predicate Pred;
7304 switch (CC) {
7305 default: llvm_unreachable("Unknown condition code");
7306 case 0: Pred = ICmpInst::ICMP_EQ; break;
7307 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
7308 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
7309 case 4: Pred = ICmpInst::ICMP_NE; break;
7310 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
7311 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
7312 }
7313 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7314 }
7315
7316 const auto *C = dyn_cast<Constant>(Ops.back());
Craig Toppera54c21e2016-06-15 14:06:34 +00007317 if (!C || !C->isAllOnesValue())
Craig Topperd1691c72016-06-22 04:47:58 +00007318 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts));
Craig Toppera54c21e2016-06-15 14:06:34 +00007319
7320 if (NumElts < 8) {
7321 uint32_t Indices[8];
7322 for (unsigned i = 0; i != NumElts; ++i)
7323 Indices[i] = i;
7324 for (unsigned i = NumElts; i != 8; ++i)
Craig Topperac1823f2016-07-04 07:09:46 +00007325 Indices[i] = i % NumElts + NumElts;
Igor Breger2c880cf2016-06-29 08:14:17 +00007326 Cmp = CGF.Builder.CreateShuffleVector(
7327 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices);
Craig Toppera54c21e2016-06-15 14:06:34 +00007328 }
7329 return CGF.Builder.CreateBitCast(Cmp,
7330 IntegerType::get(CGF.getLLVMContext(),
7331 std::max(NumElts, 8U)));
7332}
7333
Craig Topper531ce282016-10-24 04:04:24 +00007334static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred,
7335 ArrayRef<Value *> Ops) {
7336 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7337 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]);
7338
7339 if (Ops.size() == 2)
7340 return Res;
7341
7342 assert(Ops.size() == 4);
7343 return EmitX86Select(CGF, Ops[3], Res, Ops[2]);
7344}
7345
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007346static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op,
7347 llvm::Type *DstTy) {
7348 unsigned NumberOfElements = DstTy->getVectorNumElements();
7349 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements);
7350 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2");
7351}
7352
Erich Keane9937b132017-09-01 19:42:45 +00007353Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007354 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
7355 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
Erich Keane9937b132017-09-01 19:42:45 +00007356 return EmitX86CpuIs(CPUStr);
7357}
7358
7359Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007360
7361 // This enum contains the vendor, type, and subtype enums from the
7362 // runtime library concatenated together. The _START labels mark
7363 // the start and are used to adjust the value into the correct
7364 // encoding space.
7365 enum X86CPUs {
7366 INTEL = 1,
7367 AMD,
7368 CPU_TYPE_START,
7369 INTEL_BONNELL,
7370 INTEL_CORE2,
7371 INTEL_COREI7,
7372 AMDFAM10H,
7373 AMDFAM15H,
7374 INTEL_SILVERMONT,
7375 INTEL_KNL,
7376 AMD_BTVER1,
7377 AMD_BTVER2,
7378 CPU_SUBTYPE_START,
7379 INTEL_COREI7_NEHALEM,
7380 INTEL_COREI7_WESTMERE,
7381 INTEL_COREI7_SANDYBRIDGE,
7382 AMDFAM10H_BARCELONA,
7383 AMDFAM10H_SHANGHAI,
7384 AMDFAM10H_ISTANBUL,
7385 AMDFAM15H_BDVER1,
7386 AMDFAM15H_BDVER2,
7387 AMDFAM15H_BDVER3,
7388 AMDFAM15H_BDVER4,
7389 AMDFAM17H_ZNVER1,
7390 INTEL_COREI7_IVYBRIDGE,
7391 INTEL_COREI7_HASWELL,
7392 INTEL_COREI7_BROADWELL,
7393 INTEL_COREI7_SKYLAKE,
7394 INTEL_COREI7_SKYLAKE_AVX512,
7395 };
7396
7397 X86CPUs CPU =
7398 StringSwitch<X86CPUs>(CPUStr)
7399 .Case("amd", AMD)
7400 .Case("amdfam10h", AMDFAM10H)
Erich Keane9937b132017-09-01 19:42:45 +00007401 .Case("amdfam10", AMDFAM10H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007402 .Case("amdfam15h", AMDFAM15H)
Erich Keane9937b132017-09-01 19:42:45 +00007403 .Case("amdfam15", AMDFAM15H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007404 .Case("atom", INTEL_BONNELL)
7405 .Case("barcelona", AMDFAM10H_BARCELONA)
7406 .Case("bdver1", AMDFAM15H_BDVER1)
7407 .Case("bdver2", AMDFAM15H_BDVER2)
7408 .Case("bdver3", AMDFAM15H_BDVER3)
7409 .Case("bdver4", AMDFAM15H_BDVER4)
7410 .Case("bonnell", INTEL_BONNELL)
7411 .Case("broadwell", INTEL_COREI7_BROADWELL)
7412 .Case("btver1", AMD_BTVER1)
7413 .Case("btver2", AMD_BTVER2)
7414 .Case("core2", INTEL_CORE2)
7415 .Case("corei7", INTEL_COREI7)
7416 .Case("haswell", INTEL_COREI7_HASWELL)
7417 .Case("intel", INTEL)
7418 .Case("istanbul", AMDFAM10H_ISTANBUL)
7419 .Case("ivybridge", INTEL_COREI7_IVYBRIDGE)
7420 .Case("knl", INTEL_KNL)
7421 .Case("nehalem", INTEL_COREI7_NEHALEM)
7422 .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE)
7423 .Case("shanghai", AMDFAM10H_SHANGHAI)
7424 .Case("silvermont", INTEL_SILVERMONT)
7425 .Case("skylake", INTEL_COREI7_SKYLAKE)
7426 .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512)
7427 .Case("slm", INTEL_SILVERMONT)
7428 .Case("westmere", INTEL_COREI7_WESTMERE)
7429 .Case("znver1", AMDFAM17H_ZNVER1);
7430
Erich Keane9937b132017-09-01 19:42:45 +00007431 llvm::Type *Int32Ty = Builder.getInt32Ty();
Craig Topper699ae0c2017-08-10 20:28:30 +00007432
7433 // Matching the struct layout from the compiler-rt/libgcc structure that is
7434 // filled in:
7435 // unsigned int __cpu_vendor;
7436 // unsigned int __cpu_type;
7437 // unsigned int __cpu_subtype;
7438 // unsigned int __cpu_features[1];
7439 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7440 llvm::ArrayType::get(Int32Ty, 1));
7441
7442 // Grab the global __cpu_model.
Erich Keane9937b132017-09-01 19:42:45 +00007443 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
Craig Topper699ae0c2017-08-10 20:28:30 +00007444
7445 // Calculate the index needed to access the correct field based on the
7446 // range. Also adjust the expected value.
7447 unsigned Index;
7448 unsigned Value;
7449 if (CPU > CPU_SUBTYPE_START) {
7450 Index = 2;
7451 Value = CPU - CPU_SUBTYPE_START;
7452 } else if (CPU > CPU_TYPE_START) {
7453 Index = 1;
7454 Value = CPU - CPU_TYPE_START;
7455 } else {
7456 Index = 0;
7457 Value = CPU;
7458 }
7459
7460 // Grab the appropriate field from __cpu_model.
7461 llvm::Value *Idxs[] = {
7462 ConstantInt::get(Int32Ty, 0),
7463 ConstantInt::get(Int32Ty, Index)
7464 };
Erich Keane9937b132017-09-01 19:42:45 +00007465 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs);
7466 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4));
Craig Topper699ae0c2017-08-10 20:28:30 +00007467
7468 // Check the value of the field against the requested value.
Erich Keane9937b132017-09-01 19:42:45 +00007469 return Builder.CreateICmpEQ(CpuValue,
Craig Topper699ae0c2017-08-10 20:28:30 +00007470 llvm::ConstantInt::get(Int32Ty, Value));
7471}
7472
Erich Keane9937b132017-09-01 19:42:45 +00007473Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) {
7474 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts();
7475 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString();
7476 return EmitX86CpuSupports(FeatureStr);
7477}
7478
7479Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) {
7480 // TODO: When/if this becomes more than x86 specific then use a TargetInfo
7481 // based mapping.
7482 // Processor features and mapping to processor feature value.
7483 enum X86Features {
7484 CMOV = 0,
7485 MMX,
7486 POPCNT,
7487 SSE,
7488 SSE2,
7489 SSE3,
7490 SSSE3,
7491 SSE4_1,
7492 SSE4_2,
7493 AVX,
7494 AVX2,
7495 SSE4_A,
7496 FMA4,
7497 XOP,
7498 FMA,
7499 AVX512F,
7500 BMI,
7501 BMI2,
7502 AES,
7503 PCLMUL,
7504 AVX512VL,
7505 AVX512BW,
7506 AVX512DQ,
7507 AVX512CD,
7508 AVX512ER,
7509 AVX512PF,
7510 AVX512VBMI,
7511 AVX512IFMA,
7512 AVX5124VNNIW,
7513 AVX5124FMAPS,
7514 AVX512VPOPCNTDQ,
7515 MAX
7516 };
7517
7518 uint32_t FeaturesMask = 0;
7519
7520 for (const StringRef &FeatureStr : FeatureStrs) {
7521 X86Features Feature =
7522 StringSwitch<X86Features>(FeatureStr)
7523 .Case("cmov", X86Features::CMOV)
7524 .Case("mmx", X86Features::MMX)
7525 .Case("popcnt", X86Features::POPCNT)
7526 .Case("sse", X86Features::SSE)
7527 .Case("sse2", X86Features::SSE2)
7528 .Case("sse3", X86Features::SSE3)
7529 .Case("ssse3", X86Features::SSSE3)
7530 .Case("sse4.1", X86Features::SSE4_1)
7531 .Case("sse4.2", X86Features::SSE4_2)
7532 .Case("avx", X86Features::AVX)
7533 .Case("avx2", X86Features::AVX2)
7534 .Case("sse4a", X86Features::SSE4_A)
7535 .Case("fma4", X86Features::FMA4)
7536 .Case("xop", X86Features::XOP)
7537 .Case("fma", X86Features::FMA)
7538 .Case("avx512f", X86Features::AVX512F)
7539 .Case("bmi", X86Features::BMI)
7540 .Case("bmi2", X86Features::BMI2)
7541 .Case("aes", X86Features::AES)
7542 .Case("pclmul", X86Features::PCLMUL)
7543 .Case("avx512vl", X86Features::AVX512VL)
7544 .Case("avx512bw", X86Features::AVX512BW)
7545 .Case("avx512dq", X86Features::AVX512DQ)
7546 .Case("avx512cd", X86Features::AVX512CD)
7547 .Case("avx512er", X86Features::AVX512ER)
7548 .Case("avx512pf", X86Features::AVX512PF)
7549 .Case("avx512vbmi", X86Features::AVX512VBMI)
7550 .Case("avx512ifma", X86Features::AVX512IFMA)
7551 .Case("avx5124vnniw", X86Features::AVX5124VNNIW)
7552 .Case("avx5124fmaps", X86Features::AVX5124FMAPS)
7553 .Case("avx512vpopcntdq", X86Features::AVX512VPOPCNTDQ)
7554 .Default(X86Features::MAX);
7555 assert(Feature != X86Features::MAX && "Invalid feature!");
7556 FeaturesMask |= (1U << Feature);
7557 }
7558
7559 // Matching the struct layout from the compiler-rt/libgcc structure that is
7560 // filled in:
7561 // unsigned int __cpu_vendor;
7562 // unsigned int __cpu_type;
7563 // unsigned int __cpu_subtype;
7564 // unsigned int __cpu_features[1];
7565 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7566 llvm::ArrayType::get(Int32Ty, 1));
7567
7568 // Grab the global __cpu_model.
7569 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
7570
7571 // Grab the first (0th) element from the field __cpu_features off of the
7572 // global in the struct STy.
7573 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3),
7574 ConstantInt::get(Int32Ty, 0)};
7575 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs);
7576 Value *Features =
7577 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4));
7578
7579 // Check the value of the bit corresponding to the feature requested.
7580 Value *Bitset = Builder.CreateAnd(
7581 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask));
7582 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0));
7583}
7584
Mike Stump11289f42009-09-09 15:08:12 +00007585Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00007586 const CallExpr *E) {
Erich Keane9937b132017-09-01 19:42:45 +00007587 if (BuiltinID == X86::BI__builtin_cpu_is)
7588 return EmitX86CpuIs(E);
7589 if (BuiltinID == X86::BI__builtin_cpu_supports)
7590 return EmitX86CpuSupports(E);
7591
Chris Lattner0e62c1c2011-07-23 10:55:15 +00007592 SmallVector<Value*, 4> Ops;
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007593
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007594 // Find out if any arguments are required to be integer constant expressions.
7595 unsigned ICEArguments = 0;
7596 ASTContext::GetBuiltinTypeError Error;
7597 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
7598 assert(Error == ASTContext::GE_None && "Should not codegen an error");
7599
7600 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
7601 // If this is a normal argument, just emit it as a scalar.
7602 if ((ICEArguments & (1 << i)) == 0) {
7603 Ops.push_back(EmitScalarExpr(E->getArg(i)));
7604 continue;
7605 }
7606
7607 // If this is required to be a constant, constant fold it so that we know
7608 // that the generated intrinsic gets a ConstantInt.
7609 llvm::APSInt Result;
7610 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
7611 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00007612 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007613 }
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007614
Sanjay Patel280cfd12016-06-15 21:20:04 +00007615 // These exist so that the builtin that takes an immediate can be bounds
7616 // checked by clang to avoid passing bad immediates to the backend. Since
7617 // AVX has a larger immediate than SSE we would need separate builtins to
7618 // do the different bounds checking. Rather than create a clang specific
7619 // SSE only builtin, this implements eight separate builtins to match gcc
7620 // implementation.
7621 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) {
7622 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm));
7623 llvm::Function *F = CGM.getIntrinsic(ID);
7624 return Builder.CreateCall(F, Ops);
7625 };
7626
7627 // For the vector forms of FP comparisons, translate the builtins directly to
7628 // IR.
7629 // TODO: The builtins could be removed if the SSE header files used vector
7630 // extension comparisons directly (vector ordered/unordered may need
7631 // additional support via __builtin_isnan()).
Craig Topper01600632016-07-08 01:57:24 +00007632 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) {
Sanjay Patel280cfd12016-06-15 21:20:04 +00007633 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]);
Craig Topper01600632016-07-08 01:57:24 +00007634 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType());
Sanjay Patel280cfd12016-06-15 21:20:04 +00007635 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy);
7636 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy);
7637 return Builder.CreateBitCast(Sext, FPVecTy);
7638 };
7639
Anders Carlsson895af082007-12-09 23:17:02 +00007640 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00007641 default: return nullptr;
Craig Topper2c03e532017-08-28 05:43:23 +00007642 case X86::BI__builtin_cpu_init: {
7643 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
7644 /*Variadic*/false);
7645 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy,
7646 "__cpu_indicator_init");
7647 return Builder.CreateCall(Func);
7648 }
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007649 case X86::BI_mm_prefetch: {
John McCall7f416cc2015-09-08 08:05:57 +00007650 Value *Address = Ops[0];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007651 Value *RW = ConstantInt::get(Int32Ty, 0);
John McCall7f416cc2015-09-08 08:05:57 +00007652 Value *Locality = Ops[1];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007653 Value *Data = ConstantInt::get(Int32Ty, 1);
7654 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00007655 return Builder.CreateCall(F, {Address, RW, Locality, Data});
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007656 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007657 case X86::BI_mm_clflush: {
7658 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush),
7659 Ops[0]);
7660 }
7661 case X86::BI_mm_lfence: {
7662 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence));
7663 }
7664 case X86::BI_mm_mfence: {
7665 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence));
7666 }
7667 case X86::BI_mm_sfence: {
7668 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence));
7669 }
7670 case X86::BI_mm_pause: {
7671 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause));
7672 }
7673 case X86::BI__rdtsc: {
7674 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc));
7675 }
Simon Pilgrim5aba9922015-08-26 21:17:12 +00007676 case X86::BI__builtin_ia32_undef128:
7677 case X86::BI__builtin_ia32_undef256:
7678 case X86::BI__builtin_ia32_undef512:
Sanjay Patele795daa2017-03-12 19:15:10 +00007679 // The x86 definition of "undef" is not the same as the LLVM definition
7680 // (PR32176). We leave optimizing away an unnecessary zero constant to the
7681 // IR optimizer and backend.
7682 // TODO: If we had a "freeze" IR instruction to generate a fixed undef
7683 // value, we should use that here instead of a zero.
7684 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Bill Wendling65b2a962010-10-09 08:47:25 +00007685 case X86::BI__builtin_ia32_vec_init_v8qi:
7686 case X86::BI__builtin_ia32_vec_init_v4hi:
7687 case X86::BI__builtin_ia32_vec_init_v2si:
7688 return Builder.CreateBitCast(BuildVector(Ops),
John McCallad7c5c12011-02-08 08:22:06 +00007689 llvm::Type::getX86_MMXTy(getLLVMContext()));
Argyrios Kyrtzidis073c9cb2010-10-10 03:19:11 +00007690 case X86::BI__builtin_ia32_vec_ext_v2si:
7691 return Builder.CreateExtractElement(Ops[0],
7692 llvm::ConstantInt::get(Ops[1]->getType(), 0));
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007693 case X86::BI_mm_setcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007694 case X86::BI__builtin_ia32_ldmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007695 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Nate Begeman91f40e32008-04-14 04:49:57 +00007696 Builder.CreateStore(Ops[0], Tmp);
7697 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007698 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007699 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007700 case X86::BI_mm_getcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007701 case X86::BI__builtin_ia32_stmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007702 Address Tmp = CreateMemTemp(E->getType());
Ted Kremenekc14efa72011-08-17 21:04:19 +00007703 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007704 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007705 return Builder.CreateLoad(Tmp, "stmxcsr");
7706 }
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007707 case X86::BI__builtin_ia32_xsave:
7708 case X86::BI__builtin_ia32_xsave64:
7709 case X86::BI__builtin_ia32_xrstor:
7710 case X86::BI__builtin_ia32_xrstor64:
7711 case X86::BI__builtin_ia32_xsaveopt:
7712 case X86::BI__builtin_ia32_xsaveopt64:
7713 case X86::BI__builtin_ia32_xrstors:
7714 case X86::BI__builtin_ia32_xrstors64:
7715 case X86::BI__builtin_ia32_xsavec:
7716 case X86::BI__builtin_ia32_xsavec64:
7717 case X86::BI__builtin_ia32_xsaves:
Reid Kleckner66e77172016-08-16 16:04:14 +00007718 case X86::BI__builtin_ia32_xsaves64: {
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007719 Intrinsic::ID ID;
7720#define INTRINSIC_X86_XSAVE_ID(NAME) \
7721 case X86::BI__builtin_ia32_##NAME: \
7722 ID = Intrinsic::x86_##NAME; \
7723 break
7724 switch (BuiltinID) {
7725 default: llvm_unreachable("Unsupported intrinsic!");
7726 INTRINSIC_X86_XSAVE_ID(xsave);
7727 INTRINSIC_X86_XSAVE_ID(xsave64);
7728 INTRINSIC_X86_XSAVE_ID(xrstor);
7729 INTRINSIC_X86_XSAVE_ID(xrstor64);
7730 INTRINSIC_X86_XSAVE_ID(xsaveopt);
7731 INTRINSIC_X86_XSAVE_ID(xsaveopt64);
7732 INTRINSIC_X86_XSAVE_ID(xrstors);
7733 INTRINSIC_X86_XSAVE_ID(xrstors64);
7734 INTRINSIC_X86_XSAVE_ID(xsavec);
7735 INTRINSIC_X86_XSAVE_ID(xsavec64);
7736 INTRINSIC_X86_XSAVE_ID(xsaves);
7737 INTRINSIC_X86_XSAVE_ID(xsaves64);
7738 }
7739#undef INTRINSIC_X86_XSAVE_ID
7740 Value *Mhi = Builder.CreateTrunc(
7741 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty);
7742 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty);
7743 Ops[1] = Mhi;
7744 Ops.push_back(Mlo);
7745 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
7746 }
Craig Topper6e891fb2016-05-31 01:50:10 +00007747 case X86::BI__builtin_ia32_storedqudi128_mask:
7748 case X86::BI__builtin_ia32_storedqusi128_mask:
7749 case X86::BI__builtin_ia32_storedquhi128_mask:
7750 case X86::BI__builtin_ia32_storedquqi128_mask:
7751 case X86::BI__builtin_ia32_storeupd128_mask:
7752 case X86::BI__builtin_ia32_storeups128_mask:
7753 case X86::BI__builtin_ia32_storedqudi256_mask:
7754 case X86::BI__builtin_ia32_storedqusi256_mask:
7755 case X86::BI__builtin_ia32_storedquhi256_mask:
7756 case X86::BI__builtin_ia32_storedquqi256_mask:
7757 case X86::BI__builtin_ia32_storeupd256_mask:
7758 case X86::BI__builtin_ia32_storeups256_mask:
7759 case X86::BI__builtin_ia32_storedqudi512_mask:
7760 case X86::BI__builtin_ia32_storedqusi512_mask:
7761 case X86::BI__builtin_ia32_storedquhi512_mask:
7762 case X86::BI__builtin_ia32_storedquqi512_mask:
7763 case X86::BI__builtin_ia32_storeupd512_mask:
7764 case X86::BI__builtin_ia32_storeups512_mask:
7765 return EmitX86MaskedStore(*this, Ops, 1);
7766
Ayman Musae60a41c2016-11-08 12:00:30 +00007767 case X86::BI__builtin_ia32_storess128_mask:
7768 case X86::BI__builtin_ia32_storesd128_mask: {
7769 return EmitX86MaskedStore(*this, Ops, 16);
7770 }
Oren Ben Simhon140c1fb2017-05-25 13:44:11 +00007771 case X86::BI__builtin_ia32_vpopcntd_512:
7772 case X86::BI__builtin_ia32_vpopcntq_512: {
7773 llvm::Type *ResultType = ConvertType(E->getType());
7774 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
7775 return Builder.CreateCall(F, Ops);
7776 }
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007777 case X86::BI__builtin_ia32_cvtmask2b128:
7778 case X86::BI__builtin_ia32_cvtmask2b256:
7779 case X86::BI__builtin_ia32_cvtmask2b512:
7780 case X86::BI__builtin_ia32_cvtmask2w128:
7781 case X86::BI__builtin_ia32_cvtmask2w256:
7782 case X86::BI__builtin_ia32_cvtmask2w512:
7783 case X86::BI__builtin_ia32_cvtmask2d128:
7784 case X86::BI__builtin_ia32_cvtmask2d256:
7785 case X86::BI__builtin_ia32_cvtmask2d512:
7786 case X86::BI__builtin_ia32_cvtmask2q128:
7787 case X86::BI__builtin_ia32_cvtmask2q256:
7788 case X86::BI__builtin_ia32_cvtmask2q512:
7789 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType()));
7790
Craig Topper6e891fb2016-05-31 01:50:10 +00007791 case X86::BI__builtin_ia32_movdqa32store128_mask:
7792 case X86::BI__builtin_ia32_movdqa64store128_mask:
7793 case X86::BI__builtin_ia32_storeaps128_mask:
7794 case X86::BI__builtin_ia32_storeapd128_mask:
7795 case X86::BI__builtin_ia32_movdqa32store256_mask:
7796 case X86::BI__builtin_ia32_movdqa64store256_mask:
7797 case X86::BI__builtin_ia32_storeaps256_mask:
7798 case X86::BI__builtin_ia32_storeapd256_mask:
7799 case X86::BI__builtin_ia32_movdqa32store512_mask:
7800 case X86::BI__builtin_ia32_movdqa64store512_mask:
7801 case X86::BI__builtin_ia32_storeaps512_mask:
7802 case X86::BI__builtin_ia32_storeapd512_mask: {
7803 unsigned Align =
7804 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7805 return EmitX86MaskedStore(*this, Ops, Align);
7806 }
Craig Topper4b060e32016-05-31 06:58:07 +00007807 case X86::BI__builtin_ia32_loadups128_mask:
7808 case X86::BI__builtin_ia32_loadups256_mask:
7809 case X86::BI__builtin_ia32_loadups512_mask:
7810 case X86::BI__builtin_ia32_loadupd128_mask:
7811 case X86::BI__builtin_ia32_loadupd256_mask:
7812 case X86::BI__builtin_ia32_loadupd512_mask:
7813 case X86::BI__builtin_ia32_loaddquqi128_mask:
7814 case X86::BI__builtin_ia32_loaddquqi256_mask:
7815 case X86::BI__builtin_ia32_loaddquqi512_mask:
7816 case X86::BI__builtin_ia32_loaddquhi128_mask:
7817 case X86::BI__builtin_ia32_loaddquhi256_mask:
7818 case X86::BI__builtin_ia32_loaddquhi512_mask:
7819 case X86::BI__builtin_ia32_loaddqusi128_mask:
7820 case X86::BI__builtin_ia32_loaddqusi256_mask:
7821 case X86::BI__builtin_ia32_loaddqusi512_mask:
7822 case X86::BI__builtin_ia32_loaddqudi128_mask:
7823 case X86::BI__builtin_ia32_loaddqudi256_mask:
7824 case X86::BI__builtin_ia32_loaddqudi512_mask:
7825 return EmitX86MaskedLoad(*this, Ops, 1);
7826
Ayman Musae60a41c2016-11-08 12:00:30 +00007827 case X86::BI__builtin_ia32_loadss128_mask:
7828 case X86::BI__builtin_ia32_loadsd128_mask:
7829 return EmitX86MaskedLoad(*this, Ops, 16);
7830
Craig Topper4b060e32016-05-31 06:58:07 +00007831 case X86::BI__builtin_ia32_loadaps128_mask:
7832 case X86::BI__builtin_ia32_loadaps256_mask:
7833 case X86::BI__builtin_ia32_loadaps512_mask:
7834 case X86::BI__builtin_ia32_loadapd128_mask:
7835 case X86::BI__builtin_ia32_loadapd256_mask:
7836 case X86::BI__builtin_ia32_loadapd512_mask:
7837 case X86::BI__builtin_ia32_movdqa32load128_mask:
7838 case X86::BI__builtin_ia32_movdqa32load256_mask:
7839 case X86::BI__builtin_ia32_movdqa32load512_mask:
7840 case X86::BI__builtin_ia32_movdqa64load128_mask:
7841 case X86::BI__builtin_ia32_movdqa64load256_mask:
7842 case X86::BI__builtin_ia32_movdqa64load512_mask: {
7843 unsigned Align =
7844 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7845 return EmitX86MaskedLoad(*this, Ops, Align);
7846 }
Simon Pilgrim2d851732016-07-22 13:58:56 +00007847
7848 case X86::BI__builtin_ia32_vbroadcastf128_pd256:
7849 case X86::BI__builtin_ia32_vbroadcastf128_ps256: {
7850 llvm::Type *DstTy = ConvertType(E->getType());
Chandler Carruth4c5e8cc2016-08-10 07:32:47 +00007851 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1);
Simon Pilgrim2d851732016-07-22 13:58:56 +00007852 }
7853
Nate Begeman91f40e32008-04-14 04:49:57 +00007854 case X86::BI__builtin_ia32_storehps:
7855 case X86::BI__builtin_ia32_storelps: {
Chris Lattner5e016ae2010-06-27 07:15:29 +00007856 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty);
7857 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2);
Mike Stump11289f42009-09-09 15:08:12 +00007858
Nate Begeman91f40e32008-04-14 04:49:57 +00007859 // cast val v2i64
7860 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
Mike Stump11289f42009-09-09 15:08:12 +00007861
Nate Begeman91f40e32008-04-14 04:49:57 +00007862 // extract (0, 1)
7863 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
Michael J. Spencerdd597752014-05-31 00:22:12 +00007864 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index);
Nate Begeman91f40e32008-04-14 04:49:57 +00007865 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
7866
7867 // cast pointer to i64 & store
7868 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00007869 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begeman91f40e32008-04-14 04:49:57 +00007870 }
Craig Topper480e2b62015-02-17 06:37:58 +00007871 case X86::BI__builtin_ia32_palignr128:
Craig Topperf51cc072016-06-06 06:13:01 +00007872 case X86::BI__builtin_ia32_palignr256:
Craig Topperf51cc072016-06-06 06:13:01 +00007873 case X86::BI__builtin_ia32_palignr512_mask: {
Craig Topper480e2b62015-02-17 06:37:58 +00007874 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
Craig Topper94aba2c2011-12-19 07:03:25 +00007875
Craig Topperf2f1a092016-07-08 02:17:35 +00007876 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topper480e2b62015-02-17 06:37:58 +00007877 assert(NumElts % 16 == 0);
Craig Topper480e2b62015-02-17 06:37:58 +00007878
Craig Topper480e2b62015-02-17 06:37:58 +00007879 // If palignr is shifting the pair of vectors more than the size of two
7880 // lanes, emit zero.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007881 if (ShiftVal >= 32)
Craig Topper480e2b62015-02-17 06:37:58 +00007882 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Craig Topper94aba2c2011-12-19 07:03:25 +00007883
Craig Topper480e2b62015-02-17 06:37:58 +00007884 // If palignr is shifting the pair of input vectors more than one lane,
Craig Topper96f9a572015-02-17 07:18:01 +00007885 // but less than two lanes, convert to shifting in zeroes.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007886 if (ShiftVal > 16) {
7887 ShiftVal -= 16;
Benjamin Kramerb5960562015-07-20 15:31:17 +00007888 Ops[1] = Ops[0];
Craig Topper96f9a572015-02-17 07:18:01 +00007889 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType());
Craig Topper94aba2c2011-12-19 07:03:25 +00007890 }
7891
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007892 uint32_t Indices[64];
Craig Topper96f9a572015-02-17 07:18:01 +00007893 // 256-bit palignr operates on 128-bit lanes so we need to handle that
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007894 for (unsigned l = 0; l != NumElts; l += 16) {
7895 for (unsigned i = 0; i != 16; ++i) {
Craig Topper96f9a572015-02-17 07:18:01 +00007896 unsigned Idx = ShiftVal + i;
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007897 if (Idx >= 16)
7898 Idx += NumElts - 16; // End of lane, switch operand.
Benjamin Kramerc385a802015-07-28 15:40:11 +00007899 Indices[l + i] = Idx + l;
Craig Topper96f9a572015-02-17 07:18:01 +00007900 }
7901 }
7902
Craig Topperf51cc072016-06-06 06:13:01 +00007903 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0],
7904 makeArrayRef(Indices, NumElts),
7905 "palignr");
7906
7907 // If this isn't a masked builtin, just return the align operation.
7908 if (Ops.size() == 3)
7909 return Align;
7910
Simon Pilgrim532de1c2016-06-13 10:05:19 +00007911 return EmitX86Select(*this, Ops[4], Align, Ops[3]);
7912 }
7913
7914 case X86::BI__builtin_ia32_movnti:
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007915 case X86::BI__builtin_ia32_movnti64:
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007916 case X86::BI__builtin_ia32_movntsd:
7917 case X86::BI__builtin_ia32_movntss: {
7918 llvm::MDNode *Node = llvm::MDNode::get(
7919 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
7920
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007921 Value *Ptr = Ops[0];
7922 Value *Src = Ops[1];
7923
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007924 // Extract the 0'th element of the source vector.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007925 if (BuiltinID == X86::BI__builtin_ia32_movntsd ||
7926 BuiltinID == X86::BI__builtin_ia32_movntss)
7927 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007928
7929 // Convert the type of the pointer to a pointer to the stored type.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007930 Value *BC = Builder.CreateBitCast(
7931 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007932
7933 // Unaligned nontemporal store of the scalar value.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007934 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC);
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007935 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
7936 SI->setAlignment(1);
7937 return SI;
7938 }
7939
Simon Pilgrim532de1c2016-06-13 10:05:19 +00007940 case X86::BI__builtin_ia32_selectb_128:
Igor Bregeraadb8762016-06-08 13:59:20 +00007941 case X86::BI__builtin_ia32_selectb_256:
7942 case X86::BI__builtin_ia32_selectb_512:
7943 case X86::BI__builtin_ia32_selectw_128:
7944 case X86::BI__builtin_ia32_selectw_256:
7945 case X86::BI__builtin_ia32_selectw_512:
7946 case X86::BI__builtin_ia32_selectd_128:
7947 case X86::BI__builtin_ia32_selectd_256:
7948 case X86::BI__builtin_ia32_selectd_512:
7949 case X86::BI__builtin_ia32_selectq_128:
7950 case X86::BI__builtin_ia32_selectq_256:
7951 case X86::BI__builtin_ia32_selectq_512:
7952 case X86::BI__builtin_ia32_selectps_128:
7953 case X86::BI__builtin_ia32_selectps_256:
7954 case X86::BI__builtin_ia32_selectps_512:
7955 case X86::BI__builtin_ia32_selectpd_128:
7956 case X86::BI__builtin_ia32_selectpd_256:
7957 case X86::BI__builtin_ia32_selectpd_512:
Craig Topperc1442972016-06-09 05:15:00 +00007958 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]);
Craig Toppera54c21e2016-06-15 14:06:34 +00007959 case X86::BI__builtin_ia32_pcmpeqb128_mask:
7960 case X86::BI__builtin_ia32_pcmpeqb256_mask:
7961 case X86::BI__builtin_ia32_pcmpeqb512_mask:
7962 case X86::BI__builtin_ia32_pcmpeqw128_mask:
7963 case X86::BI__builtin_ia32_pcmpeqw256_mask:
7964 case X86::BI__builtin_ia32_pcmpeqw512_mask:
7965 case X86::BI__builtin_ia32_pcmpeqd128_mask:
7966 case X86::BI__builtin_ia32_pcmpeqd256_mask:
7967 case X86::BI__builtin_ia32_pcmpeqd512_mask:
7968 case X86::BI__builtin_ia32_pcmpeqq128_mask:
7969 case X86::BI__builtin_ia32_pcmpeqq256_mask:
7970 case X86::BI__builtin_ia32_pcmpeqq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00007971 return EmitX86MaskedCompare(*this, 0, false, Ops);
Craig Toppera54c21e2016-06-15 14:06:34 +00007972 case X86::BI__builtin_ia32_pcmpgtb128_mask:
7973 case X86::BI__builtin_ia32_pcmpgtb256_mask:
7974 case X86::BI__builtin_ia32_pcmpgtb512_mask:
7975 case X86::BI__builtin_ia32_pcmpgtw128_mask:
7976 case X86::BI__builtin_ia32_pcmpgtw256_mask:
7977 case X86::BI__builtin_ia32_pcmpgtw512_mask:
7978 case X86::BI__builtin_ia32_pcmpgtd128_mask:
7979 case X86::BI__builtin_ia32_pcmpgtd256_mask:
7980 case X86::BI__builtin_ia32_pcmpgtd512_mask:
7981 case X86::BI__builtin_ia32_pcmpgtq128_mask:
7982 case X86::BI__builtin_ia32_pcmpgtq256_mask:
7983 case X86::BI__builtin_ia32_pcmpgtq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00007984 return EmitX86MaskedCompare(*this, 6, true, Ops);
7985 case X86::BI__builtin_ia32_cmpb128_mask:
7986 case X86::BI__builtin_ia32_cmpb256_mask:
7987 case X86::BI__builtin_ia32_cmpb512_mask:
7988 case X86::BI__builtin_ia32_cmpw128_mask:
7989 case X86::BI__builtin_ia32_cmpw256_mask:
7990 case X86::BI__builtin_ia32_cmpw512_mask:
7991 case X86::BI__builtin_ia32_cmpd128_mask:
7992 case X86::BI__builtin_ia32_cmpd256_mask:
7993 case X86::BI__builtin_ia32_cmpd512_mask:
7994 case X86::BI__builtin_ia32_cmpq128_mask:
7995 case X86::BI__builtin_ia32_cmpq256_mask:
7996 case X86::BI__builtin_ia32_cmpq512_mask: {
7997 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
7998 return EmitX86MaskedCompare(*this, CC, true, Ops);
7999 }
8000 case X86::BI__builtin_ia32_ucmpb128_mask:
8001 case X86::BI__builtin_ia32_ucmpb256_mask:
8002 case X86::BI__builtin_ia32_ucmpb512_mask:
8003 case X86::BI__builtin_ia32_ucmpw128_mask:
8004 case X86::BI__builtin_ia32_ucmpw256_mask:
8005 case X86::BI__builtin_ia32_ucmpw512_mask:
8006 case X86::BI__builtin_ia32_ucmpd128_mask:
8007 case X86::BI__builtin_ia32_ucmpd256_mask:
8008 case X86::BI__builtin_ia32_ucmpd512_mask:
8009 case X86::BI__builtin_ia32_ucmpq128_mask:
8010 case X86::BI__builtin_ia32_ucmpq256_mask:
8011 case X86::BI__builtin_ia32_ucmpq512_mask: {
8012 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
8013 return EmitX86MaskedCompare(*this, CC, false, Ops);
8014 }
Sanjay Patel7495ec02016-06-15 17:18:50 +00008015
Craig Topper46e75552016-07-06 04:24:29 +00008016 case X86::BI__builtin_ia32_vplzcntd_128_mask:
8017 case X86::BI__builtin_ia32_vplzcntd_256_mask:
8018 case X86::BI__builtin_ia32_vplzcntd_512_mask:
8019 case X86::BI__builtin_ia32_vplzcntq_128_mask:
8020 case X86::BI__builtin_ia32_vplzcntq_256_mask:
8021 case X86::BI__builtin_ia32_vplzcntq_512_mask: {
8022 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType());
8023 return EmitX86Select(*this, Ops[2],
8024 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}),
8025 Ops[1]);
8026 }
8027
Sanjay Patel7495ec02016-06-15 17:18:50 +00008028 case X86::BI__builtin_ia32_pmaxsb128:
8029 case X86::BI__builtin_ia32_pmaxsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008030 case X86::BI__builtin_ia32_pmaxsd128:
Craig Topper531ce282016-10-24 04:04:24 +00008031 case X86::BI__builtin_ia32_pmaxsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008032 case X86::BI__builtin_ia32_pmaxsb256:
8033 case X86::BI__builtin_ia32_pmaxsw256:
Craig Topper531ce282016-10-24 04:04:24 +00008034 case X86::BI__builtin_ia32_pmaxsd256:
8035 case X86::BI__builtin_ia32_pmaxsq256_mask:
8036 case X86::BI__builtin_ia32_pmaxsb512_mask:
8037 case X86::BI__builtin_ia32_pmaxsw512_mask:
8038 case X86::BI__builtin_ia32_pmaxsd512_mask:
8039 case X86::BI__builtin_ia32_pmaxsq512_mask:
8040 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008041 case X86::BI__builtin_ia32_pmaxub128:
8042 case X86::BI__builtin_ia32_pmaxuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008043 case X86::BI__builtin_ia32_pmaxud128:
Craig Topper531ce282016-10-24 04:04:24 +00008044 case X86::BI__builtin_ia32_pmaxuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008045 case X86::BI__builtin_ia32_pmaxub256:
8046 case X86::BI__builtin_ia32_pmaxuw256:
Craig Topper531ce282016-10-24 04:04:24 +00008047 case X86::BI__builtin_ia32_pmaxud256:
8048 case X86::BI__builtin_ia32_pmaxuq256_mask:
8049 case X86::BI__builtin_ia32_pmaxub512_mask:
8050 case X86::BI__builtin_ia32_pmaxuw512_mask:
8051 case X86::BI__builtin_ia32_pmaxud512_mask:
8052 case X86::BI__builtin_ia32_pmaxuq512_mask:
8053 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008054 case X86::BI__builtin_ia32_pminsb128:
8055 case X86::BI__builtin_ia32_pminsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008056 case X86::BI__builtin_ia32_pminsd128:
Craig Topper531ce282016-10-24 04:04:24 +00008057 case X86::BI__builtin_ia32_pminsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008058 case X86::BI__builtin_ia32_pminsb256:
8059 case X86::BI__builtin_ia32_pminsw256:
Craig Topper531ce282016-10-24 04:04:24 +00008060 case X86::BI__builtin_ia32_pminsd256:
8061 case X86::BI__builtin_ia32_pminsq256_mask:
8062 case X86::BI__builtin_ia32_pminsb512_mask:
8063 case X86::BI__builtin_ia32_pminsw512_mask:
8064 case X86::BI__builtin_ia32_pminsd512_mask:
8065 case X86::BI__builtin_ia32_pminsq512_mask:
8066 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008067 case X86::BI__builtin_ia32_pminub128:
8068 case X86::BI__builtin_ia32_pminuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008069 case X86::BI__builtin_ia32_pminud128:
Craig Topper531ce282016-10-24 04:04:24 +00008070 case X86::BI__builtin_ia32_pminuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008071 case X86::BI__builtin_ia32_pminub256:
8072 case X86::BI__builtin_ia32_pminuw256:
Craig Topper531ce282016-10-24 04:04:24 +00008073 case X86::BI__builtin_ia32_pminud256:
8074 case X86::BI__builtin_ia32_pminuq256_mask:
8075 case X86::BI__builtin_ia32_pminub512_mask:
8076 case X86::BI__builtin_ia32_pminuw512_mask:
8077 case X86::BI__builtin_ia32_pminud512_mask:
8078 case X86::BI__builtin_ia32_pminuq512_mask:
8079 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008080
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008081 // 3DNow!
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008082 case X86::BI__builtin_ia32_pswapdsf:
8083 case X86::BI__builtin_ia32_pswapdsi: {
Chandler Carrutha2a54102012-02-20 07:35:45 +00008084 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext());
8085 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast");
Craig Topperd2f814d2015-02-16 21:30:08 +00008086 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd);
8087 return Builder.CreateCall(F, Ops, "pswapd");
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008088 }
Benjamin Kramera43b6992012-07-12 09:33:03 +00008089 case X86::BI__builtin_ia32_rdrand16_step:
8090 case X86::BI__builtin_ia32_rdrand32_step:
Michael Liaoffaae352013-03-29 05:17:55 +00008091 case X86::BI__builtin_ia32_rdrand64_step:
8092 case X86::BI__builtin_ia32_rdseed16_step:
8093 case X86::BI__builtin_ia32_rdseed32_step:
8094 case X86::BI__builtin_ia32_rdseed64_step: {
Benjamin Kramera43b6992012-07-12 09:33:03 +00008095 Intrinsic::ID ID;
8096 switch (BuiltinID) {
8097 default: llvm_unreachable("Unsupported intrinsic!");
8098 case X86::BI__builtin_ia32_rdrand16_step:
8099 ID = Intrinsic::x86_rdrand_16;
8100 break;
8101 case X86::BI__builtin_ia32_rdrand32_step:
8102 ID = Intrinsic::x86_rdrand_32;
8103 break;
8104 case X86::BI__builtin_ia32_rdrand64_step:
8105 ID = Intrinsic::x86_rdrand_64;
8106 break;
Michael Liaoffaae352013-03-29 05:17:55 +00008107 case X86::BI__builtin_ia32_rdseed16_step:
8108 ID = Intrinsic::x86_rdseed_16;
8109 break;
8110 case X86::BI__builtin_ia32_rdseed32_step:
8111 ID = Intrinsic::x86_rdseed_32;
8112 break;
8113 case X86::BI__builtin_ia32_rdseed64_step:
8114 ID = Intrinsic::x86_rdseed_64;
8115 break;
Benjamin Kramera43b6992012-07-12 09:33:03 +00008116 }
8117
David Blaikie4ba525b2015-07-14 17:27:39 +00008118 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID));
John McCall7f416cc2015-09-08 08:05:57 +00008119 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0),
8120 Ops[0]);
Benjamin Kramera43b6992012-07-12 09:33:03 +00008121 return Builder.CreateExtractValue(Call, 1);
8122 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008123
8124 // SSE packed comparison intrinsics
Craig Topper2094d8f2014-12-27 06:59:57 +00008125 case X86::BI__builtin_ia32_cmpeqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008126 case X86::BI__builtin_ia32_cmpeqpd:
Craig Topper01600632016-07-08 01:57:24 +00008127 return getVectorFCmpIR(CmpInst::FCMP_OEQ);
Craig Topper925ef0a2016-07-08 01:48:44 +00008128 case X86::BI__builtin_ia32_cmpltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008129 case X86::BI__builtin_ia32_cmpltpd:
Craig Topper01600632016-07-08 01:57:24 +00008130 return getVectorFCmpIR(CmpInst::FCMP_OLT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008131 case X86::BI__builtin_ia32_cmpleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008132 case X86::BI__builtin_ia32_cmplepd:
Craig Topper01600632016-07-08 01:57:24 +00008133 return getVectorFCmpIR(CmpInst::FCMP_OLE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008134 case X86::BI__builtin_ia32_cmpunordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008135 case X86::BI__builtin_ia32_cmpunordpd:
Craig Topper01600632016-07-08 01:57:24 +00008136 return getVectorFCmpIR(CmpInst::FCMP_UNO);
Craig Topper925ef0a2016-07-08 01:48:44 +00008137 case X86::BI__builtin_ia32_cmpneqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008138 case X86::BI__builtin_ia32_cmpneqpd:
Craig Topper01600632016-07-08 01:57:24 +00008139 return getVectorFCmpIR(CmpInst::FCMP_UNE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008140 case X86::BI__builtin_ia32_cmpnltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008141 case X86::BI__builtin_ia32_cmpnltpd:
Craig Topper01600632016-07-08 01:57:24 +00008142 return getVectorFCmpIR(CmpInst::FCMP_UGE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008143 case X86::BI__builtin_ia32_cmpnleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008144 case X86::BI__builtin_ia32_cmpnlepd:
Craig Topper01600632016-07-08 01:57:24 +00008145 return getVectorFCmpIR(CmpInst::FCMP_UGT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008146 case X86::BI__builtin_ia32_cmpordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008147 case X86::BI__builtin_ia32_cmpordpd:
Craig Topper01600632016-07-08 01:57:24 +00008148 return getVectorFCmpIR(CmpInst::FCMP_ORD);
Craig Topper425d02d2016-07-06 06:27:31 +00008149 case X86::BI__builtin_ia32_cmpps:
8150 case X86::BI__builtin_ia32_cmpps256:
8151 case X86::BI__builtin_ia32_cmppd:
8152 case X86::BI__builtin_ia32_cmppd256: {
8153 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
8154 // If this one of the SSE immediates, we can use native IR.
8155 if (CC < 8) {
8156 FCmpInst::Predicate Pred;
8157 switch (CC) {
8158 case 0: Pred = FCmpInst::FCMP_OEQ; break;
8159 case 1: Pred = FCmpInst::FCMP_OLT; break;
8160 case 2: Pred = FCmpInst::FCMP_OLE; break;
8161 case 3: Pred = FCmpInst::FCMP_UNO; break;
8162 case 4: Pred = FCmpInst::FCMP_UNE; break;
8163 case 5: Pred = FCmpInst::FCMP_UGE; break;
8164 case 6: Pred = FCmpInst::FCMP_UGT; break;
8165 case 7: Pred = FCmpInst::FCMP_ORD; break;
8166 }
Craig Topper01600632016-07-08 01:57:24 +00008167 return getVectorFCmpIR(Pred);
Craig Topper425d02d2016-07-06 06:27:31 +00008168 }
8169
8170 // We can't handle 8-31 immediates with native IR, use the intrinsic.
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008171 // Except for predicates that create constants.
Craig Topper425d02d2016-07-06 06:27:31 +00008172 Intrinsic::ID ID;
8173 switch (BuiltinID) {
8174 default: llvm_unreachable("Unsupported intrinsic!");
8175 case X86::BI__builtin_ia32_cmpps:
8176 ID = Intrinsic::x86_sse_cmp_ps;
8177 break;
8178 case X86::BI__builtin_ia32_cmpps256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008179 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8180 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8181 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8182 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8183 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) :
8184 llvm::Constant::getNullValue(Builder.getInt32Ty());
8185 Value *Vec = Builder.CreateVectorSplat(
8186 Ops[0]->getType()->getVectorNumElements(), Constant);
8187 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8188 }
Craig Topper425d02d2016-07-06 06:27:31 +00008189 ID = Intrinsic::x86_avx_cmp_ps_256;
8190 break;
8191 case X86::BI__builtin_ia32_cmppd:
8192 ID = Intrinsic::x86_sse2_cmp_pd;
8193 break;
8194 case X86::BI__builtin_ia32_cmppd256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008195 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8196 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8197 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8198 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8199 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) :
8200 llvm::Constant::getNullValue(Builder.getInt64Ty());
8201 Value *Vec = Builder.CreateVectorSplat(
8202 Ops[0]->getType()->getVectorNumElements(), Constant);
8203 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8204 }
Craig Topper425d02d2016-07-06 06:27:31 +00008205 ID = Intrinsic::x86_avx_cmp_pd_256;
8206 break;
8207 }
8208
8209 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
8210 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008211
8212 // SSE scalar comparison intrinsics
8213 case X86::BI__builtin_ia32_cmpeqss:
8214 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0);
8215 case X86::BI__builtin_ia32_cmpltss:
8216 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1);
8217 case X86::BI__builtin_ia32_cmpless:
8218 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2);
8219 case X86::BI__builtin_ia32_cmpunordss:
8220 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3);
8221 case X86::BI__builtin_ia32_cmpneqss:
8222 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4);
8223 case X86::BI__builtin_ia32_cmpnltss:
8224 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5);
8225 case X86::BI__builtin_ia32_cmpnless:
8226 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6);
8227 case X86::BI__builtin_ia32_cmpordss:
8228 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7);
Craig Topper2094d8f2014-12-27 06:59:57 +00008229 case X86::BI__builtin_ia32_cmpeqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008230 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0);
Craig Topper2094d8f2014-12-27 06:59:57 +00008231 case X86::BI__builtin_ia32_cmpltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008232 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1);
Craig Topper2094d8f2014-12-27 06:59:57 +00008233 case X86::BI__builtin_ia32_cmplesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008234 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2);
Craig Topper2094d8f2014-12-27 06:59:57 +00008235 case X86::BI__builtin_ia32_cmpunordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008236 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3);
Craig Topper2094d8f2014-12-27 06:59:57 +00008237 case X86::BI__builtin_ia32_cmpneqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008238 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4);
Craig Topper2094d8f2014-12-27 06:59:57 +00008239 case X86::BI__builtin_ia32_cmpnltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008240 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5);
Craig Topper2094d8f2014-12-27 06:59:57 +00008241 case X86::BI__builtin_ia32_cmpnlesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008242 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6);
Craig Topper2094d8f2014-12-27 06:59:57 +00008243 case X86::BI__builtin_ia32_cmpordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008244 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008245
Albert Gutowski7216f172016-10-10 18:09:27 +00008246 case X86::BI__emul:
8247 case X86::BI__emulu: {
8248 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64);
8249 bool isSigned = (BuiltinID == X86::BI__emul);
8250 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned);
8251 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned);
8252 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned);
8253 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008254 case X86::BI__mulh:
Albert Gutowski7216f172016-10-10 18:09:27 +00008255 case X86::BI__umulh:
8256 case X86::BI_mul128:
8257 case X86::BI_umul128: {
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008258 llvm::Type *ResType = ConvertType(E->getType());
8259 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
8260
Albert Gutowski7216f172016-10-10 18:09:27 +00008261 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128);
8262 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned);
8263 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008264
8265 Value *MulResult, *HigherBits;
8266 if (IsSigned) {
8267 MulResult = Builder.CreateNSWMul(LHS, RHS);
8268 HigherBits = Builder.CreateAShr(MulResult, 64);
8269 } else {
8270 MulResult = Builder.CreateNUWMul(LHS, RHS);
8271 HigherBits = Builder.CreateLShr(MulResult, 64);
8272 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008273 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned);
Albert Gutowski7216f172016-10-10 18:09:27 +00008274
8275 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh)
8276 return HigherBits;
8277
8278 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2));
8279 Builder.CreateStore(HigherBits, HighBitsAddress);
8280 return Builder.CreateIntCast(MulResult, ResType, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008281 }
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008282
8283 case X86::BI__faststorefence: {
8284 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008285 llvm::SyncScope::System);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008286 }
8287 case X86::BI_ReadWriteBarrier:
8288 case X86::BI_ReadBarrier:
8289 case X86::BI_WriteBarrier: {
8290 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008291 llvm::SyncScope::SingleThread);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008292 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00008293 case X86::BI_BitScanForward:
8294 case X86::BI_BitScanForward64:
8295 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
8296 case X86::BI_BitScanReverse:
8297 case X86::BI_BitScanReverse64:
8298 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00008299
8300 case X86::BI_InterlockedAnd64:
8301 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
8302 case X86::BI_InterlockedExchange64:
8303 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
8304 case X86::BI_InterlockedExchangeAdd64:
8305 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
8306 case X86::BI_InterlockedExchangeSub64:
8307 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
8308 case X86::BI_InterlockedOr64:
8309 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
8310 case X86::BI_InterlockedXor64:
8311 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
8312 case X86::BI_InterlockedDecrement64:
8313 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
8314 case X86::BI_InterlockedIncrement64:
8315 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
8316
Albert Gutowski397d81b2016-10-13 16:03:42 +00008317 case X86::BI_AddressOfReturnAddress: {
8318 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
8319 return Builder.CreateCall(F);
8320 }
Albert Gutowski1deab382016-10-14 17:33:05 +00008321 case X86::BI__stosb: {
8322 // We treat __stosb as a volatile memset - it may not generate "rep stosb"
8323 // instruction, but it will create a memset that won't be optimized away.
8324 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true);
8325 }
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008326 case X86::BI__ud2:
8327 // llvm.trap makes a ud2a instruction on x86.
8328 return EmitTrapCall(Intrinsic::trap);
8329 case X86::BI__int2c: {
8330 // This syscall signals a driver assertion failure in x86 NT kernels.
8331 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
8332 llvm::InlineAsm *IA =
8333 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true);
Reid Klecknerde864822017-03-21 16:57:30 +00008334 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
8335 getLLVMContext(), llvm::AttributeList::FunctionIndex,
8336 llvm::Attribute::NoReturn);
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008337 CallSite CS = Builder.CreateCall(IA);
8338 CS.setAttributes(NoReturnAttr);
8339 return CS.getInstruction();
8340 }
Hans Wennborg043f4022017-03-22 19:13:13 +00008341 case X86::BI__readfsbyte:
8342 case X86::BI__readfsword:
8343 case X86::BI__readfsdword:
8344 case X86::BI__readfsqword: {
8345 llvm::Type *IntTy = ConvertType(E->getType());
8346 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8347 llvm::PointerType::get(IntTy, 257));
8348 LoadInst *Load = Builder.CreateAlignedLoad(
8349 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8350 Load->setVolatile(true);
8351 return Load;
8352 }
8353 case X86::BI__readgsbyte:
8354 case X86::BI__readgsword:
8355 case X86::BI__readgsdword:
8356 case X86::BI__readgsqword: {
8357 llvm::Type *IntTy = ConvertType(E->getType());
8358 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8359 llvm::PointerType::get(IntTy, 256));
8360 LoadInst *Load = Builder.CreateAlignedLoad(
8361 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8362 Load->setVolatile(true);
8363 return Load;
8364 }
Anders Carlsson895af082007-12-09 23:17:02 +00008365 }
8366}
8367
Tony Linthicum76329bf2011-12-12 21:14:55 +00008368
Mike Stump11289f42009-09-09 15:08:12 +00008369Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00008370 const CallExpr *E) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00008371 SmallVector<Value*, 4> Ops;
Chris Lattnerdad40622010-04-14 03:54:58 +00008372
8373 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
8374 Ops.push_back(EmitScalarExpr(E->getArg(i)));
8375
8376 Intrinsic::ID ID = Intrinsic::not_intrinsic;
8377
8378 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00008379 default: return nullptr;
Chris Lattnerdad40622010-04-14 03:54:58 +00008380
Hal Finkel65e1e4d2015-08-31 23:55:19 +00008381 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we
8382 // call __builtin_readcyclecounter.
8383 case PPC::BI__builtin_ppc_get_timebase:
8384 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter));
8385
Tony Jiang6a49aad2016-11-15 14:30:56 +00008386 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008387 case PPC::BI__builtin_altivec_lvx:
8388 case PPC::BI__builtin_altivec_lvxl:
8389 case PPC::BI__builtin_altivec_lvebx:
8390 case PPC::BI__builtin_altivec_lvehx:
8391 case PPC::BI__builtin_altivec_lvewx:
8392 case PPC::BI__builtin_altivec_lvsl:
8393 case PPC::BI__builtin_altivec_lvsr:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008394 case PPC::BI__builtin_vsx_lxvd2x:
8395 case PPC::BI__builtin_vsx_lxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008396 case PPC::BI__builtin_vsx_lxvd2x_be:
8397 case PPC::BI__builtin_vsx_lxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008398 case PPC::BI__builtin_vsx_lxvl:
8399 case PPC::BI__builtin_vsx_lxvll:
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008400 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008401 if(BuiltinID == PPC::BI__builtin_vsx_lxvl ||
8402 BuiltinID == PPC::BI__builtin_vsx_lxvll){
8403 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
8404 }else {
8405 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8406 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]);
8407 Ops.pop_back();
8408 }
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008409
8410 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008411 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008412 case PPC::BI__builtin_altivec_lvx:
8413 ID = Intrinsic::ppc_altivec_lvx;
8414 break;
8415 case PPC::BI__builtin_altivec_lvxl:
8416 ID = Intrinsic::ppc_altivec_lvxl;
8417 break;
8418 case PPC::BI__builtin_altivec_lvebx:
8419 ID = Intrinsic::ppc_altivec_lvebx;
8420 break;
8421 case PPC::BI__builtin_altivec_lvehx:
8422 ID = Intrinsic::ppc_altivec_lvehx;
8423 break;
8424 case PPC::BI__builtin_altivec_lvewx:
8425 ID = Intrinsic::ppc_altivec_lvewx;
8426 break;
8427 case PPC::BI__builtin_altivec_lvsl:
8428 ID = Intrinsic::ppc_altivec_lvsl;
8429 break;
8430 case PPC::BI__builtin_altivec_lvsr:
8431 ID = Intrinsic::ppc_altivec_lvsr;
8432 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008433 case PPC::BI__builtin_vsx_lxvd2x:
8434 ID = Intrinsic::ppc_vsx_lxvd2x;
8435 break;
8436 case PPC::BI__builtin_vsx_lxvw4x:
8437 ID = Intrinsic::ppc_vsx_lxvw4x;
8438 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008439 case PPC::BI__builtin_vsx_lxvd2x_be:
8440 ID = Intrinsic::ppc_vsx_lxvd2x_be;
8441 break;
8442 case PPC::BI__builtin_vsx_lxvw4x_be:
8443 ID = Intrinsic::ppc_vsx_lxvw4x_be;
8444 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008445 case PPC::BI__builtin_vsx_lxvl:
8446 ID = Intrinsic::ppc_vsx_lxvl;
8447 break;
8448 case PPC::BI__builtin_vsx_lxvll:
8449 ID = Intrinsic::ppc_vsx_lxvll;
8450 break;
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008451 }
8452 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008453 return Builder.CreateCall(F, Ops, "");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008454 }
8455
Tony Jiang6a49aad2016-11-15 14:30:56 +00008456 // vec_st, vec_xst_be
Chris Lattnerdad40622010-04-14 03:54:58 +00008457 case PPC::BI__builtin_altivec_stvx:
8458 case PPC::BI__builtin_altivec_stvxl:
8459 case PPC::BI__builtin_altivec_stvebx:
8460 case PPC::BI__builtin_altivec_stvehx:
8461 case PPC::BI__builtin_altivec_stvewx:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008462 case PPC::BI__builtin_vsx_stxvd2x:
8463 case PPC::BI__builtin_vsx_stxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008464 case PPC::BI__builtin_vsx_stxvd2x_be:
8465 case PPC::BI__builtin_vsx_stxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008466 case PPC::BI__builtin_vsx_stxvl:
8467 case PPC::BI__builtin_vsx_stxvll:
Chris Lattnerdad40622010-04-14 03:54:58 +00008468 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008469 if(BuiltinID == PPC::BI__builtin_vsx_stxvl ||
8470 BuiltinID == PPC::BI__builtin_vsx_stxvll ){
8471 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8472 }else {
8473 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy);
8474 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]);
8475 Ops.pop_back();
8476 }
Chris Lattnerdad40622010-04-14 03:54:58 +00008477
8478 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008479 default: llvm_unreachable("Unsupported st intrinsic!");
Chris Lattnerdad40622010-04-14 03:54:58 +00008480 case PPC::BI__builtin_altivec_stvx:
8481 ID = Intrinsic::ppc_altivec_stvx;
8482 break;
8483 case PPC::BI__builtin_altivec_stvxl:
8484 ID = Intrinsic::ppc_altivec_stvxl;
8485 break;
8486 case PPC::BI__builtin_altivec_stvebx:
8487 ID = Intrinsic::ppc_altivec_stvebx;
8488 break;
8489 case PPC::BI__builtin_altivec_stvehx:
8490 ID = Intrinsic::ppc_altivec_stvehx;
8491 break;
8492 case PPC::BI__builtin_altivec_stvewx:
8493 ID = Intrinsic::ppc_altivec_stvewx;
8494 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008495 case PPC::BI__builtin_vsx_stxvd2x:
8496 ID = Intrinsic::ppc_vsx_stxvd2x;
8497 break;
8498 case PPC::BI__builtin_vsx_stxvw4x:
8499 ID = Intrinsic::ppc_vsx_stxvw4x;
8500 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008501 case PPC::BI__builtin_vsx_stxvd2x_be:
8502 ID = Intrinsic::ppc_vsx_stxvd2x_be;
8503 break;
8504 case PPC::BI__builtin_vsx_stxvw4x_be:
8505 ID = Intrinsic::ppc_vsx_stxvw4x_be;
8506 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008507 case PPC::BI__builtin_vsx_stxvl:
8508 ID = Intrinsic::ppc_vsx_stxvl;
8509 break;
8510 case PPC::BI__builtin_vsx_stxvll:
8511 ID = Intrinsic::ppc_vsx_stxvll;
8512 break;
Chris Lattnerdad40622010-04-14 03:54:58 +00008513 }
8514 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008515 return Builder.CreateCall(F, Ops, "");
Chris Lattnerdad40622010-04-14 03:54:58 +00008516 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008517 // Square root
8518 case PPC::BI__builtin_vsx_xvsqrtsp:
8519 case PPC::BI__builtin_vsx_xvsqrtdp: {
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008520 llvm::Type *ResultType = ConvertType(E->getType());
8521 Value *X = EmitScalarExpr(E->getArg(0));
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008522 ID = Intrinsic::sqrt;
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008523 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8524 return Builder.CreateCall(F, X);
Chris Lattnerdad40622010-04-14 03:54:58 +00008525 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008526 // Count leading zeros
8527 case PPC::BI__builtin_altivec_vclzb:
8528 case PPC::BI__builtin_altivec_vclzh:
8529 case PPC::BI__builtin_altivec_vclzw:
8530 case PPC::BI__builtin_altivec_vclzd: {
8531 llvm::Type *ResultType = ConvertType(E->getType());
8532 Value *X = EmitScalarExpr(E->getArg(0));
8533 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8534 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
8535 return Builder.CreateCall(F, {X, Undef});
8536 }
Nemanja Ivanovic10e2b5d2016-09-27 10:45:22 +00008537 case PPC::BI__builtin_altivec_vctzb:
8538 case PPC::BI__builtin_altivec_vctzh:
8539 case PPC::BI__builtin_altivec_vctzw:
8540 case PPC::BI__builtin_altivec_vctzd: {
8541 llvm::Type *ResultType = ConvertType(E->getType());
8542 Value *X = EmitScalarExpr(E->getArg(0));
8543 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8544 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
8545 return Builder.CreateCall(F, {X, Undef});
8546 }
8547 case PPC::BI__builtin_altivec_vpopcntb:
8548 case PPC::BI__builtin_altivec_vpopcnth:
8549 case PPC::BI__builtin_altivec_vpopcntw:
8550 case PPC::BI__builtin_altivec_vpopcntd: {
8551 llvm::Type *ResultType = ConvertType(E->getType());
8552 Value *X = EmitScalarExpr(E->getArg(0));
8553 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
8554 return Builder.CreateCall(F, X);
8555 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008556 // Copy sign
8557 case PPC::BI__builtin_vsx_xvcpsgnsp:
8558 case PPC::BI__builtin_vsx_xvcpsgndp: {
8559 llvm::Type *ResultType = ConvertType(E->getType());
8560 Value *X = EmitScalarExpr(E->getArg(0));
8561 Value *Y = EmitScalarExpr(E->getArg(1));
8562 ID = Intrinsic::copysign;
8563 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8564 return Builder.CreateCall(F, {X, Y});
8565 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008566 // Rounding/truncation
8567 case PPC::BI__builtin_vsx_xvrspip:
8568 case PPC::BI__builtin_vsx_xvrdpip:
8569 case PPC::BI__builtin_vsx_xvrdpim:
8570 case PPC::BI__builtin_vsx_xvrspim:
8571 case PPC::BI__builtin_vsx_xvrdpi:
8572 case PPC::BI__builtin_vsx_xvrspi:
8573 case PPC::BI__builtin_vsx_xvrdpic:
8574 case PPC::BI__builtin_vsx_xvrspic:
8575 case PPC::BI__builtin_vsx_xvrdpiz:
8576 case PPC::BI__builtin_vsx_xvrspiz: {
8577 llvm::Type *ResultType = ConvertType(E->getType());
8578 Value *X = EmitScalarExpr(E->getArg(0));
8579 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
8580 BuiltinID == PPC::BI__builtin_vsx_xvrspim)
8581 ID = Intrinsic::floor;
8582 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
8583 BuiltinID == PPC::BI__builtin_vsx_xvrspi)
8584 ID = Intrinsic::round;
8585 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
8586 BuiltinID == PPC::BI__builtin_vsx_xvrspic)
8587 ID = Intrinsic::nearbyint;
8588 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
8589 BuiltinID == PPC::BI__builtin_vsx_xvrspip)
8590 ID = Intrinsic::ceil;
8591 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
8592 BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
8593 ID = Intrinsic::trunc;
8594 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8595 return Builder.CreateCall(F, X);
8596 }
Kit Bartonfbab1582016-03-09 19:28:31 +00008597
8598 // Absolute value
8599 case PPC::BI__builtin_vsx_xvabsdp:
8600 case PPC::BI__builtin_vsx_xvabssp: {
8601 llvm::Type *ResultType = ConvertType(E->getType());
8602 Value *X = EmitScalarExpr(E->getArg(0));
8603 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
8604 return Builder.CreateCall(F, X);
8605 }
8606
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008607 // FMA variations
8608 case PPC::BI__builtin_vsx_xvmaddadp:
8609 case PPC::BI__builtin_vsx_xvmaddasp:
8610 case PPC::BI__builtin_vsx_xvnmaddadp:
8611 case PPC::BI__builtin_vsx_xvnmaddasp:
8612 case PPC::BI__builtin_vsx_xvmsubadp:
8613 case PPC::BI__builtin_vsx_xvmsubasp:
8614 case PPC::BI__builtin_vsx_xvnmsubadp:
8615 case PPC::BI__builtin_vsx_xvnmsubasp: {
8616 llvm::Type *ResultType = ConvertType(E->getType());
8617 Value *X = EmitScalarExpr(E->getArg(0));
8618 Value *Y = EmitScalarExpr(E->getArg(1));
8619 Value *Z = EmitScalarExpr(E->getArg(2));
8620 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
8621 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
8622 switch (BuiltinID) {
8623 case PPC::BI__builtin_vsx_xvmaddadp:
8624 case PPC::BI__builtin_vsx_xvmaddasp:
8625 return Builder.CreateCall(F, {X, Y, Z});
8626 case PPC::BI__builtin_vsx_xvnmaddadp:
8627 case PPC::BI__builtin_vsx_xvnmaddasp:
8628 return Builder.CreateFSub(Zero,
8629 Builder.CreateCall(F, {X, Y, Z}), "sub");
8630 case PPC::BI__builtin_vsx_xvmsubadp:
8631 case PPC::BI__builtin_vsx_xvmsubasp:
8632 return Builder.CreateCall(F,
8633 {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8634 case PPC::BI__builtin_vsx_xvnmsubadp:
8635 case PPC::BI__builtin_vsx_xvnmsubasp:
8636 Value *FsubRes =
8637 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8638 return Builder.CreateFSub(Zero, FsubRes, "sub");
8639 }
8640 llvm_unreachable("Unknown FMA operation");
8641 return nullptr; // Suppress no-return warning
8642 }
Sean Fertile96d9e0e2017-01-05 21:43:30 +00008643
8644 case PPC::BI__builtin_vsx_insertword: {
8645 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
8646
8647 // Third argument is a compile time constant int. It must be clamped to
8648 // to the range [0, 12].
8649 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8650 assert(ArgCI &&
8651 "Third arg to xxinsertw intrinsic must be constant integer");
8652 const int64_t MaxIndex = 12;
8653 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8654
8655 // The builtin semantics don't exactly match the xxinsertw instructions
8656 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the
8657 // word from the first argument, and inserts it in the second argument. The
8658 // instruction extracts the word from its second input register and inserts
8659 // it into its first input register, so swap the first and second arguments.
8660 std::swap(Ops[0], Ops[1]);
8661
8662 // Need to cast the second argument from a vector of unsigned int to a
8663 // vector of long long.
8664 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8665
8666 if (getTarget().isLittleEndian()) {
8667 // Create a shuffle mask of (1, 0)
8668 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8669 ConstantInt::get(Int32Ty, 0)
8670 };
8671 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8672
8673 // Reverse the double words in the vector we will extract from.
8674 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8675 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask);
8676
8677 // Reverse the index.
8678 Index = MaxIndex - Index;
8679 }
8680
8681 // Intrinsic expects the first arg to be a vector of int.
8682 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8683 Ops[2] = ConstantInt::getSigned(Int32Ty, Index);
8684 return Builder.CreateCall(F, Ops);
8685 }
8686
8687 case PPC::BI__builtin_vsx_extractuword: {
8688 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
8689
8690 // Intrinsic expects the first argument to be a vector of doublewords.
8691 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8692
8693 // The second argument is a compile time constant int that needs to
8694 // be clamped to the range [0, 12].
8695 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]);
8696 assert(ArgCI &&
8697 "Second Arg to xxextractuw intrinsic must be a constant integer!");
8698 const int64_t MaxIndex = 12;
8699 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8700
8701 if (getTarget().isLittleEndian()) {
8702 // Reverse the index.
8703 Index = MaxIndex - Index;
8704 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8705
8706 // Emit the call, then reverse the double words of the results vector.
8707 Value *Call = Builder.CreateCall(F, Ops);
8708
8709 // Create a shuffle mask of (1, 0)
8710 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8711 ConstantInt::get(Int32Ty, 0)
8712 };
8713 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8714
8715 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask);
8716 return ShuffleCall;
8717 } else {
8718 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8719 return Builder.CreateCall(F, Ops);
8720 }
8721 }
Tony Jiangbbc48e92017-05-24 15:13:32 +00008722
8723 case PPC::BI__builtin_vsx_xxpermdi: {
8724 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8725 assert(ArgCI && "Third arg must be constant integer!");
8726
8727 unsigned Index = ArgCI->getZExtValue();
8728 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8729 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8730
8731 // Element zero comes from the first input vector and element one comes from
8732 // the second. The element indices within each vector are numbered in big
8733 // endian order so the shuffle mask must be adjusted for this on little
8734 // endian platforms (i.e. index is complemented and source vector reversed).
8735 unsigned ElemIdx0;
8736 unsigned ElemIdx1;
8737 if (getTarget().isLittleEndian()) {
8738 ElemIdx0 = (~Index & 1) + 2;
8739 ElemIdx1 = (~Index & 2) >> 1;
8740 } else { // BigEndian
8741 ElemIdx0 = (Index & 2) >> 1;
8742 ElemIdx1 = 2 + (Index & 1);
8743 }
8744
8745 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0),
8746 ConstantInt::get(Int32Ty, ElemIdx1)};
8747 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8748
8749 Value *ShuffleCall =
8750 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8751 QualType BIRetType = E->getType();
8752 auto RetTy = ConvertType(BIRetType);
8753 return Builder.CreateBitCast(ShuffleCall, RetTy);
8754 }
Tony Jiang9aa2c032017-05-24 15:54:13 +00008755
8756 case PPC::BI__builtin_vsx_xxsldwi: {
8757 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8758 assert(ArgCI && "Third argument must be a compile time constant");
8759 unsigned Index = ArgCI->getZExtValue() & 0x3;
8760 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8761 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4));
8762
8763 // Create a shuffle mask
8764 unsigned ElemIdx0;
8765 unsigned ElemIdx1;
8766 unsigned ElemIdx2;
8767 unsigned ElemIdx3;
8768 if (getTarget().isLittleEndian()) {
8769 // Little endian element N comes from element 8+N-Index of the
8770 // concatenated wide vector (of course, using modulo arithmetic on
8771 // the total number of elements).
8772 ElemIdx0 = (8 - Index) % 8;
8773 ElemIdx1 = (9 - Index) % 8;
8774 ElemIdx2 = (10 - Index) % 8;
8775 ElemIdx3 = (11 - Index) % 8;
8776 } else {
8777 // Big endian ElemIdx<N> = Index + N
8778 ElemIdx0 = Index;
8779 ElemIdx1 = Index + 1;
8780 ElemIdx2 = Index + 2;
8781 ElemIdx3 = Index + 3;
8782 }
8783
8784 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0),
8785 ConstantInt::get(Int32Ty, ElemIdx1),
8786 ConstantInt::get(Int32Ty, ElemIdx2),
8787 ConstantInt::get(Int32Ty, ElemIdx3)};
8788
8789 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8790 Value *ShuffleCall =
8791 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8792 QualType BIRetType = E->getType();
8793 auto RetTy = ConvertType(BIRetType);
8794 return Builder.CreateBitCast(ShuffleCall, RetTy);
8795 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008796 }
Mike Stump11289f42009-09-09 15:08:12 +00008797}
Matt Arsenault56f008d2014-06-24 20:45:01 +00008798
Matt Arsenault3ea39f92015-06-19 17:54:10 +00008799Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
8800 const CallExpr *E) {
Matt Arsenault56f008d2014-06-24 20:45:01 +00008801 switch (BuiltinID) {
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008802 case AMDGPU::BI__builtin_amdgcn_div_scale:
8803 case AMDGPU::BI__builtin_amdgcn_div_scalef: {
Matt Arsenault56f008d2014-06-24 20:45:01 +00008804 // Translate from the intrinsics's struct return to the builtin's out
8805 // argument.
8806
John McCall7f416cc2015-09-08 08:05:57 +00008807 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3));
Matt Arsenault56f008d2014-06-24 20:45:01 +00008808
8809 llvm::Value *X = EmitScalarExpr(E->getArg(0));
8810 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
8811 llvm::Value *Z = EmitScalarExpr(E->getArg(2));
8812
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008813 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale,
Matt Arsenault56f008d2014-06-24 20:45:01 +00008814 X->getType());
8815
David Blaikie43f9bb72015-05-18 22:14:03 +00008816 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z});
Matt Arsenault56f008d2014-06-24 20:45:01 +00008817
8818 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0);
8819 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1);
8820
8821 llvm::Type *RealFlagType
John McCall7f416cc2015-09-08 08:05:57 +00008822 = FlagOutPtr.getPointer()->getType()->getPointerElementType();
Matt Arsenault56f008d2014-06-24 20:45:01 +00008823
8824 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType);
John McCall7f416cc2015-09-08 08:05:57 +00008825 Builder.CreateStore(FlagExt, FlagOutPtr);
Matt Arsenault56f008d2014-06-24 20:45:01 +00008826 return Result;
Matt Arsenault85877112014-07-15 17:23:46 +00008827 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008828 case AMDGPU::BI__builtin_amdgcn_div_fmas:
8829 case AMDGPU::BI__builtin_amdgcn_div_fmasf: {
Matt Arsenault2174a9d2014-10-21 22:21:41 +00008830 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0));
8831 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1));
8832 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2));
8833 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3));
8834
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008835 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas,
Matt Arsenault2174a9d2014-10-21 22:21:41 +00008836 Src0->getType());
8837 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3);
David Blaikie43f9bb72015-05-18 22:14:03 +00008838 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool});
Matt Arsenault2174a9d2014-10-21 22:21:41 +00008839 }
Changpeng Fang03bdd8f2016-08-18 22:04:54 +00008840
8841 case AMDGPU::BI__builtin_amdgcn_ds_swizzle:
8842 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle);
Yaxun Liu4d867992017-03-10 01:30:46 +00008843 case AMDGPU::BI__builtin_amdgcn_mov_dpp: {
8844 llvm::SmallVector<llvm::Value *, 5> Args;
8845 for (unsigned I = 0; I != 5; ++I)
8846 Args.push_back(EmitScalarExpr(E->getArg(I)));
8847 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp,
8848 Args[0]->getType());
8849 return Builder.CreateCall(F, Args);
8850 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008851 case AMDGPU::BI__builtin_amdgcn_div_fixup:
8852 case AMDGPU::BI__builtin_amdgcn_div_fixupf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008853 case AMDGPU::BI__builtin_amdgcn_div_fixuph:
Matt Arsenaultf652cae2016-07-01 17:38:14 +00008854 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008855 case AMDGPU::BI__builtin_amdgcn_trig_preop:
8856 case AMDGPU::BI__builtin_amdgcn_trig_preopf:
8857 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop);
8858 case AMDGPU::BI__builtin_amdgcn_rcp:
8859 case AMDGPU::BI__builtin_amdgcn_rcpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008860 case AMDGPU::BI__builtin_amdgcn_rcph:
Matt Arsenault105e8922016-02-03 17:49:38 +00008861 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008862 case AMDGPU::BI__builtin_amdgcn_rsq:
8863 case AMDGPU::BI__builtin_amdgcn_rsqf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008864 case AMDGPU::BI__builtin_amdgcn_rsqh:
Matt Arsenault105e8922016-02-03 17:49:38 +00008865 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq);
Matt Arsenaultf5c1f472016-02-13 01:03:09 +00008866 case AMDGPU::BI__builtin_amdgcn_rsq_clamp:
8867 case AMDGPU::BI__builtin_amdgcn_rsq_clampf:
8868 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp);
Matt Arsenault9b277b42016-02-13 01:21:09 +00008869 case AMDGPU::BI__builtin_amdgcn_sinf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008870 case AMDGPU::BI__builtin_amdgcn_sinh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00008871 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin);
8872 case AMDGPU::BI__builtin_amdgcn_cosf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008873 case AMDGPU::BI__builtin_amdgcn_cosh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00008874 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos);
8875 case AMDGPU::BI__builtin_amdgcn_log_clampf:
8876 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008877 case AMDGPU::BI__builtin_amdgcn_ldexp:
8878 case AMDGPU::BI__builtin_amdgcn_ldexpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008879 case AMDGPU::BI__builtin_amdgcn_ldexph:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008880 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp);
Matt Arsenault3fb96332016-03-30 22:57:40 +00008881 case AMDGPU::BI__builtin_amdgcn_frexp_mant:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008882 case AMDGPU::BI__builtin_amdgcn_frexp_mantf:
8883 case AMDGPU::BI__builtin_amdgcn_frexp_manth:
Matt Arsenault3fb96332016-03-30 22:57:40 +00008884 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant);
Matt Arsenault3fb96332016-03-30 22:57:40 +00008885 case AMDGPU::BI__builtin_amdgcn_frexp_exp:
Konstantin Zhuravlyov62ae8f62016-11-18 22:31:51 +00008886 case AMDGPU::BI__builtin_amdgcn_frexp_expf: {
8887 Value *Src0 = EmitScalarExpr(E->getArg(0));
8888 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
8889 { Builder.getInt32Ty(), Src0->getType() });
8890 return Builder.CreateCall(F, Src0);
8891 }
8892 case AMDGPU::BI__builtin_amdgcn_frexp_exph: {
8893 Value *Src0 = EmitScalarExpr(E->getArg(0));
8894 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
8895 { Builder.getInt16Ty(), Src0->getType() });
8896 return Builder.CreateCall(F, Src0);
8897 }
Matt Arsenault2d510592016-05-28 00:43:27 +00008898 case AMDGPU::BI__builtin_amdgcn_fract:
8899 case AMDGPU::BI__builtin_amdgcn_fractf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008900 case AMDGPU::BI__builtin_amdgcn_fracth:
Matt Arsenault2d510592016-05-28 00:43:27 +00008901 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract);
Wei Dingea41f352016-07-15 16:43:03 +00008902 case AMDGPU::BI__builtin_amdgcn_lerp:
8903 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp);
Wei Ding91c84502016-08-05 15:38:46 +00008904 case AMDGPU::BI__builtin_amdgcn_uicmp:
8905 case AMDGPU::BI__builtin_amdgcn_uicmpl:
8906 case AMDGPU::BI__builtin_amdgcn_sicmp:
8907 case AMDGPU::BI__builtin_amdgcn_sicmpl:
8908 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp);
8909 case AMDGPU::BI__builtin_amdgcn_fcmp:
8910 case AMDGPU::BI__builtin_amdgcn_fcmpf:
8911 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008912 case AMDGPU::BI__builtin_amdgcn_class:
8913 case AMDGPU::BI__builtin_amdgcn_classf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008914 case AMDGPU::BI__builtin_amdgcn_classh:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008915 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class);
Matt Arsenaulta274b202017-01-31 03:42:07 +00008916 case AMDGPU::BI__builtin_amdgcn_fmed3f:
Matt Arsenaulta0c6dca2017-02-22 20:55:59 +00008917 case AMDGPU::BI__builtin_amdgcn_fmed3h:
Matt Arsenaulta274b202017-01-31 03:42:07 +00008918 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3);
Matt Arsenault64665bc2016-06-28 00:13:17 +00008919 case AMDGPU::BI__builtin_amdgcn_read_exec: {
8920 CallInst *CI = cast<CallInst>(
8921 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec"));
8922 CI->setConvergent();
8923 return CI;
8924 }
Jan Veselyd7e03a52016-07-10 22:38:04 +00008925
8926 // amdgcn workitem
8927 case AMDGPU::BI__builtin_amdgcn_workitem_id_x:
8928 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024);
8929 case AMDGPU::BI__builtin_amdgcn_workitem_id_y:
8930 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024);
8931 case AMDGPU::BI__builtin_amdgcn_workitem_id_z:
8932 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024);
8933
Matt Arsenaultc86671d2016-07-15 21:33:02 +00008934 // r600 intrinsics
8935 case AMDGPU::BI__builtin_r600_recipsqrt_ieee:
8936 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef:
8937 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee);
Jan Veselyd7e03a52016-07-10 22:38:04 +00008938 case AMDGPU::BI__builtin_r600_read_tidig_x:
8939 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024);
8940 case AMDGPU::BI__builtin_r600_read_tidig_y:
8941 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024);
8942 case AMDGPU::BI__builtin_r600_read_tidig_z:
8943 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008944 default:
Matt Arsenault56f008d2014-06-24 20:45:01 +00008945 return nullptr;
8946 }
8947}
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008948
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008949/// Handle a SystemZ function in which the final argument is a pointer
8950/// to an int that receives the post-instruction CC value. At the LLVM level
8951/// this is represented as a function that returns a {result, cc} pair.
8952static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF,
8953 unsigned IntrinsicID,
8954 const CallExpr *E) {
8955 unsigned NumArgs = E->getNumArgs() - 1;
8956 SmallVector<Value *, 8> Args(NumArgs);
8957 for (unsigned I = 0; I < NumArgs; ++I)
8958 Args[I] = CGF.EmitScalarExpr(E->getArg(I));
John McCall7f416cc2015-09-08 08:05:57 +00008959 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs));
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008960 Value *F = CGF.CGM.getIntrinsic(IntrinsicID);
8961 Value *Call = CGF.Builder.CreateCall(F, Args);
8962 Value *CC = CGF.Builder.CreateExtractValue(Call, 1);
8963 CGF.Builder.CreateStore(CC, CCPtr);
8964 return CGF.Builder.CreateExtractValue(Call, 0);
8965}
8966
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008967Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
8968 const CallExpr *E) {
8969 switch (BuiltinID) {
8970 case SystemZ::BI__builtin_tbegin: {
8971 Value *TDB = EmitScalarExpr(E->getArg(0));
8972 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
8973 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin);
David Blaikie43f9bb72015-05-18 22:14:03 +00008974 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008975 }
8976 case SystemZ::BI__builtin_tbegin_nofloat: {
8977 Value *TDB = EmitScalarExpr(E->getArg(0));
8978 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
8979 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat);
David Blaikie43f9bb72015-05-18 22:14:03 +00008980 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008981 }
8982 case SystemZ::BI__builtin_tbeginc: {
8983 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy);
8984 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08);
8985 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc);
David Blaikie43f9bb72015-05-18 22:14:03 +00008986 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008987 }
8988 case SystemZ::BI__builtin_tabort: {
8989 Value *Data = EmitScalarExpr(E->getArg(0));
8990 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort);
8991 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort"));
8992 }
8993 case SystemZ::BI__builtin_non_tx_store: {
8994 Value *Address = EmitScalarExpr(E->getArg(0));
8995 Value *Data = EmitScalarExpr(E->getArg(1));
8996 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg);
David Blaikie43f9bb72015-05-18 22:14:03 +00008997 return Builder.CreateCall(F, {Data, Address});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008998 }
8999
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009000 // Vector builtins. Note that most vector builtins are mapped automatically
9001 // to target-specific LLVM intrinsics. The ones handled specially here can
9002 // be represented via standard LLVM IR, which is preferable to enable common
9003 // LLVM optimizations.
9004
9005 case SystemZ::BI__builtin_s390_vpopctb:
9006 case SystemZ::BI__builtin_s390_vpopcth:
9007 case SystemZ::BI__builtin_s390_vpopctf:
9008 case SystemZ::BI__builtin_s390_vpopctg: {
9009 llvm::Type *ResultType = ConvertType(E->getType());
9010 Value *X = EmitScalarExpr(E->getArg(0));
9011 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
9012 return Builder.CreateCall(F, X);
9013 }
9014
9015 case SystemZ::BI__builtin_s390_vclzb:
9016 case SystemZ::BI__builtin_s390_vclzh:
9017 case SystemZ::BI__builtin_s390_vclzf:
9018 case SystemZ::BI__builtin_s390_vclzg: {
9019 llvm::Type *ResultType = ConvertType(E->getType());
9020 Value *X = EmitScalarExpr(E->getArg(0));
9021 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
9022 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009023 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009024 }
9025
9026 case SystemZ::BI__builtin_s390_vctzb:
9027 case SystemZ::BI__builtin_s390_vctzh:
9028 case SystemZ::BI__builtin_s390_vctzf:
9029 case SystemZ::BI__builtin_s390_vctzg: {
9030 llvm::Type *ResultType = ConvertType(E->getType());
9031 Value *X = EmitScalarExpr(E->getArg(0));
9032 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
9033 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009034 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009035 }
9036
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009037 case SystemZ::BI__builtin_s390_vfsqsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009038 case SystemZ::BI__builtin_s390_vfsqdb: {
9039 llvm::Type *ResultType = ConvertType(E->getType());
9040 Value *X = EmitScalarExpr(E->getArg(0));
9041 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
9042 return Builder.CreateCall(F, X);
9043 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009044 case SystemZ::BI__builtin_s390_vfmasb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009045 case SystemZ::BI__builtin_s390_vfmadb: {
9046 llvm::Type *ResultType = ConvertType(E->getType());
9047 Value *X = EmitScalarExpr(E->getArg(0));
9048 Value *Y = EmitScalarExpr(E->getArg(1));
9049 Value *Z = EmitScalarExpr(E->getArg(2));
9050 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009051 return Builder.CreateCall(F, {X, Y, Z});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009052 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009053 case SystemZ::BI__builtin_s390_vfmssb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009054 case SystemZ::BI__builtin_s390_vfmsdb: {
9055 llvm::Type *ResultType = ConvertType(E->getType());
9056 Value *X = EmitScalarExpr(E->getArg(0));
9057 Value *Y = EmitScalarExpr(E->getArg(1));
9058 Value *Z = EmitScalarExpr(E->getArg(2));
9059 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9060 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009061 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009062 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009063 case SystemZ::BI__builtin_s390_vfnmasb:
9064 case SystemZ::BI__builtin_s390_vfnmadb: {
9065 llvm::Type *ResultType = ConvertType(E->getType());
9066 Value *X = EmitScalarExpr(E->getArg(0));
9067 Value *Y = EmitScalarExpr(E->getArg(1));
9068 Value *Z = EmitScalarExpr(E->getArg(2));
9069 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9070 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9071 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub");
9072 }
9073 case SystemZ::BI__builtin_s390_vfnmssb:
9074 case SystemZ::BI__builtin_s390_vfnmsdb: {
9075 llvm::Type *ResultType = ConvertType(E->getType());
9076 Value *X = EmitScalarExpr(E->getArg(0));
9077 Value *Y = EmitScalarExpr(E->getArg(1));
9078 Value *Z = EmitScalarExpr(E->getArg(2));
9079 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9080 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9081 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub");
9082 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ}));
9083 }
9084 case SystemZ::BI__builtin_s390_vflpsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009085 case SystemZ::BI__builtin_s390_vflpdb: {
9086 llvm::Type *ResultType = ConvertType(E->getType());
9087 Value *X = EmitScalarExpr(E->getArg(0));
9088 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9089 return Builder.CreateCall(F, X);
9090 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009091 case SystemZ::BI__builtin_s390_vflnsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009092 case SystemZ::BI__builtin_s390_vflndb: {
9093 llvm::Type *ResultType = ConvertType(E->getType());
9094 Value *X = EmitScalarExpr(E->getArg(0));
9095 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9096 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9097 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub");
9098 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009099 case SystemZ::BI__builtin_s390_vfisb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009100 case SystemZ::BI__builtin_s390_vfidb: {
9101 llvm::Type *ResultType = ConvertType(E->getType());
9102 Value *X = EmitScalarExpr(E->getArg(0));
9103 // Constant-fold the M4 and M5 mask arguments.
9104 llvm::APSInt M4, M5;
9105 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext());
9106 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext());
9107 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?");
9108 (void)IsConstM4; (void)IsConstM5;
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009109 // Check whether this instance can be represented via a LLVM standard
9110 // intrinsic. We only support some combinations of M4 and M5.
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009111 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9112 switch (M4.getZExtValue()) {
9113 default: break;
9114 case 0: // IEEE-inexact exception allowed
9115 switch (M5.getZExtValue()) {
9116 default: break;
9117 case 0: ID = Intrinsic::rint; break;
9118 }
9119 break;
9120 case 4: // IEEE-inexact exception suppressed
9121 switch (M5.getZExtValue()) {
9122 default: break;
9123 case 0: ID = Intrinsic::nearbyint; break;
9124 case 1: ID = Intrinsic::round; break;
9125 case 5: ID = Intrinsic::trunc; break;
9126 case 6: ID = Intrinsic::ceil; break;
9127 case 7: ID = Intrinsic::floor; break;
9128 }
9129 break;
9130 }
9131 if (ID != Intrinsic::not_intrinsic) {
9132 Function *F = CGM.getIntrinsic(ID, ResultType);
9133 return Builder.CreateCall(F, X);
9134 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009135 switch (BuiltinID) {
9136 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break;
9137 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break;
9138 default: llvm_unreachable("Unknown BuiltinID");
9139 }
9140 Function *F = CGM.getIntrinsic(ID);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009141 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9142 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5);
David Blaikie43f9bb72015-05-18 22:14:03 +00009143 return Builder.CreateCall(F, {X, M4Value, M5Value});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009144 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009145 case SystemZ::BI__builtin_s390_vfmaxsb:
9146 case SystemZ::BI__builtin_s390_vfmaxdb: {
9147 llvm::Type *ResultType = ConvertType(E->getType());
9148 Value *X = EmitScalarExpr(E->getArg(0));
9149 Value *Y = EmitScalarExpr(E->getArg(1));
9150 // Constant-fold the M4 mask argument.
9151 llvm::APSInt M4;
9152 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9153 assert(IsConstM4 && "Constant arg isn't actually constant?");
9154 (void)IsConstM4;
9155 // Check whether this instance can be represented via a LLVM standard
9156 // intrinsic. We only support some values of M4.
9157 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9158 switch (M4.getZExtValue()) {
9159 default: break;
9160 case 4: ID = Intrinsic::maxnum; break;
9161 }
9162 if (ID != Intrinsic::not_intrinsic) {
9163 Function *F = CGM.getIntrinsic(ID, ResultType);
9164 return Builder.CreateCall(F, {X, Y});
9165 }
9166 switch (BuiltinID) {
9167 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break;
9168 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break;
9169 default: llvm_unreachable("Unknown BuiltinID");
9170 }
9171 Function *F = CGM.getIntrinsic(ID);
9172 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9173 return Builder.CreateCall(F, {X, Y, M4Value});
9174 }
9175 case SystemZ::BI__builtin_s390_vfminsb:
9176 case SystemZ::BI__builtin_s390_vfmindb: {
9177 llvm::Type *ResultType = ConvertType(E->getType());
9178 Value *X = EmitScalarExpr(E->getArg(0));
9179 Value *Y = EmitScalarExpr(E->getArg(1));
9180 // Constant-fold the M4 mask argument.
9181 llvm::APSInt M4;
9182 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9183 assert(IsConstM4 && "Constant arg isn't actually constant?");
9184 (void)IsConstM4;
9185 // Check whether this instance can be represented via a LLVM standard
9186 // intrinsic. We only support some values of M4.
9187 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9188 switch (M4.getZExtValue()) {
9189 default: break;
9190 case 4: ID = Intrinsic::minnum; break;
9191 }
9192 if (ID != Intrinsic::not_intrinsic) {
9193 Function *F = CGM.getIntrinsic(ID, ResultType);
9194 return Builder.CreateCall(F, {X, Y});
9195 }
9196 switch (BuiltinID) {
9197 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break;
9198 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break;
9199 default: llvm_unreachable("Unknown BuiltinID");
9200 }
9201 Function *F = CGM.getIntrinsic(ID);
9202 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9203 return Builder.CreateCall(F, {X, Y, M4Value});
9204 }
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009205
9206 // Vector intrisincs that output the post-instruction CC value.
9207
9208#define INTRINSIC_WITH_CC(NAME) \
9209 case SystemZ::BI__builtin_##NAME: \
9210 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E)
9211
9212 INTRINSIC_WITH_CC(s390_vpkshs);
9213 INTRINSIC_WITH_CC(s390_vpksfs);
9214 INTRINSIC_WITH_CC(s390_vpksgs);
9215
9216 INTRINSIC_WITH_CC(s390_vpklshs);
9217 INTRINSIC_WITH_CC(s390_vpklsfs);
9218 INTRINSIC_WITH_CC(s390_vpklsgs);
9219
9220 INTRINSIC_WITH_CC(s390_vceqbs);
9221 INTRINSIC_WITH_CC(s390_vceqhs);
9222 INTRINSIC_WITH_CC(s390_vceqfs);
9223 INTRINSIC_WITH_CC(s390_vceqgs);
9224
9225 INTRINSIC_WITH_CC(s390_vchbs);
9226 INTRINSIC_WITH_CC(s390_vchhs);
9227 INTRINSIC_WITH_CC(s390_vchfs);
9228 INTRINSIC_WITH_CC(s390_vchgs);
9229
9230 INTRINSIC_WITH_CC(s390_vchlbs);
9231 INTRINSIC_WITH_CC(s390_vchlhs);
9232 INTRINSIC_WITH_CC(s390_vchlfs);
9233 INTRINSIC_WITH_CC(s390_vchlgs);
9234
9235 INTRINSIC_WITH_CC(s390_vfaebs);
9236 INTRINSIC_WITH_CC(s390_vfaehs);
9237 INTRINSIC_WITH_CC(s390_vfaefs);
9238
9239 INTRINSIC_WITH_CC(s390_vfaezbs);
9240 INTRINSIC_WITH_CC(s390_vfaezhs);
9241 INTRINSIC_WITH_CC(s390_vfaezfs);
9242
9243 INTRINSIC_WITH_CC(s390_vfeebs);
9244 INTRINSIC_WITH_CC(s390_vfeehs);
9245 INTRINSIC_WITH_CC(s390_vfeefs);
9246
9247 INTRINSIC_WITH_CC(s390_vfeezbs);
9248 INTRINSIC_WITH_CC(s390_vfeezhs);
9249 INTRINSIC_WITH_CC(s390_vfeezfs);
9250
9251 INTRINSIC_WITH_CC(s390_vfenebs);
9252 INTRINSIC_WITH_CC(s390_vfenehs);
9253 INTRINSIC_WITH_CC(s390_vfenefs);
9254
9255 INTRINSIC_WITH_CC(s390_vfenezbs);
9256 INTRINSIC_WITH_CC(s390_vfenezhs);
9257 INTRINSIC_WITH_CC(s390_vfenezfs);
9258
9259 INTRINSIC_WITH_CC(s390_vistrbs);
9260 INTRINSIC_WITH_CC(s390_vistrhs);
9261 INTRINSIC_WITH_CC(s390_vistrfs);
9262
9263 INTRINSIC_WITH_CC(s390_vstrcbs);
9264 INTRINSIC_WITH_CC(s390_vstrchs);
9265 INTRINSIC_WITH_CC(s390_vstrcfs);
9266
9267 INTRINSIC_WITH_CC(s390_vstrczbs);
9268 INTRINSIC_WITH_CC(s390_vstrczhs);
9269 INTRINSIC_WITH_CC(s390_vstrczfs);
9270
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009271 INTRINSIC_WITH_CC(s390_vfcesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009272 INTRINSIC_WITH_CC(s390_vfcedbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009273 INTRINSIC_WITH_CC(s390_vfchsbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009274 INTRINSIC_WITH_CC(s390_vfchdbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009275 INTRINSIC_WITH_CC(s390_vfchesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009276 INTRINSIC_WITH_CC(s390_vfchedbs);
9277
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009278 INTRINSIC_WITH_CC(s390_vftcisb);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009279 INTRINSIC_WITH_CC(s390_vftcidb);
9280
9281#undef INTRINSIC_WITH_CC
9282
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009283 default:
9284 return nullptr;
9285 }
9286}
Artem Belevichd21e5c62015-06-25 18:29:42 +00009287
9288Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
9289 const CallExpr *E) {
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009290 auto MakeLdg = [&](unsigned IntrinsicID) {
9291 Value *Ptr = EmitScalarExpr(E->getArg(0));
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009292 clang::CharUnits Align =
Krzysztof Parzyszek8f248232017-05-18 17:07:11 +00009293 getNaturalPointeeTypeAlignment(E->getArg(0)->getType());
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009294 return Builder.CreateCall(
9295 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9296 Ptr->getType()}),
9297 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())});
9298 };
Artem Belevichfda99052016-09-28 17:47:35 +00009299 auto MakeScopedAtomic = [&](unsigned IntrinsicID) {
9300 Value *Ptr = EmitScalarExpr(E->getArg(0));
9301 return Builder.CreateCall(
9302 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9303 Ptr->getType()}),
9304 {Ptr, EmitScalarExpr(E->getArg(1))});
9305 };
Artem Belevichd21e5c62015-06-25 18:29:42 +00009306 switch (BuiltinID) {
9307 case NVPTX::BI__nvvm_atom_add_gen_i:
9308 case NVPTX::BI__nvvm_atom_add_gen_l:
9309 case NVPTX::BI__nvvm_atom_add_gen_ll:
9310 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E);
9311
9312 case NVPTX::BI__nvvm_atom_sub_gen_i:
9313 case NVPTX::BI__nvvm_atom_sub_gen_l:
9314 case NVPTX::BI__nvvm_atom_sub_gen_ll:
9315 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E);
9316
9317 case NVPTX::BI__nvvm_atom_and_gen_i:
9318 case NVPTX::BI__nvvm_atom_and_gen_l:
9319 case NVPTX::BI__nvvm_atom_and_gen_ll:
9320 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E);
9321
9322 case NVPTX::BI__nvvm_atom_or_gen_i:
9323 case NVPTX::BI__nvvm_atom_or_gen_l:
9324 case NVPTX::BI__nvvm_atom_or_gen_ll:
9325 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E);
9326
9327 case NVPTX::BI__nvvm_atom_xor_gen_i:
9328 case NVPTX::BI__nvvm_atom_xor_gen_l:
9329 case NVPTX::BI__nvvm_atom_xor_gen_ll:
9330 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E);
9331
9332 case NVPTX::BI__nvvm_atom_xchg_gen_i:
9333 case NVPTX::BI__nvvm_atom_xchg_gen_l:
9334 case NVPTX::BI__nvvm_atom_xchg_gen_ll:
9335 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E);
9336
9337 case NVPTX::BI__nvvm_atom_max_gen_i:
9338 case NVPTX::BI__nvvm_atom_max_gen_l:
9339 case NVPTX::BI__nvvm_atom_max_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009340 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E);
9341
Artem Belevichd21e5c62015-06-25 18:29:42 +00009342 case NVPTX::BI__nvvm_atom_max_gen_ui:
9343 case NVPTX::BI__nvvm_atom_max_gen_ul:
9344 case NVPTX::BI__nvvm_atom_max_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009345 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009346
9347 case NVPTX::BI__nvvm_atom_min_gen_i:
9348 case NVPTX::BI__nvvm_atom_min_gen_l:
9349 case NVPTX::BI__nvvm_atom_min_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009350 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E);
9351
Artem Belevichd21e5c62015-06-25 18:29:42 +00009352 case NVPTX::BI__nvvm_atom_min_gen_ui:
9353 case NVPTX::BI__nvvm_atom_min_gen_ul:
9354 case NVPTX::BI__nvvm_atom_min_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009355 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009356
9357 case NVPTX::BI__nvvm_atom_cas_gen_i:
9358 case NVPTX::BI__nvvm_atom_cas_gen_l:
9359 case NVPTX::BI__nvvm_atom_cas_gen_ll:
Jingyue Wuf1eca252015-09-30 21:49:32 +00009360 // __nvvm_atom_cas_gen_* should return the old value rather than the
9361 // success flag.
9362 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009363
9364 case NVPTX::BI__nvvm_atom_add_gen_f: {
9365 Value *Ptr = EmitScalarExpr(E->getArg(0));
9366 Value *Val = EmitScalarExpr(E->getArg(1));
9367 // atomicrmw only deals with integer arguments so we need to use
9368 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that.
9369 Value *FnALAF32 =
9370 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType());
9371 return Builder.CreateCall(FnALAF32, {Ptr, Val});
9372 }
9373
Justin Lebar717d2b02016-03-22 00:09:28 +00009374 case NVPTX::BI__nvvm_atom_inc_gen_ui: {
9375 Value *Ptr = EmitScalarExpr(E->getArg(0));
9376 Value *Val = EmitScalarExpr(E->getArg(1));
9377 Value *FnALI32 =
9378 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType());
9379 return Builder.CreateCall(FnALI32, {Ptr, Val});
9380 }
9381
9382 case NVPTX::BI__nvvm_atom_dec_gen_ui: {
9383 Value *Ptr = EmitScalarExpr(E->getArg(0));
9384 Value *Val = EmitScalarExpr(E->getArg(1));
9385 Value *FnALD32 =
9386 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType());
9387 return Builder.CreateCall(FnALD32, {Ptr, Val});
9388 }
9389
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009390 case NVPTX::BI__nvvm_ldg_c:
9391 case NVPTX::BI__nvvm_ldg_c2:
9392 case NVPTX::BI__nvvm_ldg_c4:
9393 case NVPTX::BI__nvvm_ldg_s:
9394 case NVPTX::BI__nvvm_ldg_s2:
9395 case NVPTX::BI__nvvm_ldg_s4:
9396 case NVPTX::BI__nvvm_ldg_i:
9397 case NVPTX::BI__nvvm_ldg_i2:
9398 case NVPTX::BI__nvvm_ldg_i4:
9399 case NVPTX::BI__nvvm_ldg_l:
9400 case NVPTX::BI__nvvm_ldg_ll:
9401 case NVPTX::BI__nvvm_ldg_ll2:
9402 case NVPTX::BI__nvvm_ldg_uc:
9403 case NVPTX::BI__nvvm_ldg_uc2:
9404 case NVPTX::BI__nvvm_ldg_uc4:
9405 case NVPTX::BI__nvvm_ldg_us:
9406 case NVPTX::BI__nvvm_ldg_us2:
9407 case NVPTX::BI__nvvm_ldg_us4:
9408 case NVPTX::BI__nvvm_ldg_ui:
9409 case NVPTX::BI__nvvm_ldg_ui2:
9410 case NVPTX::BI__nvvm_ldg_ui4:
9411 case NVPTX::BI__nvvm_ldg_ul:
9412 case NVPTX::BI__nvvm_ldg_ull:
9413 case NVPTX::BI__nvvm_ldg_ull2:
9414 // PTX Interoperability section 2.2: "For a vector with an even number of
9415 // elements, its alignment is set to number of elements times the alignment
9416 // of its member: n*alignof(t)."
9417 return MakeLdg(Intrinsic::nvvm_ldg_global_i);
9418 case NVPTX::BI__nvvm_ldg_f:
9419 case NVPTX::BI__nvvm_ldg_f2:
9420 case NVPTX::BI__nvvm_ldg_f4:
9421 case NVPTX::BI__nvvm_ldg_d:
9422 case NVPTX::BI__nvvm_ldg_d2:
9423 return MakeLdg(Intrinsic::nvvm_ldg_global_f);
Artem Belevichfda99052016-09-28 17:47:35 +00009424
9425 case NVPTX::BI__nvvm_atom_cta_add_gen_i:
9426 case NVPTX::BI__nvvm_atom_cta_add_gen_l:
9427 case NVPTX::BI__nvvm_atom_cta_add_gen_ll:
9428 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta);
9429 case NVPTX::BI__nvvm_atom_sys_add_gen_i:
9430 case NVPTX::BI__nvvm_atom_sys_add_gen_l:
9431 case NVPTX::BI__nvvm_atom_sys_add_gen_ll:
9432 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys);
9433 case NVPTX::BI__nvvm_atom_cta_add_gen_f:
9434 case NVPTX::BI__nvvm_atom_cta_add_gen_d:
9435 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta);
9436 case NVPTX::BI__nvvm_atom_sys_add_gen_f:
9437 case NVPTX::BI__nvvm_atom_sys_add_gen_d:
9438 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys);
9439 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i:
9440 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l:
9441 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll:
9442 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta);
9443 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i:
9444 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l:
9445 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll:
9446 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys);
9447 case NVPTX::BI__nvvm_atom_cta_max_gen_i:
9448 case NVPTX::BI__nvvm_atom_cta_max_gen_ui:
9449 case NVPTX::BI__nvvm_atom_cta_max_gen_l:
9450 case NVPTX::BI__nvvm_atom_cta_max_gen_ul:
9451 case NVPTX::BI__nvvm_atom_cta_max_gen_ll:
9452 case NVPTX::BI__nvvm_atom_cta_max_gen_ull:
9453 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta);
9454 case NVPTX::BI__nvvm_atom_sys_max_gen_i:
9455 case NVPTX::BI__nvvm_atom_sys_max_gen_ui:
9456 case NVPTX::BI__nvvm_atom_sys_max_gen_l:
9457 case NVPTX::BI__nvvm_atom_sys_max_gen_ul:
9458 case NVPTX::BI__nvvm_atom_sys_max_gen_ll:
9459 case NVPTX::BI__nvvm_atom_sys_max_gen_ull:
9460 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys);
9461 case NVPTX::BI__nvvm_atom_cta_min_gen_i:
9462 case NVPTX::BI__nvvm_atom_cta_min_gen_ui:
9463 case NVPTX::BI__nvvm_atom_cta_min_gen_l:
9464 case NVPTX::BI__nvvm_atom_cta_min_gen_ul:
9465 case NVPTX::BI__nvvm_atom_cta_min_gen_ll:
9466 case NVPTX::BI__nvvm_atom_cta_min_gen_ull:
9467 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta);
9468 case NVPTX::BI__nvvm_atom_sys_min_gen_i:
9469 case NVPTX::BI__nvvm_atom_sys_min_gen_ui:
9470 case NVPTX::BI__nvvm_atom_sys_min_gen_l:
9471 case NVPTX::BI__nvvm_atom_sys_min_gen_ul:
9472 case NVPTX::BI__nvvm_atom_sys_min_gen_ll:
9473 case NVPTX::BI__nvvm_atom_sys_min_gen_ull:
9474 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys);
9475 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui:
9476 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta);
9477 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui:
9478 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta);
9479 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui:
9480 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys);
9481 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui:
9482 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys);
9483 case NVPTX::BI__nvvm_atom_cta_and_gen_i:
9484 case NVPTX::BI__nvvm_atom_cta_and_gen_l:
9485 case NVPTX::BI__nvvm_atom_cta_and_gen_ll:
9486 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta);
9487 case NVPTX::BI__nvvm_atom_sys_and_gen_i:
9488 case NVPTX::BI__nvvm_atom_sys_and_gen_l:
9489 case NVPTX::BI__nvvm_atom_sys_and_gen_ll:
9490 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys);
9491 case NVPTX::BI__nvvm_atom_cta_or_gen_i:
9492 case NVPTX::BI__nvvm_atom_cta_or_gen_l:
9493 case NVPTX::BI__nvvm_atom_cta_or_gen_ll:
9494 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta);
9495 case NVPTX::BI__nvvm_atom_sys_or_gen_i:
9496 case NVPTX::BI__nvvm_atom_sys_or_gen_l:
9497 case NVPTX::BI__nvvm_atom_sys_or_gen_ll:
9498 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys);
9499 case NVPTX::BI__nvvm_atom_cta_xor_gen_i:
9500 case NVPTX::BI__nvvm_atom_cta_xor_gen_l:
9501 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll:
9502 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta);
9503 case NVPTX::BI__nvvm_atom_sys_xor_gen_i:
9504 case NVPTX::BI__nvvm_atom_sys_xor_gen_l:
9505 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll:
9506 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys);
9507 case NVPTX::BI__nvvm_atom_cta_cas_gen_i:
9508 case NVPTX::BI__nvvm_atom_cta_cas_gen_l:
9509 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: {
9510 Value *Ptr = EmitScalarExpr(E->getArg(0));
9511 return Builder.CreateCall(
9512 CGM.getIntrinsic(
9513 Intrinsic::nvvm_atomic_cas_gen_i_cta,
9514 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9515 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9516 }
9517 case NVPTX::BI__nvvm_atom_sys_cas_gen_i:
9518 case NVPTX::BI__nvvm_atom_sys_cas_gen_l:
9519 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: {
9520 Value *Ptr = EmitScalarExpr(E->getArg(0));
9521 return Builder.CreateCall(
9522 CGM.getIntrinsic(
9523 Intrinsic::nvvm_atomic_cas_gen_i_sys,
9524 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9525 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9526 }
Artem Belevichd21e5c62015-06-25 18:29:42 +00009527 default:
9528 return nullptr;
9529 }
9530}
Dan Gohmanc2853072015-09-03 22:51:53 +00009531
9532Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
9533 const CallExpr *E) {
9534 switch (BuiltinID) {
Derek Schuffdbd24b42016-05-02 17:26:19 +00009535 case WebAssembly::BI__builtin_wasm_current_memory: {
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009536 llvm::Type *ResultType = ConvertType(E->getType());
Derek Schuffdbd24b42016-05-02 17:26:19 +00009537 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType);
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009538 return Builder.CreateCall(Callee);
9539 }
Dan Gohman24f0a082015-11-05 20:16:37 +00009540 case WebAssembly::BI__builtin_wasm_grow_memory: {
Dan Gohman266b38a2015-10-02 20:20:01 +00009541 Value *X = EmitScalarExpr(E->getArg(0));
Dan Gohman24f0a082015-11-05 20:16:37 +00009542 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType());
Dan Gohman266b38a2015-10-02 20:20:01 +00009543 return Builder.CreateCall(Callee, X);
9544 }
Heejin Ahnb92440e2017-06-30 00:44:01 +00009545 case WebAssembly::BI__builtin_wasm_throw: {
9546 Value *Tag = EmitScalarExpr(E->getArg(0));
9547 Value *Obj = EmitScalarExpr(E->getArg(1));
9548 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
9549 return Builder.CreateCall(Callee, {Tag, Obj});
9550 }
9551 case WebAssembly::BI__builtin_wasm_rethrow: {
9552 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow);
9553 return Builder.CreateCall(Callee);
9554 }
Dan Gohmanc2853072015-09-03 22:51:53 +00009555
9556 default:
9557 return nullptr;
9558 }
9559}