blob: e6ae74a73cecaf8c4959fe44ebb3eabf65b5e93e [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"
Kit Barton8246f282015-03-25 19:41:41 +000033#include <sstream>
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +000034
Anders Carlsson1d8e5212007-08-20 18:05:56 +000035using namespace clang;
36using namespace CodeGen;
Anders Carlssona020c432007-12-09 21:20:04 +000037using namespace llvm;
38
Sean Fertile96d9e0e2017-01-05 21:43:30 +000039static
40int64_t clamp(int64_t Value, int64_t Low, int64_t High) {
41 return std::min(High, std::max(Low, Value));
42}
43
John McCall30e4efd2011-09-13 23:05:03 +000044/// getBuiltinLibFunction - Given a builtin id for a function like
45/// "__builtin_fabsf", return a Function* for "fabsf".
John McCallb92ab1a2016-10-26 23:46:34 +000046llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
47 unsigned BuiltinID) {
John McCall30e4efd2011-09-13 23:05:03 +000048 assert(Context.BuiltinInfo.isLibFunction(BuiltinID));
49
50 // Get the name, skip over the __builtin_ prefix (if necessary).
51 StringRef Name;
52 GlobalDecl D(FD);
53
54 // If the builtin has been declared explicitly with an assembler label,
55 // use the mangled name. This differs from the plain label on platforms
56 // that prefix labels.
57 if (FD->hasAttr<AsmLabelAttr>())
58 Name = getMangledName(D);
59 else
Mehdi Amini7186a432016-10-11 19:04:24 +000060 Name = Context.BuiltinInfo.getName(BuiltinID) + 10;
John McCall30e4efd2011-09-13 23:05:03 +000061
62 llvm::FunctionType *Ty =
63 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType()));
64
65 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false);
66}
67
John McCall3a7f6922010-10-27 20:58:56 +000068/// Emit the conversions required to turn the given value into an
69/// integer of the given size.
70static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V,
Chris Lattner2192fe52011-07-18 04:24:23 +000071 QualType T, llvm::IntegerType *IntType) {
John McCall3a7f6922010-10-27 20:58:56 +000072 V = CGF.EmitToMemory(V, T);
Chris Lattner07e96862010-10-01 23:43:16 +000073
John McCall3a7f6922010-10-27 20:58:56 +000074 if (V->getType()->isPointerTy())
75 return CGF.Builder.CreatePtrToInt(V, IntType);
76
77 assert(V->getType() == IntType);
78 return V;
Chandler Carruthbc8cab12010-07-18 07:23:17 +000079}
80
John McCall3a7f6922010-10-27 20:58:56 +000081static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V,
Chris Lattner2192fe52011-07-18 04:24:23 +000082 QualType T, llvm::Type *ResultType) {
John McCall3a7f6922010-10-27 20:58:56 +000083 V = CGF.EmitFromMemory(V, T);
84
85 if (ResultType->isPointerTy())
86 return CGF.Builder.CreateIntToPtr(V, ResultType);
87
88 assert(V->getType() == ResultType);
89 return V;
Chandler Carruthbc8cab12010-07-18 07:23:17 +000090}
91
Daniel Dunbar4fab57d2009-04-07 00:55:51 +000092/// Utility to insert an atomic instruction based on Instrinsic::ID
93/// and the expression node.
Artem Belevichd21e5c62015-06-25 18:29:42 +000094static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF,
95 llvm::AtomicRMWInst::BinOp Kind,
96 const CallExpr *E) {
John McCall3a7f6922010-10-27 20:58:56 +000097 QualType T = E->getType();
98 assert(E->getArg(0)->getType()->isPointerType());
99 assert(CGF.getContext().hasSameUnqualifiedType(T,
100 E->getArg(0)->getType()->getPointeeType()));
101 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
102
Chris Lattnerb2f659b2010-09-21 23:40:48 +0000103 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +0000104 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
John McCall6bde9542010-10-26 22:09:15 +0000105
Chris Lattnera5f58b02011-07-09 17:41:47 +0000106 llvm::IntegerType *IntType =
John McCall3a7f6922010-10-27 20:58:56 +0000107 llvm::IntegerType::get(CGF.getLLVMContext(),
108 CGF.getContext().getTypeSize(T));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000109 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
John McCall3a7f6922010-10-27 20:58:56 +0000110
John McCall3a7f6922010-10-27 20:58:56 +0000111 llvm::Value *Args[2];
112 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
113 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
Chris Lattner2192fe52011-07-18 04:24:23 +0000114 llvm::Type *ValueType = Args[1]->getType();
John McCall3a7f6922010-10-27 20:58:56 +0000115 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
116
JF Bastien92f4ef12016-04-06 17:26:42 +0000117 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
118 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
Artem Belevichd21e5c62015-06-25 18:29:42 +0000119 return EmitFromInt(CGF, Result, T, ValueType);
120}
121
Michael Zolotukhin84df1232015-09-08 23:52:33 +0000122static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) {
123 Value *Val = CGF.EmitScalarExpr(E->getArg(0));
124 Value *Address = CGF.EmitScalarExpr(E->getArg(1));
125
126 // Convert the type of the pointer to a pointer to the stored type.
127 Val = CGF.EmitToMemory(Val, E->getArg(0)->getType());
128 Value *BC = CGF.Builder.CreateBitCast(
129 Address, llvm::PointerType::getUnqual(Val->getType()), "cast");
130 LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType());
131 LV.setNontemporal(true);
132 CGF.EmitStoreOfScalar(Val, LV, false);
133 return nullptr;
134}
135
136static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) {
137 Value *Address = CGF.EmitScalarExpr(E->getArg(0));
138
139 LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType());
140 LV.setNontemporal(true);
141 return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
142}
143
Artem Belevichd21e5c62015-06-25 18:29:42 +0000144static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
145 llvm::AtomicRMWInst::BinOp Kind,
146 const CallExpr *E) {
147 return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +0000148}
149
150/// Utility to insert an atomic instruction based Instrinsic::ID and
John McCall3a7f6922010-10-27 20:58:56 +0000151/// the expression node, where the return value is the result of the
152/// operation.
Chris Lattner43660c52010-05-06 05:35:16 +0000153static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
Eli Friedmane9f81132011-09-07 01:41:24 +0000154 llvm::AtomicRMWInst::BinOp Kind,
155 const CallExpr *E,
Hal Finkeld2208b52014-10-02 20:53:50 +0000156 Instruction::BinaryOps Op,
157 bool Invert = false) {
John McCall3a7f6922010-10-27 20:58:56 +0000158 QualType T = E->getType();
159 assert(E->getArg(0)->getType()->isPointerType());
160 assert(CGF.getContext().hasSameUnqualifiedType(T,
161 E->getArg(0)->getType()->getPointeeType()));
162 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
163
Chris Lattnerb2f659b2010-09-21 23:40:48 +0000164 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +0000165 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
John McCall6bde9542010-10-26 22:09:15 +0000166
Chris Lattnera5f58b02011-07-09 17:41:47 +0000167 llvm::IntegerType *IntType =
John McCall3a7f6922010-10-27 20:58:56 +0000168 llvm::IntegerType::get(CGF.getLLVMContext(),
169 CGF.getContext().getTypeSize(T));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000170 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
John McCall3a7f6922010-10-27 20:58:56 +0000171
John McCall3a7f6922010-10-27 20:58:56 +0000172 llvm::Value *Args[2];
173 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
Chris Lattner2192fe52011-07-18 04:24:23 +0000174 llvm::Type *ValueType = Args[1]->getType();
John McCall3a7f6922010-10-27 20:58:56 +0000175 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
176 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
177
JF Bastien92f4ef12016-04-06 17:26:42 +0000178 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
179 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
John McCall3a7f6922010-10-27 20:58:56 +0000180 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]);
Hal Finkeld2208b52014-10-02 20:53:50 +0000181 if (Invert)
182 Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
183 llvm::ConstantInt::get(IntType, -1));
John McCall3a7f6922010-10-27 20:58:56 +0000184 Result = EmitFromInt(CGF, Result, T, ValueType);
185 return RValue::get(Result);
Mon P Wangb84407d2008-05-09 22:40:52 +0000186}
187
Artem Belevichd21e5c62015-06-25 18:29:42 +0000188/// @brief Utility to insert an atomic cmpxchg instruction.
189///
190/// @param CGF The current codegen function.
191/// @param E Builtin call expression to convert to cmpxchg.
192/// arg0 - address to operate on
193/// arg1 - value to compare with
194/// arg2 - new value
195/// @param ReturnBool Specifies whether to return success flag of
196/// cmpxchg result or the old value.
197///
198/// @returns result of cmpxchg, according to ReturnBool
199static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E,
200 bool ReturnBool) {
201 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType();
202 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
203 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
204
205 llvm::IntegerType *IntType = llvm::IntegerType::get(
206 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T));
207 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
208
209 Value *Args[3];
210 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
211 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
212 llvm::Type *ValueType = Args[1]->getType();
213 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
214 Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType);
215
JF Bastien92f4ef12016-04-06 17:26:42 +0000216 Value *Pair = CGF.Builder.CreateAtomicCmpXchg(
217 Args[0], Args[1], Args[2], llvm::AtomicOrdering::SequentiallyConsistent,
218 llvm::AtomicOrdering::SequentiallyConsistent);
Artem Belevichd21e5c62015-06-25 18:29:42 +0000219 if (ReturnBool)
220 // Extract boolean success flag and zext it to int.
221 return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1),
222 CGF.ConvertType(E->getType()));
223 else
224 // Extract old value and emit it using the same type as compare value.
225 return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T,
226 ValueType);
227}
228
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000229// Emit a simple mangled intrinsic that has 1 argument and a return type
230// matching the argument type.
231static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
232 const CallExpr *E,
233 unsigned IntrinsicID) {
234 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
235
236 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
237 return CGF.Builder.CreateCall(F, Src0);
238}
239
240// Emit an intrinsic that has 2 operands of the same type as its result.
241static Value *emitBinaryBuiltin(CodeGenFunction &CGF,
242 const CallExpr *E,
243 unsigned IntrinsicID) {
244 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
245 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
246
247 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
248 return CGF.Builder.CreateCall(F, { Src0, Src1 });
249}
250
251// Emit an intrinsic that has 3 operands of the same type as its result.
252static Value *emitTernaryBuiltin(CodeGenFunction &CGF,
253 const CallExpr *E,
254 unsigned IntrinsicID) {
255 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
256 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
257 llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2));
258
259 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
260 return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 });
261}
262
263// Emit an intrinsic that has 1 float or double operand, and 1 integer.
264static Value *emitFPIntBuiltin(CodeGenFunction &CGF,
265 const CallExpr *E,
266 unsigned IntrinsicID) {
267 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
268 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
269
270 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
271 return CGF.Builder.CreateCall(F, {Src0, Src1});
272}
273
Tom Stellardc4e0c102014-09-03 15:24:29 +0000274/// EmitFAbs - Emit a call to @llvm.fabs().
Reid Kleckner4cad00a2014-11-03 23:51:40 +0000275static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
Tom Stellardc4e0c102014-09-03 15:24:29 +0000276 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
277 llvm::CallInst *Call = CGF.Builder.CreateCall(F, V);
278 Call->setDoesNotAccessMemory();
279 return Call;
Chris Lattner43660c52010-05-06 05:35:16 +0000280}
281
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000282/// Emit the computation of the sign bit for a floating point value. Returns
283/// the i1 sign bit value.
284static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {
285 LLVMContext &C = CGF.CGM.getLLVMContext();
286
287 llvm::Type *Ty = V->getType();
288 int Width = Ty->getPrimitiveSizeInBits();
289 llvm::Type *IntTy = llvm::IntegerType::get(C, Width);
290 V = CGF.Builder.CreateBitCast(V, IntTy);
291 if (Ty->isPPC_FP128Ty()) {
Petar Jovanovic73d10442015-11-06 14:52:46 +0000292 // We want the sign bit of the higher-order double. The bitcast we just
293 // did works as if the double-double was stored to memory and then
294 // read as an i128. The "store" will put the higher-order double in the
295 // lower address in both little- and big-Endian modes, but the "load"
296 // will treat those bits as a different part of the i128: the low bits in
297 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian
298 // we need to shift the high bits down to the low before truncating.
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000299 Width >>= 1;
Simon Pilgrim532de1c2016-06-13 10:05:19 +0000300 if (CGF.getTarget().isBigEndian()) {
301 Value *ShiftCst = llvm::ConstantInt::get(IntTy, Width);
302 V = CGF.Builder.CreateLShr(V, ShiftCst);
303 }
304 // We are truncating value in order to extract the higher-order
305 // double, which we will be using to extract the sign from.
306 IntTy = llvm::IntegerType::get(C, Width);
307 V = CGF.Builder.CreateTrunc(V, IntTy);
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000308 }
309 Value *Zero = llvm::Constant::getNullValue(IntTy);
310 return CGF.Builder.CreateICmpSLT(V, Zero);
311}
312
John McCallb92ab1a2016-10-26 23:46:34 +0000313static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
314 const CallExpr *E, llvm::Constant *calleeValue) {
315 CGCallee callee = CGCallee::forDirect(calleeValue, FD);
316 return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
John McCall30e4efd2011-09-13 23:05:03 +0000317}
318
Michael Gottesman54398012013-01-13 02:22:39 +0000319/// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.*
320/// depending on IntrinsicID.
321///
322/// \arg CGF The current codegen function.
323/// \arg IntrinsicID The ID for the Intrinsic we wish to generate.
324/// \arg X The first argument to the llvm.*.with.overflow.*.
325/// \arg Y The second argument to the llvm.*.with.overflow.*.
326/// \arg Carry The carry returned by the llvm.*.with.overflow.*.
327/// \returns The result (i.e. sum/product) returned by the intrinsic.
328static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF,
329 const llvm::Intrinsic::ID IntrinsicID,
330 llvm::Value *X, llvm::Value *Y,
331 llvm::Value *&Carry) {
332 // Make sure we have integers of the same width.
333 assert(X->getType() == Y->getType() &&
334 "Arguments must be the same type. (Did you forget to make sure both "
335 "arguments have the same integer width?)");
336
NAKAMURA Takumi7ab4fbf2013-01-13 11:26:44 +0000337 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +0000338 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y});
Michael Gottesman54398012013-01-13 02:22:39 +0000339 Carry = CGF.Builder.CreateExtractValue(Tmp, 1);
340 return CGF.Builder.CreateExtractValue(Tmp, 0);
341}
342
Jan Veselyd7e03a52016-07-10 22:38:04 +0000343static Value *emitRangedBuiltin(CodeGenFunction &CGF,
344 unsigned IntrinsicID,
345 int low, int high) {
346 llvm::MDBuilder MDHelper(CGF.getLLVMContext());
347 llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high));
348 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {});
349 llvm::Instruction *Call = CGF.Builder.CreateCall(F);
350 Call->setMetadata(llvm::LLVMContext::MD_range, RNode);
351 return Call;
352}
353
John McCall03107a42015-10-29 20:48:01 +0000354namespace {
355 struct WidthAndSignedness {
356 unsigned Width;
357 bool Signed;
358 };
359}
360
361static WidthAndSignedness
362getIntegerWidthAndSignedness(const clang::ASTContext &context,
363 const clang::QualType Type) {
364 assert(Type->isIntegerType() && "Given type is not an integer.");
365 unsigned Width = Type->isBooleanType() ? 1 : context.getTypeInfo(Type).Width;
366 bool Signed = Type->isSignedIntegerType();
367 return {Width, Signed};
368}
369
370// Given one or more integer types, this function produces an integer type that
371// encompasses them: any value in one of the given types could be expressed in
372// the encompassing type.
373static struct WidthAndSignedness
374EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) {
375 assert(Types.size() > 0 && "Empty list of types.");
376
377 // If any of the given types is signed, we must return a signed type.
378 bool Signed = false;
379 for (const auto &Type : Types) {
380 Signed |= Type.Signed;
381 }
382
383 // The encompassing type must have a width greater than or equal to the width
384 // of the specified types. Aditionally, if the encompassing type is signed,
385 // its width must be strictly greater than the width of any unsigned types
386 // given.
387 unsigned Width = 0;
388 for (const auto &Type : Types) {
389 unsigned MinWidth = Type.Width + (Signed && !Type.Signed);
390 if (Width < MinWidth) {
391 Width = MinWidth;
392 }
393 }
394
395 return {Width, Signed};
396}
397
Charles Davisc7d5c942015-09-17 20:55:33 +0000398Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) {
399 llvm::Type *DestType = Int8PtrTy;
400 if (ArgValue->getType() != DestType)
401 ArgValue =
402 Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data());
403
404 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend;
405 return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue);
406}
407
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000408/// Checks if using the result of __builtin_object_size(p, @p From) in place of
409/// __builtin_object_size(p, @p To) is correct
410static bool areBOSTypesCompatible(int From, int To) {
411 // Note: Our __builtin_object_size implementation currently treats Type=0 and
412 // Type=2 identically. Encoding this implementation detail here may make
413 // improving __builtin_object_size difficult in the future, so it's omitted.
414 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2);
415}
416
417static llvm::Value *
418getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) {
419 return ConstantInt::get(ResType, (Type & 2) ? 0 : -1, /*isSigned=*/true);
420}
421
422llvm::Value *
423CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
George Burgess IV0d6592a2017-02-23 05:59:56 +0000424 llvm::IntegerType *ResType,
425 llvm::Value *EmittedE) {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000426 uint64_t ObjectSize;
427 if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type))
George Burgess IV0d6592a2017-02-23 05:59:56 +0000428 return emitBuiltinObjectSize(E, Type, ResType, EmittedE);
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000429 return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
430}
431
432/// Returns a Value corresponding to the size of the given expression.
433/// This Value may be either of the following:
434/// - A llvm::Argument (if E is a param with the pass_object_size attribute on
435/// it)
436/// - A call to the @llvm.objectsize intrinsic
George Burgess IV0d6592a2017-02-23 05:59:56 +0000437///
438/// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null
439/// and we wouldn't otherwise try to reference a pass_object_size parameter,
440/// we'll call @llvm.objectsize on EmittedE, rather than emitting E.
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000441llvm::Value *
442CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
George Burgess IV0d6592a2017-02-23 05:59:56 +0000443 llvm::IntegerType *ResType,
444 llvm::Value *EmittedE) {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000445 // We need to reference an argument if the pointer is a parameter with the
446 // pass_object_size attribute.
447 if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
448 auto *Param = dyn_cast<ParmVarDecl>(D->getDecl());
449 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>();
450 if (Param != nullptr && PS != nullptr &&
451 areBOSTypesCompatible(PS->getType(), Type)) {
452 auto Iter = SizeArguments.find(Param);
453 assert(Iter != SizeArguments.end());
454
455 const ImplicitParamDecl *D = Iter->second;
456 auto DIter = LocalDeclMap.find(D);
457 assert(DIter != LocalDeclMap.end());
458
459 return EmitLoadOfScalar(DIter->second, /*volatile=*/false,
460 getContext().getSizeType(), E->getLocStart());
461 }
462 }
463
464 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't
465 // evaluate E for side-effects. In either case, we shouldn't lower to
466 // @llvm.objectsize.
George Burgess IV0d6592a2017-02-23 05:59:56 +0000467 if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext())))
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000468 return getDefaultBuiltinObjectSizeResult(Type, ResType);
469
George Burgess IV0d6592a2017-02-23 05:59:56 +0000470 Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E);
George Burgess IV8856aa92017-02-22 02:35:51 +0000471 assert(Ptr->getType()->isPointerTy() &&
472 "Non-pointer passed to __builtin_object_size?");
473
George Burgess IV8856aa92017-02-22 02:35:51 +0000474 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()});
George Burgess IVa63f9152017-03-21 20:09:35 +0000475
476 // LLVM only supports 0 and 2, make sure that we pass along that as a boolean.
477 Value *Min = Builder.getInt1((Type & 2) != 0);
478 // For GCC compatability, __builtin_object_size treat NULL as unknown size.
479 Value *NullIsUnknown = Builder.getTrue();
480 return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown});
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000481}
482
Albert Gutowski5e08df02016-10-13 22:35:07 +0000483// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we
484// handle them here.
485enum class CodeGenFunction::MSVCIntrin {
486 _BitScanForward,
487 _BitScanReverse,
488 _InterlockedAnd,
489 _InterlockedDecrement,
490 _InterlockedExchange,
491 _InterlockedExchangeAdd,
492 _InterlockedExchangeSub,
493 _InterlockedIncrement,
494 _InterlockedOr,
495 _InterlockedXor,
Hans Wennborg5c3c51f2017-04-07 16:41:47 +0000496 _interlockedbittestandset,
Reid Kleckner04f9f912017-02-09 18:31:06 +0000497 __fastfail,
Albert Gutowski5e08df02016-10-13 22:35:07 +0000498};
499
500Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
Reid Kleckner04f9f912017-02-09 18:31:06 +0000501 const CallExpr *E) {
Albert Gutowski5e08df02016-10-13 22:35:07 +0000502 switch (BuiltinID) {
503 case MSVCIntrin::_BitScanForward:
504 case MSVCIntrin::_BitScanReverse: {
505 Value *ArgValue = EmitScalarExpr(E->getArg(1));
506
507 llvm::Type *ArgType = ArgValue->getType();
508 llvm::Type *IndexType =
509 EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType();
510 llvm::Type *ResultType = ConvertType(E->getType());
511
512 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
513 Value *ResZero = llvm::Constant::getNullValue(ResultType);
514 Value *ResOne = llvm::ConstantInt::get(ResultType, 1);
515
516 BasicBlock *Begin = Builder.GetInsertBlock();
517 BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn);
518 Builder.SetInsertPoint(End);
519 PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result");
520
521 Builder.SetInsertPoint(Begin);
522 Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero);
523 BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn);
524 Builder.CreateCondBr(IsZero, End, NotZero);
525 Result->addIncoming(ResZero, Begin);
526
527 Builder.SetInsertPoint(NotZero);
528 Address IndexAddress = EmitPointerWithAlignment(E->getArg(0));
529
530 if (BuiltinID == MSVCIntrin::_BitScanForward) {
531 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
532 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
533 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
534 Builder.CreateStore(ZeroCount, IndexAddress, false);
535 } else {
536 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
537 Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1);
538
539 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
540 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
541 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
542 Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount);
543 Builder.CreateStore(Index, IndexAddress, false);
544 }
545 Builder.CreateBr(End);
546 Result->addIncoming(ResOne, NotZero);
547
548 Builder.SetInsertPoint(End);
549 return Result;
550 }
551 case MSVCIntrin::_InterlockedAnd:
552 return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E);
553 case MSVCIntrin::_InterlockedExchange:
554 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E);
555 case MSVCIntrin::_InterlockedExchangeAdd:
556 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E);
557 case MSVCIntrin::_InterlockedExchangeSub:
558 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Sub, E);
559 case MSVCIntrin::_InterlockedOr:
560 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E);
561 case MSVCIntrin::_InterlockedXor:
562 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E);
563
Hans Wennborg5c3c51f2017-04-07 16:41:47 +0000564 case MSVCIntrin::_interlockedbittestandset: {
565 llvm::Value *Addr = EmitScalarExpr(E->getArg(0));
566 llvm::Value *Bit = EmitScalarExpr(E->getArg(1));
567 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
568 AtomicRMWInst::Or, Addr,
569 Builder.CreateShl(ConstantInt::get(Bit->getType(), 1), Bit),
570 llvm::AtomicOrdering::SequentiallyConsistent);
571 // Shift the relevant bit to the least significant position, truncate to
572 // the result type, and test the low bit.
573 llvm::Value *Shifted = Builder.CreateLShr(RMWI, Bit);
574 llvm::Value *Truncated =
575 Builder.CreateTrunc(Shifted, ConvertType(E->getType()));
576 return Builder.CreateAnd(Truncated,
577 ConstantInt::get(Truncated->getType(), 1));
578 }
579
Albert Gutowski5e08df02016-10-13 22:35:07 +0000580 case MSVCIntrin::_InterlockedDecrement: {
581 llvm::Type *IntTy = ConvertType(E->getType());
582 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
583 AtomicRMWInst::Sub,
584 EmitScalarExpr(E->getArg(0)),
585 ConstantInt::get(IntTy, 1),
586 llvm::AtomicOrdering::SequentiallyConsistent);
587 return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1));
588 }
589 case MSVCIntrin::_InterlockedIncrement: {
590 llvm::Type *IntTy = ConvertType(E->getType());
591 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
592 AtomicRMWInst::Add,
593 EmitScalarExpr(E->getArg(0)),
594 ConstantInt::get(IntTy, 1),
595 llvm::AtomicOrdering::SequentiallyConsistent);
596 return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1));
597 }
Reid Kleckner04f9f912017-02-09 18:31:06 +0000598
599 case MSVCIntrin::__fastfail: {
600 // Request immediate process termination from the kernel. The instruction
601 // sequences to do this are documented on MSDN:
602 // https://msdn.microsoft.com/en-us/library/dn774154.aspx
603 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch();
604 StringRef Asm, Constraints;
605 switch (ISA) {
606 default:
607 ErrorUnsupported(E, "__fastfail call for this architecture");
608 break;
609 case llvm::Triple::x86:
610 case llvm::Triple::x86_64:
611 Asm = "int $$0x29";
612 Constraints = "{cx}";
613 break;
614 case llvm::Triple::thumb:
615 Asm = "udf #251";
616 Constraints = "{r0}";
617 break;
618 }
619 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false);
620 llvm::InlineAsm *IA =
621 llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true);
Reid Klecknerde864822017-03-21 16:57:30 +0000622 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
623 getLLVMContext(), llvm::AttributeList::FunctionIndex,
624 llvm::Attribute::NoReturn);
Reid Kleckner04f9f912017-02-09 18:31:06 +0000625 CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0)));
626 CS.setAttributes(NoReturnAttr);
627 return CS.getInstruction();
628 }
Albert Gutowski5e08df02016-10-13 22:35:07 +0000629 }
630 llvm_unreachable("Incorrect MSVC intrinsic!");
631}
632
Mehdi Amini06d367c2016-10-24 20:39:34 +0000633namespace {
634// ARC cleanup for __builtin_os_log_format
635struct CallObjCArcUse final : EHScopeStack::Cleanup {
636 CallObjCArcUse(llvm::Value *object) : object(object) {}
637 llvm::Value *object;
638
639 void Emit(CodeGenFunction &CGF, Flags flags) override {
640 CGF.EmitARCIntrinsicUse(object);
641 }
642};
643}
644
Vedant Kumar10c31022017-07-29 00:19:51 +0000645Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
646 BuiltinCheckKind Kind) {
Victor Leschuk198357b2017-07-29 08:18:38 +0000647 assert((Kind == BCK_CLZPassedZero || Kind == BCK_CTZPassedZero)
648 && "Unsupported builtin check kind");
Vedant Kumar10c31022017-07-29 00:19:51 +0000649
650 Value *ArgValue = EmitScalarExpr(E);
651 if (!SanOpts.has(SanitizerKind::Builtin) || !getTarget().isCLZForZeroUndef())
652 return ArgValue;
653
654 SanitizerScope SanScope(this);
655 Value *Cond = Builder.CreateICmpNE(
656 ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
657 EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin),
658 SanitizerHandler::InvalidBuiltin,
659 {EmitCheckSourceLocation(E->getExprLoc()),
660 llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)},
661 None);
662 return ArgValue;
663}
664
Mike Stump11289f42009-09-09 15:08:12 +0000665RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Peter Collingbournef7706832014-12-12 23:41:25 +0000666 unsigned BuiltinID, const CallExpr *E,
667 ReturnValueSlot ReturnValue) {
Chris Lattner24355b52008-10-06 06:56:41 +0000668 // See if we can constant fold this builtin. If so, don't emit it at all.
Anders Carlssonc9687902008-12-01 02:31:41 +0000669 Expr::EvalResult Result;
Eli Friedmandf88c542012-01-06 20:03:09 +0000670 if (E->EvaluateAsRValue(Result, CGM.getContext()) &&
Fariborz Jahanian24ac1592011-04-25 23:10:07 +0000671 !Result.hasSideEffects()) {
Anders Carlssonc9687902008-12-01 02:31:41 +0000672 if (Result.Val.isInt())
John McCallad7c5c12011-02-08 08:22:06 +0000673 return RValue::get(llvm::ConstantInt::get(getLLVMContext(),
Owen Andersonb7a2fe62009-07-24 23:12:58 +0000674 Result.Val.getInt()));
Chris Lattner07e96862010-10-01 23:43:16 +0000675 if (Result.Val.isFloat())
John McCallad7c5c12011-02-08 08:22:06 +0000676 return RValue::get(llvm::ConstantFP::get(getLLVMContext(),
677 Result.Val.getFloat()));
Chris Lattnera1518b12008-10-06 06:09:18 +0000678 }
Mike Stump11289f42009-09-09 15:08:12 +0000679
Chris Lattner24355b52008-10-06 06:56:41 +0000680 switch (BuiltinID) {
681 default: break; // Handle intrinsics and libm functions below.
Chris Lattnera97132a2008-10-06 07:26:43 +0000682 case Builtin::BI__builtin___CFStringMakeConstantString:
David Chisnall481e3a82010-01-23 02:40:42 +0000683 case Builtin::BI__builtin___NSStringMakeConstantString:
John McCallde0fe072017-08-15 21:42:52 +0000684 return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType()));
Chris Lattner0bf67912008-07-09 17:28:44 +0000685 case Builtin::BI__builtin_stdarg_start:
Anders Carlsson24ebce62007-10-12 23:56:29 +0000686 case Builtin::BI__builtin_va_start:
Reid Kleckner597e81d2014-03-26 15:38:33 +0000687 case Builtin::BI__va_start:
Charles Davisc7d5c942015-09-17 20:55:33 +0000688 case Builtin::BI__builtin_va_end:
689 return RValue::get(
690 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start
691 ? EmitScalarExpr(E->getArg(0))
692 : EmitVAListRef(E->getArg(0)).getPointer(),
693 BuiltinID != Builtin::BI__builtin_va_end));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000694 case Builtin::BI__builtin_va_copy: {
John McCall7f416cc2015-09-08 08:05:57 +0000695 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer();
696 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer();
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000697
Chris Lattner2192fe52011-07-18 04:24:23 +0000698 llvm::Type *Type = Int8PtrTy;
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000699
700 DstPtr = Builder.CreateBitCast(DstPtr, Type);
701 SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
David Blaikie43f9bb72015-05-18 22:14:03 +0000702 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy),
703 {DstPtr, SrcPtr}));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000704 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000705 case Builtin::BI__builtin_abs:
Eli Friedman65499b42012-01-17 22:11:30 +0000706 case Builtin::BI__builtin_labs:
707 case Builtin::BI__builtin_llabs: {
Mike Stump11289f42009-09-09 15:08:12 +0000708 Value *ArgValue = EmitScalarExpr(E->getArg(0));
709
Chris Lattner28ee5b32008-07-23 06:53:34 +0000710 Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
Mike Stump11289f42009-09-09 15:08:12 +0000711 Value *CmpResult =
712 Builder.CreateICmpSGE(ArgValue,
Owen Anderson0b75f232009-07-31 20:28:54 +0000713 llvm::Constant::getNullValue(ArgValue->getType()),
Chris Lattner28ee5b32008-07-23 06:53:34 +0000714 "abscond");
Mike Stump11289f42009-09-09 15:08:12 +0000715 Value *Result =
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000716 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
Mike Stump11289f42009-09-09 15:08:12 +0000717
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000718 return RValue::get(Result);
719 }
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000720 case Builtin::BI__builtin_fabs:
721 case Builtin::BI__builtin_fabsf:
722 case Builtin::BI__builtin_fabsl: {
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000723 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs));
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000724 }
Jan Veselyb4379f92014-09-26 01:19:41 +0000725 case Builtin::BI__builtin_fmod:
726 case Builtin::BI__builtin_fmodf:
727 case Builtin::BI__builtin_fmodl: {
728 Value *Arg1 = EmitScalarExpr(E->getArg(0));
729 Value *Arg2 = EmitScalarExpr(E->getArg(1));
730 Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod");
731 return RValue::get(Result);
732 }
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000733 case Builtin::BI__builtin_copysign:
734 case Builtin::BI__builtin_copysignf:
735 case Builtin::BI__builtin_copysignl: {
736 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign));
737 }
738 case Builtin::BI__builtin_ceil:
739 case Builtin::BI__builtin_ceilf:
740 case Builtin::BI__builtin_ceill: {
741 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil));
742 }
743 case Builtin::BI__builtin_floor:
744 case Builtin::BI__builtin_floorf:
745 case Builtin::BI__builtin_floorl: {
746 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor));
747 }
748 case Builtin::BI__builtin_trunc:
749 case Builtin::BI__builtin_truncf:
750 case Builtin::BI__builtin_truncl: {
751 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc));
752 }
753 case Builtin::BI__builtin_rint:
754 case Builtin::BI__builtin_rintf:
755 case Builtin::BI__builtin_rintl: {
756 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint));
757 }
758 case Builtin::BI__builtin_nearbyint:
759 case Builtin::BI__builtin_nearbyintf:
760 case Builtin::BI__builtin_nearbyintl: {
761 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint));
762 }
763 case Builtin::BI__builtin_round:
764 case Builtin::BI__builtin_roundf:
765 case Builtin::BI__builtin_roundl: {
766 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round));
767 }
768 case Builtin::BI__builtin_fmin:
769 case Builtin::BI__builtin_fminf:
770 case Builtin::BI__builtin_fminl: {
771 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum));
772 }
773 case Builtin::BI__builtin_fmax:
774 case Builtin::BI__builtin_fmaxf:
775 case Builtin::BI__builtin_fmaxl: {
776 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum));
777 }
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000778 case Builtin::BI__builtin_conj:
779 case Builtin::BI__builtin_conjf:
780 case Builtin::BI__builtin_conjl: {
781 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
782 Value *Real = ComplexVal.first;
783 Value *Imag = ComplexVal.second;
Jim Grosbachd3608f42012-09-21 00:18:27 +0000784 Value *Zero =
785 Imag->getType()->isFPOrFPVectorTy()
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000786 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType())
787 : llvm::Constant::getNullValue(Imag->getType());
Jim Grosbachd3608f42012-09-21 00:18:27 +0000788
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000789 Imag = Builder.CreateFSub(Zero, Imag, "sub");
790 return RValue::getComplex(std::make_pair(Real, Imag));
791 }
792 case Builtin::BI__builtin_creal:
793 case Builtin::BI__builtin_crealf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000794 case Builtin::BI__builtin_creall:
795 case Builtin::BIcreal:
796 case Builtin::BIcrealf:
797 case Builtin::BIcreall: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000798 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
799 return RValue::get(ComplexVal.first);
800 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000801
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000802 case Builtin::BI__builtin_cimag:
803 case Builtin::BI__builtin_cimagf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000804 case Builtin::BI__builtin_cimagl:
805 case Builtin::BIcimag:
806 case Builtin::BIcimagf:
807 case Builtin::BIcimagl: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000808 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
809 return RValue::get(ComplexVal.second);
810 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000811
Benjamin Kramer14128162012-01-28 18:42:57 +0000812 case Builtin::BI__builtin_ctzs:
Anders Carlsson093f1a02008-02-06 07:19:27 +0000813 case Builtin::BI__builtin_ctz:
814 case Builtin::BI__builtin_ctzl:
815 case Builtin::BI__builtin_ctzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +0000816 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +0000817
Chris Lattnera5f58b02011-07-09 17:41:47 +0000818 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000819 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Anders Carlsson093f1a02008-02-06 07:19:27 +0000820
Chris Lattner2192fe52011-07-18 04:24:23 +0000821 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +0000822 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +0000823 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Anders Carlsson093f1a02008-02-06 07:19:27 +0000824 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000825 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
826 "cast");
Anders Carlsson093f1a02008-02-06 07:19:27 +0000827 return RValue::get(Result);
828 }
Benjamin Kramer14128162012-01-28 18:42:57 +0000829 case Builtin::BI__builtin_clzs:
Eli Friedman5e2281e2008-05-27 15:32:46 +0000830 case Builtin::BI__builtin_clz:
831 case Builtin::BI__builtin_clzl:
832 case Builtin::BI__builtin_clzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +0000833 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +0000834
Chris Lattnera5f58b02011-07-09 17:41:47 +0000835 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000836 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
Eli Friedman5e2281e2008-05-27 15:32:46 +0000837
Chris Lattner2192fe52011-07-18 04:24:23 +0000838 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +0000839 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +0000840 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Eli Friedman5e2281e2008-05-27 15:32:46 +0000841 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000842 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
843 "cast");
Eli Friedman5e2281e2008-05-27 15:32:46 +0000844 return RValue::get(Result);
845 }
Daniel Dunbard93abc32008-07-21 17:19:41 +0000846 case Builtin::BI__builtin_ffs:
847 case Builtin::BI__builtin_ffsl:
848 case Builtin::BI__builtin_ffsll: {
849 // ffs(x) -> x ? cttz(x) + 1 : 0
850 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +0000851
Chris Lattnera5f58b02011-07-09 17:41:47 +0000852 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000853 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +0000854
Chris Lattner2192fe52011-07-18 04:24:23 +0000855 llvm::Type *ResultType = ConvertType(E->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +0000856 Value *Tmp =
857 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}),
858 llvm::ConstantInt::get(ArgType, 1));
Owen Anderson0b75f232009-07-31 20:28:54 +0000859 Value *Zero = llvm::Constant::getNullValue(ArgType);
Daniel Dunbard93abc32008-07-21 17:19:41 +0000860 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
861 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs");
862 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000863 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
864 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +0000865 return RValue::get(Result);
866 }
867 case Builtin::BI__builtin_parity:
868 case Builtin::BI__builtin_parityl:
869 case Builtin::BI__builtin_parityll: {
870 // parity(x) -> ctpop(x) & 1
871 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +0000872
Chris Lattnera5f58b02011-07-09 17:41:47 +0000873 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000874 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +0000875
Chris Lattner2192fe52011-07-18 04:24:23 +0000876 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +0000877 Value *Tmp = Builder.CreateCall(F, ArgValue);
878 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1));
Daniel Dunbard93abc32008-07-21 17:19:41 +0000879 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000880 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
881 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +0000882 return RValue::get(Result);
883 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +0000884 case Builtin::BI__popcnt16:
885 case Builtin::BI__popcnt:
886 case Builtin::BI__popcnt64:
Daniel Dunbard93abc32008-07-21 17:19:41 +0000887 case Builtin::BI__builtin_popcount:
888 case Builtin::BI__builtin_popcountl:
889 case Builtin::BI__builtin_popcountll: {
890 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +0000891
Chris Lattnera5f58b02011-07-09 17:41:47 +0000892 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000893 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +0000894
Chris Lattner2192fe52011-07-18 04:24:23 +0000895 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +0000896 Value *Result = Builder.CreateCall(F, ArgValue);
Daniel Dunbard93abc32008-07-21 17:19:41 +0000897 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +0000898 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
899 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +0000900 return RValue::get(Result);
901 }
Albert Gutowskib6a11ac2016-09-08 22:32:19 +0000902 case Builtin::BI_rotr8:
903 case Builtin::BI_rotr16:
904 case Builtin::BI_rotr:
905 case Builtin::BI_lrotr:
906 case Builtin::BI_rotr64: {
907 Value *Val = EmitScalarExpr(E->getArg(0));
908 Value *Shift = EmitScalarExpr(E->getArg(1));
909
910 llvm::Type *ArgType = Val->getType();
911 Shift = Builder.CreateIntCast(Shift, ArgType, false);
912 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
913 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
914 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
915
916 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
917 Shift = Builder.CreateAnd(Shift, Mask);
918 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift);
919
920 Value *RightShifted = Builder.CreateLShr(Val, Shift);
921 Value *LeftShifted = Builder.CreateShl(Val, LeftShift);
922 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
923
924 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
925 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
926 return RValue::get(Result);
927 }
928 case Builtin::BI_rotl8:
929 case Builtin::BI_rotl16:
930 case Builtin::BI_rotl:
931 case Builtin::BI_lrotl:
932 case Builtin::BI_rotl64: {
933 Value *Val = EmitScalarExpr(E->getArg(0));
934 Value *Shift = EmitScalarExpr(E->getArg(1));
935
936 llvm::Type *ArgType = Val->getType();
937 Shift = Builder.CreateIntCast(Shift, ArgType, false);
938 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
939 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
940 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
941
942 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
943 Shift = Builder.CreateAnd(Shift, Mask);
944 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift);
945
946 Value *LeftShifted = Builder.CreateShl(Val, Shift);
947 Value *RightShifted = Builder.CreateLShr(Val, RightShift);
948 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
949
950 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
951 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
952 return RValue::get(Result);
953 }
Sanjay Patela24296b2015-09-02 20:01:30 +0000954 case Builtin::BI__builtin_unpredictable: {
955 // Always return the argument of __builtin_unpredictable. LLVM does not
956 // handle this builtin. Metadata for this builtin should be added directly
957 // to instructions such as branches or switches that use it.
958 return RValue::get(EmitScalarExpr(E->getArg(0)));
959 }
Fariborz Jahanian0ebca282010-07-26 23:11:03 +0000960 case Builtin::BI__builtin_expect: {
Fariborz Jahanian24ac1592011-04-25 23:10:07 +0000961 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000962 llvm::Type *ArgType = ArgValue->getType();
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000963
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000964 Value *ExpectedValue = EmitScalarExpr(E->getArg(1));
Pete Cooperf051cbf2015-01-26 20:51:58 +0000965 // Don't generate llvm.expect on -O0 as the backend won't use it for
966 // anything.
967 // Note, we still IRGen ExpectedValue because it could have side-effects.
968 if (CGM.getCodeGenOpts().OptimizationLevel == 0)
969 return RValue::get(ArgValue);
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000970
Pete Cooperf051cbf2015-01-26 20:51:58 +0000971 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +0000972 Value *Result =
973 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval");
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +0000974 return RValue::get(Result);
Fariborz Jahanian0ebca282010-07-26 23:11:03 +0000975 }
Hal Finkelbcc06082014-09-07 22:58:14 +0000976 case Builtin::BI__builtin_assume_aligned: {
977 Value *PtrValue = EmitScalarExpr(E->getArg(0));
978 Value *OffsetValue =
979 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
980
981 Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
982 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
983 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();
984
985 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);
986 return RValue::get(PtrValue);
987 }
988 case Builtin::BI__assume:
989 case Builtin::BI__builtin_assume: {
990 if (E->getArg(0)->HasSideEffects(getContext()))
991 return RValue::get(nullptr);
992
993 Value *ArgValue = EmitScalarExpr(E->getArg(0));
994 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
995 return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
996 }
Benjamin Kramera801f4a2012-10-06 14:42:22 +0000997 case Builtin::BI__builtin_bswap16:
Anders Carlssonef93b9d2007-12-02 21:58:10 +0000998 case Builtin::BI__builtin_bswap32:
999 case Builtin::BI__builtin_bswap64: {
Matt Arsenault105e8922016-02-03 17:49:38 +00001000 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap));
1001 }
Matt Arsenault08087c52016-03-23 22:14:43 +00001002 case Builtin::BI__builtin_bitreverse8:
Matt Arsenault105e8922016-02-03 17:49:38 +00001003 case Builtin::BI__builtin_bitreverse16:
1004 case Builtin::BI__builtin_bitreverse32:
1005 case Builtin::BI__builtin_bitreverse64: {
1006 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse));
Mike Stump11289f42009-09-09 15:08:12 +00001007 }
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001008 case Builtin::BI__builtin_object_size: {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001009 unsigned Type =
1010 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
1011 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType()));
Richard Smith01ade172012-05-23 04:13:20 +00001012
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001013 // We pass this builtin onto the optimizer so that it can figure out the
1014 // object size in more complex cases.
George Burgess IV0d6592a2017-02-23 05:59:56 +00001015 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType,
1016 /*EmittedE=*/nullptr));
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001017 }
Daniel Dunbarb7257262008-07-21 22:59:13 +00001018 case Builtin::BI__builtin_prefetch: {
1019 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
1020 // FIXME: Technically these constants should of type 'int', yes?
Mike Stump11289f42009-09-09 15:08:12 +00001021 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001022 llvm::ConstantInt::get(Int32Ty, 0);
Mike Stump11289f42009-09-09 15:08:12 +00001023 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001024 llvm::ConstantInt::get(Int32Ty, 3);
Bruno Cardoso Lopes3b0297a2011-06-14 05:00:30 +00001025 Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001026 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00001027 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data}));
Anders Carlssonef93b9d2007-12-02 21:58:10 +00001028 }
Hal Finkel3fadbb52012-08-05 22:03:08 +00001029 case Builtin::BI__builtin_readcyclecounter: {
1030 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
David Blaikie4ba525b2015-07-14 17:27:39 +00001031 return RValue::get(Builder.CreateCall(F));
Hal Finkel3fadbb52012-08-05 22:03:08 +00001032 }
Renato Golinc491a8d2014-03-26 15:36:05 +00001033 case Builtin::BI__builtin___clear_cache: {
1034 Value *Begin = EmitScalarExpr(E->getArg(0));
1035 Value *End = EmitScalarExpr(E->getArg(1));
1036 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache);
David Blaikie43f9bb72015-05-18 22:14:03 +00001037 return RValue::get(Builder.CreateCall(F, {Begin, End}));
Renato Golinc491a8d2014-03-26 15:36:05 +00001038 }
Akira Hatanaka85365cd2015-07-02 22:15:41 +00001039 case Builtin::BI__builtin_trap:
1040 return RValue::get(EmitTrapCall(Intrinsic::trap));
1041 case Builtin::BI__debugbreak:
1042 return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
Chris Lattnerbf206382009-09-21 03:09:59 +00001043 case Builtin::BI__builtin_unreachable: {
Alexey Samsonovedf99a92014-11-07 22:29:38 +00001044 if (SanOpts.has(SanitizerKind::Unreachable)) {
Alexey Samsonov24cad992014-07-17 18:46:27 +00001045 SanitizerScope SanScope(this);
Alexey Samsonove396bfc2014-11-11 22:03:54 +00001046 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
1047 SanitizerKind::Unreachable),
Filipe Cabecinhas322ecd92016-12-12 16:18:40 +00001048 SanitizerHandler::BuiltinUnreachable,
1049 EmitCheckSourceLocation(E->getExprLoc()), None);
Alexey Samsonov24cad992014-07-17 18:46:27 +00001050 } else
John McCall20f6ab82011-01-12 03:41:02 +00001051 Builder.CreateUnreachable();
1052
1053 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001054 EmitBlock(createBasicBlock("unreachable.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001055
Craig Topper8a13c412014-05-21 05:09:00 +00001056 return RValue::get(nullptr);
Chris Lattnerbf206382009-09-21 03:09:59 +00001057 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001058
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001059 case Builtin::BI__builtin_powi:
1060 case Builtin::BI__builtin_powif:
Reid Kleckner1fcccdd2015-02-05 00:24:57 +00001061 case Builtin::BI__builtin_powil: {
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001062 Value *Base = EmitScalarExpr(E->getArg(0));
1063 Value *Exponent = EmitScalarExpr(E->getArg(1));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001064 llvm::Type *ArgType = Base->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001065 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001066 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001067 }
1068
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001069 case Builtin::BI__builtin_isgreater:
1070 case Builtin::BI__builtin_isgreaterequal:
1071 case Builtin::BI__builtin_isless:
1072 case Builtin::BI__builtin_islessequal:
1073 case Builtin::BI__builtin_islessgreater:
1074 case Builtin::BI__builtin_isunordered: {
1075 // Ordered comparisons: we know the arguments to these are matching scalar
1076 // floating point values.
Mike Stump11289f42009-09-09 15:08:12 +00001077 Value *LHS = EmitScalarExpr(E->getArg(0));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001078 Value *RHS = EmitScalarExpr(E->getArg(1));
Mike Stump11289f42009-09-09 15:08:12 +00001079
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001080 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00001081 default: llvm_unreachable("Unknown ordered comparison");
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001082 case Builtin::BI__builtin_isgreater:
1083 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
1084 break;
1085 case Builtin::BI__builtin_isgreaterequal:
1086 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
1087 break;
1088 case Builtin::BI__builtin_isless:
1089 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
1090 break;
1091 case Builtin::BI__builtin_islessequal:
1092 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
1093 break;
1094 case Builtin::BI__builtin_islessgreater:
1095 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
1096 break;
Mike Stump11289f42009-09-09 15:08:12 +00001097 case Builtin::BI__builtin_isunordered:
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001098 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
1099 break;
1100 }
1101 // ZExt bool to int type.
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001102 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType())));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001103 }
Eli Friedman1c277d02009-09-01 04:19:44 +00001104 case Builtin::BI__builtin_isnan: {
1105 Value *V = EmitScalarExpr(E->getArg(0));
1106 V = Builder.CreateFCmpUNO(V, V, "cmp");
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001107 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
Eli Friedman1c277d02009-09-01 04:19:44 +00001108 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001109
Dehao Chen5d4f0be2016-09-14 17:34:14 +00001110 case Builtin::BIfinite:
1111 case Builtin::BI__finite:
1112 case Builtin::BIfinitef:
1113 case Builtin::BI__finitef:
1114 case Builtin::BIfinitel:
1115 case Builtin::BI__finitel:
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001116 case Builtin::BI__builtin_isinf:
1117 case Builtin::BI__builtin_isfinite: {
1118 // isinf(x) --> fabs(x) == infinity
1119 // isfinite(x) --> fabs(x) != infinity
1120 // x != NaN via the ordered compare in either case.
Chris Lattner43660c52010-05-06 05:35:16 +00001121 Value *V = EmitScalarExpr(E->getArg(0));
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001122 Value *Fabs = EmitFAbs(*this, V);
1123 Constant *Infinity = ConstantFP::getInfinity(V->getType());
1124 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf)
1125 ? CmpInst::FCMP_OEQ
1126 : CmpInst::FCMP_ONE;
1127 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf");
1128 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType())));
Chris Lattner43660c52010-05-06 05:35:16 +00001129 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001130
Chandler Carruthc66deaf2015-03-19 22:39:51 +00001131 case Builtin::BI__builtin_isinf_sign: {
1132 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0
1133 Value *Arg = EmitScalarExpr(E->getArg(0));
1134 Value *AbsArg = EmitFAbs(*this, Arg);
1135 Value *IsInf = Builder.CreateFCmpOEQ(
1136 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf");
1137 Value *IsNeg = EmitSignBit(*this, Arg);
1138
1139 llvm::Type *IntTy = ConvertType(E->getType());
1140 Value *Zero = Constant::getNullValue(IntTy);
1141 Value *One = ConstantInt::get(IntTy, 1);
1142 Value *NegativeOne = ConstantInt::get(IntTy, -1);
1143 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One);
1144 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero);
1145 return RValue::get(Result);
1146 }
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001147
1148 case Builtin::BI__builtin_isnormal: {
1149 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min
1150 Value *V = EmitScalarExpr(E->getArg(0));
1151 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
1152
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001153 Value *Abs = EmitFAbs(*this, V);
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001154 Value *IsLessThanInf =
1155 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf");
1156 APFloat Smallest = APFloat::getSmallestNormalized(
1157 getContext().getFloatTypeSemantics(E->getArg(0)->getType()));
1158 Value *IsNormal =
1159 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest),
1160 "isnormal");
1161 V = Builder.CreateAnd(Eq, IsLessThanInf, "and");
1162 V = Builder.CreateAnd(V, IsNormal, "and");
1163 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
1164 }
1165
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001166 case Builtin::BI__builtin_fpclassify: {
1167 Value *V = EmitScalarExpr(E->getArg(5));
Chris Lattner2192fe52011-07-18 04:24:23 +00001168 llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001169
1170 // Create Result
1171 BasicBlock *Begin = Builder.GetInsertBlock();
1172 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn);
1173 Builder.SetInsertPoint(End);
1174 PHINode *Result =
Jay Foad20c0f022011-03-30 11:28:58 +00001175 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4,
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001176 "fpclassify_result");
1177
1178 // if (V==0) return FP_ZERO
1179 Builder.SetInsertPoint(Begin);
1180 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty),
1181 "iszero");
1182 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4));
1183 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn);
1184 Builder.CreateCondBr(IsZero, End, NotZero);
1185 Result->addIncoming(ZeroLiteral, Begin);
1186
1187 // if (V != V) return FP_NAN
1188 Builder.SetInsertPoint(NotZero);
1189 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp");
1190 Value *NanLiteral = EmitScalarExpr(E->getArg(0));
1191 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn);
1192 Builder.CreateCondBr(IsNan, End, NotNan);
1193 Result->addIncoming(NanLiteral, NotZero);
1194
1195 // if (fabs(V) == infinity) return FP_INFINITY
1196 Builder.SetInsertPoint(NotNan);
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001197 Value *VAbs = EmitFAbs(*this, V);
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001198 Value *IsInf =
1199 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()),
1200 "isinf");
1201 Value *InfLiteral = EmitScalarExpr(E->getArg(1));
1202 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn);
1203 Builder.CreateCondBr(IsInf, End, NotInf);
1204 Result->addIncoming(InfLiteral, NotNan);
1205
1206 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL
1207 Builder.SetInsertPoint(NotInf);
1208 APFloat Smallest = APFloat::getSmallestNormalized(
1209 getContext().getFloatTypeSemantics(E->getArg(5)->getType()));
1210 Value *IsNormal =
1211 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest),
1212 "isnormal");
1213 Value *NormalResult =
1214 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)),
1215 EmitScalarExpr(E->getArg(3)));
1216 Builder.CreateBr(End);
1217 Result->addIncoming(NormalResult, NotInf);
1218
1219 // return Result
1220 Builder.SetInsertPoint(End);
1221 return RValue::get(Result);
1222 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001223
Eli Friedmanf6bd1502009-06-02 07:10:30 +00001224 case Builtin::BIalloca:
Reid Kleckner59e4a6f2013-11-13 22:58:53 +00001225 case Builtin::BI_alloca:
Chris Lattner22b9ff42008-06-16 17:15:14 +00001226 case Builtin::BI__builtin_alloca: {
Chris Lattner22b9ff42008-06-16 17:15:14 +00001227 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemer1878da42016-10-27 17:18:24 +00001228 const TargetInfo &TI = getContext().getTargetInfo();
1229 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
1230 unsigned SuitableAlignmentInBytes =
David Majnemerbb103d92016-10-31 16:48:30 +00001231 CGM.getContext()
1232 .toCharUnitsFromBits(TI.getSuitableAlign())
1233 .getQuantity();
David Majnemer1878da42016-10-27 17:18:24 +00001234 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1235 AI->setAlignment(SuitableAlignmentInBytes);
1236 return RValue::get(AI);
Daniel Dunbar327acd72008-07-22 00:26:45 +00001237 }
David Majnemer51169932016-10-31 05:37:48 +00001238
1239 case Builtin::BI__builtin_alloca_with_align: {
1240 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemerbb103d92016-10-31 16:48:30 +00001241 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1));
1242 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue);
1243 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue();
1244 unsigned AlignmentInBytes =
1245 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity();
David Majnemer51169932016-10-31 05:37:48 +00001246 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1247 AI->setAlignment(AlignmentInBytes);
1248 return RValue::get(AI);
1249 }
1250
Eli Friedmand6ef69a2010-01-23 19:00:10 +00001251 case Builtin::BIbzero:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001252 case Builtin::BI__builtin_bzero: {
John McCall7f416cc2015-09-08 08:05:57 +00001253 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001254 Value *SizeVal = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00001255 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001256 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001257 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false);
1258 return RValue::get(Dest.getPointer());
Chris Lattner22b9ff42008-06-16 17:15:14 +00001259 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001260 case Builtin::BImemcpy:
Eli Friedmana3a40682008-05-19 23:27:48 +00001261 case Builtin::BI__builtin_memcpy: {
John McCall7f416cc2015-09-08 08:05:57 +00001262 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1263 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001264 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001265 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001266 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001267 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001268 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001269 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1270 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001271 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001272
Richard Smith5e29dd32017-01-20 00:45:35 +00001273 case Builtin::BI__builtin_char_memchr:
1274 BuiltinID = Builtin::BI__builtin_memchr;
1275 break;
1276
Chris Lattner30107ed2011-04-17 00:40:24 +00001277 case Builtin::BI__builtin___memcpy_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001278 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001279 llvm::APSInt Size, DstSize;
1280 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1281 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001282 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001283 if (Size.ugt(DstSize))
1284 break;
John McCall7f416cc2015-09-08 08:05:57 +00001285 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1286 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001287 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001288 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1289 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001290 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001291
Fariborz Jahanian4a303072010-06-16 16:22:04 +00001292 case Builtin::BI__builtin_objc_memmove_collectable: {
John McCall7f416cc2015-09-08 08:05:57 +00001293 Address DestAddr = EmitPointerWithAlignment(E->getArg(0));
1294 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1));
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001295 Value *SizeVal = EmitScalarExpr(E->getArg(2));
Jim Grosbachd3608f42012-09-21 00:18:27 +00001296 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this,
John McCall7f416cc2015-09-08 08:05:57 +00001297 DestAddr, SrcAddr, SizeVal);
1298 return RValue::get(DestAddr.getPointer());
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001299 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001300
1301 case Builtin::BI__builtin___memmove_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001302 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001303 llvm::APSInt Size, DstSize;
1304 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1305 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001306 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001307 if (Size.ugt(DstSize))
1308 break;
John McCall7f416cc2015-09-08 08:05:57 +00001309 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1310 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001311 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001312 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1313 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001314 }
1315
Eli Friedman7f4933f2009-12-17 00:14:28 +00001316 case Builtin::BImemmove:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001317 case Builtin::BI__builtin_memmove: {
John McCall7f416cc2015-09-08 08:05:57 +00001318 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1319 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001320 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001321 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001322 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001323 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001324 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001325 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1326 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001327 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001328 case Builtin::BImemset:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001329 case Builtin::BI__builtin_memset: {
John McCall7f416cc2015-09-08 08:05:57 +00001330 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Benjamin Krameracc6b4e2010-12-30 00:13:21 +00001331 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1332 Builder.getInt8Ty());
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001333 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001334 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001335 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001336 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1337 return RValue::get(Dest.getPointer());
Eli Friedmana3a40682008-05-19 23:27:48 +00001338 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001339 case Builtin::BI__builtin___memset_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001340 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001341 llvm::APSInt Size, DstSize;
1342 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1343 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001344 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001345 if (Size.ugt(DstSize))
1346 break;
John McCall7f416cc2015-09-08 08:05:57 +00001347 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Chris Lattner30107ed2011-04-17 00:40:24 +00001348 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1349 Builder.getInt8Ty());
1350 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001351 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1352 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001353 }
John McCall515c3c52010-03-03 10:30:05 +00001354 case Builtin::BI__builtin_dwarf_cfa: {
1355 // The offset in bytes from the first argument to the CFA.
1356 //
1357 // Why on earth is this in the frontend? Is there any reason at
1358 // all that the backend can't reasonably determine this while
1359 // lowering llvm.eh.dwarf.cfa()?
1360 //
1361 // TODO: If there's a satisfactory reason, add a target hook for
1362 // this instead of hard-coding 0, which is correct for most targets.
1363 int32_t Offset = 0;
1364
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001365 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa);
Jim Grosbachd3608f42012-09-21 00:18:27 +00001366 return RValue::get(Builder.CreateCall(F,
Chris Lattner5e016ae2010-06-27 07:15:29 +00001367 llvm::ConstantInt::get(Int32Ty, Offset)));
John McCall515c3c52010-03-03 10:30:05 +00001368 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001369 case Builtin::BI__builtin_return_address: {
John McCallde0fe072017-08-15 21:42:52 +00001370 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1371 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001372 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001373 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001374 }
Albert Gutowski397d81b2016-10-13 16:03:42 +00001375 case Builtin::BI_ReturnAddress: {
1376 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
1377 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
1378 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001379 case Builtin::BI__builtin_frame_address: {
John McCallde0fe072017-08-15 21:42:52 +00001380 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1381 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001382 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001383 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001384 }
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001385 case Builtin::BI__builtin_extract_return_addr: {
John McCalld4f4b7f2010-03-03 04:15:11 +00001386 Value *Address = EmitScalarExpr(E->getArg(0));
1387 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address);
1388 return RValue::get(Result);
1389 }
1390 case Builtin::BI__builtin_frob_return_addr: {
1391 Value *Address = EmitScalarExpr(E->getArg(0));
1392 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address);
1393 return RValue::get(Result);
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001394 }
John McCallbeec5a02010-03-06 00:35:14 +00001395 case Builtin::BI__builtin_dwarf_sp_column: {
Chris Lattner2192fe52011-07-18 04:24:23 +00001396 llvm::IntegerType *Ty
John McCallbeec5a02010-03-06 00:35:14 +00001397 = cast<llvm::IntegerType>(ConvertType(E->getType()));
1398 int Column = getTargetHooks().getDwarfEHStackPointer(CGM);
1399 if (Column == -1) {
1400 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column");
1401 return RValue::get(llvm::UndefValue::get(Ty));
1402 }
1403 return RValue::get(llvm::ConstantInt::get(Ty, Column, true));
1404 }
1405 case Builtin::BI__builtin_init_dwarf_reg_size_table: {
1406 Value *Address = EmitScalarExpr(E->getArg(0));
1407 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address))
1408 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table");
1409 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
1410 }
John McCall66769f82010-03-03 05:38:58 +00001411 case Builtin::BI__builtin_eh_return: {
1412 Value *Int = EmitScalarExpr(E->getArg(0));
1413 Value *Ptr = EmitScalarExpr(E->getArg(1));
1414
Chris Lattner2192fe52011-07-18 04:24:23 +00001415 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType());
John McCall66769f82010-03-03 05:38:58 +00001416 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) &&
1417 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants");
1418 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32
1419 ? Intrinsic::eh_return_i32
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001420 : Intrinsic::eh_return_i64);
David Blaikie43f9bb72015-05-18 22:14:03 +00001421 Builder.CreateCall(F, {Int, Ptr});
John McCall20f6ab82011-01-12 03:41:02 +00001422 Builder.CreateUnreachable();
1423
1424 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001425 EmitBlock(createBasicBlock("builtin_eh_return.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001426
Craig Topper8a13c412014-05-21 05:09:00 +00001427 return RValue::get(nullptr);
John McCall66769f82010-03-03 05:38:58 +00001428 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001429 case Builtin::BI__builtin_unwind_init: {
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001430 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
David Blaikie4ba525b2015-07-14 17:27:39 +00001431 return RValue::get(Builder.CreateCall(F));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001432 }
John McCall4b613fa2010-03-02 02:31:24 +00001433 case Builtin::BI__builtin_extend_pointer: {
1434 // Extends a pointer to the size of an _Unwind_Word, which is
John McCallb6cc2c042010-03-02 03:50:12 +00001435 // uint64_t on all platforms. Generally this gets poked into a
1436 // register and eventually used as an address, so if the
1437 // addressing registers are wider than pointers and the platform
1438 // doesn't implicitly ignore high-order bits when doing
1439 // addressing, we need to make sure we zext / sext based on
1440 // the platform's expectations.
John McCall4b613fa2010-03-02 02:31:24 +00001441 //
1442 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html
John McCallb6cc2c042010-03-02 03:50:12 +00001443
John McCallb6cc2c042010-03-02 03:50:12 +00001444 // Cast the pointer to intptr_t.
John McCall4b613fa2010-03-02 02:31:24 +00001445 Value *Ptr = EmitScalarExpr(E->getArg(0));
John McCallb6cc2c042010-03-02 03:50:12 +00001446 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast");
1447
1448 // If that's 64 bits, we're done.
1449 if (IntPtrTy->getBitWidth() == 64)
1450 return RValue::get(Result);
1451
1452 // Otherwise, ask the codegen data what to do.
John McCalld4f4b7f2010-03-03 04:15:11 +00001453 if (getTargetHooks().extendPointerWithSExt())
John McCallb6cc2c042010-03-02 03:50:12 +00001454 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext"));
1455 else
1456 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
John McCall4b613fa2010-03-02 02:31:24 +00001457 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001458 case Builtin::BI__builtin_setjmp: {
John McCall02269a62010-05-27 18:47:06 +00001459 // Buffer is a void**.
John McCall7f416cc2015-09-08 08:05:57 +00001460 Address Buf = EmitPointerWithAlignment(E->getArg(0));
John McCall02269a62010-05-27 18:47:06 +00001461
1462 // Store the frame pointer to the setjmp buffer.
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001463 Value *FrameAddr =
John McCall02269a62010-05-27 18:47:06 +00001464 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
Chris Lattner5e016ae2010-06-27 07:15:29 +00001465 ConstantInt::get(Int32Ty, 0));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001466 Builder.CreateStore(FrameAddr, Buf);
John McCall02269a62010-05-27 18:47:06 +00001467
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001468 // Store the stack pointer to the setjmp buffer.
1469 Value *StackAddr =
David Blaikie4ba525b2015-07-14 17:27:39 +00001470 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave));
John McCall7f416cc2015-09-08 08:05:57 +00001471 Address StackSaveSlot =
1472 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize());
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001473 Builder.CreateStore(StackAddr, StackSaveSlot);
1474
John McCall02269a62010-05-27 18:47:06 +00001475 // Call LLVM's EH setjmp, which is lightweight.
1476 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
John McCallad7c5c12011-02-08 08:22:06 +00001477 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00001478 return RValue::get(Builder.CreateCall(F, Buf.getPointer()));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001479 }
1480 case Builtin::BI__builtin_longjmp: {
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001481 Value *Buf = EmitScalarExpr(E->getArg(0));
John McCallad7c5c12011-02-08 08:22:06 +00001482 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall02269a62010-05-27 18:47:06 +00001483
1484 // Call LLVM's EH longjmp, which is lightweight.
1485 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf);
1486
John McCall20f6ab82011-01-12 03:41:02 +00001487 // longjmp doesn't return; mark this as unreachable.
1488 Builder.CreateUnreachable();
1489
1490 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001491 EmitBlock(createBasicBlock("longjmp.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001492
Craig Topper8a13c412014-05-21 05:09:00 +00001493 return RValue::get(nullptr);
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001494 }
Mon P Wangb84407d2008-05-09 22:40:52 +00001495 case Builtin::BI__sync_fetch_and_add:
Mon P Wangb84407d2008-05-09 22:40:52 +00001496 case Builtin::BI__sync_fetch_and_sub:
Chris Lattnerdc046542009-05-08 06:58:22 +00001497 case Builtin::BI__sync_fetch_and_or:
1498 case Builtin::BI__sync_fetch_and_and:
1499 case Builtin::BI__sync_fetch_and_xor:
Hal Finkeld2208b52014-10-02 20:53:50 +00001500 case Builtin::BI__sync_fetch_and_nand:
Chris Lattnerdc046542009-05-08 06:58:22 +00001501 case Builtin::BI__sync_add_and_fetch:
1502 case Builtin::BI__sync_sub_and_fetch:
1503 case Builtin::BI__sync_and_and_fetch:
1504 case Builtin::BI__sync_or_and_fetch:
1505 case Builtin::BI__sync_xor_and_fetch:
Hal Finkeld2208b52014-10-02 20:53:50 +00001506 case Builtin::BI__sync_nand_and_fetch:
Chris Lattnerdc046542009-05-08 06:58:22 +00001507 case Builtin::BI__sync_val_compare_and_swap:
1508 case Builtin::BI__sync_bool_compare_and_swap:
1509 case Builtin::BI__sync_lock_test_and_set:
1510 case Builtin::BI__sync_lock_release:
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001511 case Builtin::BI__sync_swap:
David Blaikie83d382b2011-09-23 05:06:16 +00001512 llvm_unreachable("Shouldn't make it through sema");
Chris Lattnerdc046542009-05-08 06:58:22 +00001513 case Builtin::BI__sync_fetch_and_add_1:
1514 case Builtin::BI__sync_fetch_and_add_2:
1515 case Builtin::BI__sync_fetch_and_add_4:
1516 case Builtin::BI__sync_fetch_and_add_8:
1517 case Builtin::BI__sync_fetch_and_add_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001518 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001519 case Builtin::BI__sync_fetch_and_sub_1:
1520 case Builtin::BI__sync_fetch_and_sub_2:
1521 case Builtin::BI__sync_fetch_and_sub_4:
1522 case Builtin::BI__sync_fetch_and_sub_8:
1523 case Builtin::BI__sync_fetch_and_sub_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001524 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001525 case Builtin::BI__sync_fetch_and_or_1:
1526 case Builtin::BI__sync_fetch_and_or_2:
1527 case Builtin::BI__sync_fetch_and_or_4:
1528 case Builtin::BI__sync_fetch_and_or_8:
1529 case Builtin::BI__sync_fetch_and_or_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001530 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001531 case Builtin::BI__sync_fetch_and_and_1:
1532 case Builtin::BI__sync_fetch_and_and_2:
1533 case Builtin::BI__sync_fetch_and_and_4:
1534 case Builtin::BI__sync_fetch_and_and_8:
1535 case Builtin::BI__sync_fetch_and_and_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001536 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001537 case Builtin::BI__sync_fetch_and_xor_1:
1538 case Builtin::BI__sync_fetch_and_xor_2:
1539 case Builtin::BI__sync_fetch_and_xor_4:
1540 case Builtin::BI__sync_fetch_and_xor_8:
1541 case Builtin::BI__sync_fetch_and_xor_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001542 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E);
Hal Finkeld2208b52014-10-02 20:53:50 +00001543 case Builtin::BI__sync_fetch_and_nand_1:
1544 case Builtin::BI__sync_fetch_and_nand_2:
1545 case Builtin::BI__sync_fetch_and_nand_4:
1546 case Builtin::BI__sync_fetch_and_nand_8:
1547 case Builtin::BI__sync_fetch_and_nand_16:
1548 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E);
Mike Stump11289f42009-09-09 15:08:12 +00001549
Chris Lattnerdc046542009-05-08 06:58:22 +00001550 // Clang extensions: not overloaded yet.
Mon P Wangb84407d2008-05-09 22:40:52 +00001551 case Builtin::BI__sync_fetch_and_min:
Eli Friedmane9f81132011-09-07 01:41:24 +00001552 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001553 case Builtin::BI__sync_fetch_and_max:
Eli Friedmane9f81132011-09-07 01:41:24 +00001554 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001555 case Builtin::BI__sync_fetch_and_umin:
Eli Friedmane9f81132011-09-07 01:41:24 +00001556 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001557 case Builtin::BI__sync_fetch_and_umax:
Eli Friedmane9f81132011-09-07 01:41:24 +00001558 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E);
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001559
Chris Lattnerdc046542009-05-08 06:58:22 +00001560 case Builtin::BI__sync_add_and_fetch_1:
1561 case Builtin::BI__sync_add_and_fetch_2:
1562 case Builtin::BI__sync_add_and_fetch_4:
1563 case Builtin::BI__sync_add_and_fetch_8:
1564 case Builtin::BI__sync_add_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001565 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001566 llvm::Instruction::Add);
Chris Lattnerdc046542009-05-08 06:58:22 +00001567 case Builtin::BI__sync_sub_and_fetch_1:
1568 case Builtin::BI__sync_sub_and_fetch_2:
1569 case Builtin::BI__sync_sub_and_fetch_4:
1570 case Builtin::BI__sync_sub_and_fetch_8:
1571 case Builtin::BI__sync_sub_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001572 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001573 llvm::Instruction::Sub);
Chris Lattnerdc046542009-05-08 06:58:22 +00001574 case Builtin::BI__sync_and_and_fetch_1:
1575 case Builtin::BI__sync_and_and_fetch_2:
1576 case Builtin::BI__sync_and_and_fetch_4:
1577 case Builtin::BI__sync_and_and_fetch_8:
1578 case Builtin::BI__sync_and_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001579 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001580 llvm::Instruction::And);
Chris Lattnerdc046542009-05-08 06:58:22 +00001581 case Builtin::BI__sync_or_and_fetch_1:
1582 case Builtin::BI__sync_or_and_fetch_2:
1583 case Builtin::BI__sync_or_and_fetch_4:
1584 case Builtin::BI__sync_or_and_fetch_8:
1585 case Builtin::BI__sync_or_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001586 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001587 llvm::Instruction::Or);
Chris Lattnerdc046542009-05-08 06:58:22 +00001588 case Builtin::BI__sync_xor_and_fetch_1:
1589 case Builtin::BI__sync_xor_and_fetch_2:
1590 case Builtin::BI__sync_xor_and_fetch_4:
1591 case Builtin::BI__sync_xor_and_fetch_8:
1592 case Builtin::BI__sync_xor_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001593 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001594 llvm::Instruction::Xor);
Hal Finkeld2208b52014-10-02 20:53:50 +00001595 case Builtin::BI__sync_nand_and_fetch_1:
1596 case Builtin::BI__sync_nand_and_fetch_2:
1597 case Builtin::BI__sync_nand_and_fetch_4:
1598 case Builtin::BI__sync_nand_and_fetch_8:
1599 case Builtin::BI__sync_nand_and_fetch_16:
1600 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E,
1601 llvm::Instruction::And, true);
Mike Stump11289f42009-09-09 15:08:12 +00001602
Chris Lattnerdc046542009-05-08 06:58:22 +00001603 case Builtin::BI__sync_val_compare_and_swap_1:
1604 case Builtin::BI__sync_val_compare_and_swap_2:
1605 case Builtin::BI__sync_val_compare_and_swap_4:
1606 case Builtin::BI__sync_val_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001607 case Builtin::BI__sync_val_compare_and_swap_16:
1608 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001609
Chris Lattnerdc046542009-05-08 06:58:22 +00001610 case Builtin::BI__sync_bool_compare_and_swap_1:
1611 case Builtin::BI__sync_bool_compare_and_swap_2:
1612 case Builtin::BI__sync_bool_compare_and_swap_4:
1613 case Builtin::BI__sync_bool_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001614 case Builtin::BI__sync_bool_compare_and_swap_16:
1615 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001616
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001617 case Builtin::BI__sync_swap_1:
1618 case Builtin::BI__sync_swap_2:
1619 case Builtin::BI__sync_swap_4:
1620 case Builtin::BI__sync_swap_8:
1621 case Builtin::BI__sync_swap_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001622 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001623
Chris Lattnerdc046542009-05-08 06:58:22 +00001624 case Builtin::BI__sync_lock_test_and_set_1:
1625 case Builtin::BI__sync_lock_test_and_set_2:
1626 case Builtin::BI__sync_lock_test_and_set_4:
1627 case Builtin::BI__sync_lock_test_and_set_8:
1628 case Builtin::BI__sync_lock_test_and_set_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001629 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Daniel Dunbar4ff562d2010-03-20 07:04:11 +00001630
Chris Lattnerdc046542009-05-08 06:58:22 +00001631 case Builtin::BI__sync_lock_release_1:
1632 case Builtin::BI__sync_lock_release_2:
1633 case Builtin::BI__sync_lock_release_4:
1634 case Builtin::BI__sync_lock_release_8:
Chris Lattnerafde2592009-05-13 04:46:13 +00001635 case Builtin::BI__sync_lock_release_16: {
1636 Value *Ptr = EmitScalarExpr(E->getArg(0));
Eli Friedman84d28122011-09-13 22:21:56 +00001637 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
1638 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
Eli Friedmanfefe0d02012-03-16 01:48:04 +00001639 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
1640 StoreSize.getQuantity() * 8);
1641 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
Jim Grosbachd3608f42012-09-21 00:18:27 +00001642 llvm::StoreInst *Store =
John McCall7f416cc2015-09-08 08:05:57 +00001643 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr,
1644 StoreSize);
JF Bastien92f4ef12016-04-06 17:26:42 +00001645 Store->setAtomic(llvm::AtomicOrdering::Release);
Craig Topper8a13c412014-05-21 05:09:00 +00001646 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001647 }
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001648
Chris Lattnerafde2592009-05-13 04:46:13 +00001649 case Builtin::BI__sync_synchronize: {
Eli Friedmane9f81132011-09-07 01:41:24 +00001650 // We assume this is supposed to correspond to a C++0x-style
1651 // sequentially-consistent fence (i.e. this is only usable for
1652 // synchonization, not device I/O or anything like that). This intrinsic
Jim Grosbachd3608f42012-09-21 00:18:27 +00001653 // is really badly designed in the sense that in theory, there isn't
Eli Friedmane9f81132011-09-07 01:41:24 +00001654 // any way to safely use it... but in practice, it mostly works
1655 // to use it with non-atomic loads and stores to get acquire/release
1656 // semantics.
JF Bastien92f4ef12016-04-06 17:26:42 +00001657 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent);
Craig Topper8a13c412014-05-21 05:09:00 +00001658 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001659 }
Mike Stump11289f42009-09-09 15:08:12 +00001660
Michael Zolotukhin84df1232015-09-08 23:52:33 +00001661 case Builtin::BI__builtin_nontemporal_load:
1662 return RValue::get(EmitNontemporalLoad(*this, E));
1663 case Builtin::BI__builtin_nontemporal_store:
1664 return RValue::get(EmitNontemporalStore(*this, E));
Richard Smith01ba47d2012-04-13 00:45:38 +00001665 case Builtin::BI__c11_atomic_is_lock_free:
1666 case Builtin::BI__atomic_is_lock_free: {
1667 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the
1668 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since
1669 // _Atomic(T) is always properly-aligned.
1670 const char *LibCallName = "__atomic_is_lock_free";
1671 CallArgList Args;
1672 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))),
1673 getContext().getSizeType());
1674 if (BuiltinID == Builtin::BI__atomic_is_lock_free)
1675 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))),
1676 getContext().VoidPtrTy);
1677 else
1678 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)),
1679 getContext().VoidPtrTy);
1680 const CGFunctionInfo &FuncInfo =
John McCallc56a8b32016-03-11 04:30:31 +00001681 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001682 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
1683 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
John McCallb92ab1a2016-10-26 23:46:34 +00001684 return EmitCall(FuncInfo, CGCallee::forDirect(Func),
1685 ReturnValueSlot(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001686 }
1687
1688 case Builtin::BI__atomic_test_and_set: {
1689 // Look at the argument type to determine whether this is a volatile
1690 // operation. The parameter type is always volatile.
1691 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1692 bool Volatile =
1693 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1694
1695 Value *Ptr = EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +00001696 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001697 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1698 Value *NewVal = Builder.getInt8(1);
1699 Value *Order = EmitScalarExpr(E->getArg(1));
1700 if (isa<llvm::ConstantInt>(Order)) {
1701 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
Craig Topper8a13c412014-05-21 05:09:00 +00001702 AtomicRMWInst *Result = nullptr;
Richard Smith01ba47d2012-04-13 00:45:38 +00001703 switch (ord) {
1704 case 0: // memory_order_relaxed
1705 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001706 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1707 llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001708 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001709 case 1: // memory_order_consume
1710 case 2: // memory_order_acquire
1711 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1712 llvm::AtomicOrdering::Acquire);
Richard Smith01ba47d2012-04-13 00:45:38 +00001713 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001714 case 3: // memory_order_release
1715 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1716 llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001717 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001718 case 4: // memory_order_acq_rel
1719
1720 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1721 llvm::AtomicOrdering::AcquireRelease);
Richard Smith01ba47d2012-04-13 00:45:38 +00001722 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001723 case 5: // memory_order_seq_cst
1724 Result = Builder.CreateAtomicRMW(
1725 llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1726 llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001727 break;
1728 }
1729 Result->setVolatile(Volatile);
1730 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1731 }
1732
1733 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1734
1735 llvm::BasicBlock *BBs[5] = {
1736 createBasicBlock("monotonic", CurFn),
1737 createBasicBlock("acquire", CurFn),
1738 createBasicBlock("release", CurFn),
1739 createBasicBlock("acqrel", CurFn),
1740 createBasicBlock("seqcst", CurFn)
1741 };
1742 llvm::AtomicOrdering Orders[5] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001743 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire,
1744 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease,
1745 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001746
1747 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1748 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1749
1750 Builder.SetInsertPoint(ContBB);
1751 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set");
1752
1753 for (unsigned i = 0; i < 5; ++i) {
1754 Builder.SetInsertPoint(BBs[i]);
1755 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg,
1756 Ptr, NewVal, Orders[i]);
1757 RMW->setVolatile(Volatile);
1758 Result->addIncoming(RMW, BBs[i]);
1759 Builder.CreateBr(ContBB);
1760 }
1761
1762 SI->addCase(Builder.getInt32(0), BBs[0]);
1763 SI->addCase(Builder.getInt32(1), BBs[1]);
1764 SI->addCase(Builder.getInt32(2), BBs[1]);
1765 SI->addCase(Builder.getInt32(3), BBs[2]);
1766 SI->addCase(Builder.getInt32(4), BBs[3]);
1767 SI->addCase(Builder.getInt32(5), BBs[4]);
1768
1769 Builder.SetInsertPoint(ContBB);
1770 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1771 }
1772
1773 case Builtin::BI__atomic_clear: {
1774 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1775 bool Volatile =
1776 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1777
John McCall7f416cc2015-09-08 08:05:57 +00001778 Address Ptr = EmitPointerWithAlignment(E->getArg(0));
1779 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001780 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1781 Value *NewVal = Builder.getInt8(0);
1782 Value *Order = EmitScalarExpr(E->getArg(1));
1783 if (isa<llvm::ConstantInt>(Order)) {
1784 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1785 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001786 switch (ord) {
1787 case 0: // memory_order_relaxed
1788 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001789 Store->setOrdering(llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001790 break;
1791 case 3: // memory_order_release
JF Bastien92f4ef12016-04-06 17:26:42 +00001792 Store->setOrdering(llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001793 break;
1794 case 5: // memory_order_seq_cst
JF Bastien92f4ef12016-04-06 17:26:42 +00001795 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001796 break;
1797 }
Craig Topper8a13c412014-05-21 05:09:00 +00001798 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00001799 }
1800
1801 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1802
1803 llvm::BasicBlock *BBs[3] = {
1804 createBasicBlock("monotonic", CurFn),
1805 createBasicBlock("release", CurFn),
1806 createBasicBlock("seqcst", CurFn)
1807 };
1808 llvm::AtomicOrdering Orders[3] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001809 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release,
1810 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001811
1812 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1813 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1814
1815 for (unsigned i = 0; i < 3; ++i) {
1816 Builder.SetInsertPoint(BBs[i]);
1817 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001818 Store->setOrdering(Orders[i]);
1819 Builder.CreateBr(ContBB);
1820 }
1821
1822 SI->addCase(Builder.getInt32(0), BBs[0]);
1823 SI->addCase(Builder.getInt32(3), BBs[1]);
1824 SI->addCase(Builder.getInt32(5), BBs[2]);
1825
1826 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00001827 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00001828 }
1829
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001830 case Builtin::BI__atomic_thread_fence:
Richard Smithb1e36c62012-04-11 17:55:32 +00001831 case Builtin::BI__atomic_signal_fence:
1832 case Builtin::BI__c11_atomic_thread_fence:
1833 case Builtin::BI__c11_atomic_signal_fence: {
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001834 llvm::SyncScope::ID SSID;
Richard Smithb1e36c62012-04-11 17:55:32 +00001835 if (BuiltinID == Builtin::BI__atomic_signal_fence ||
1836 BuiltinID == Builtin::BI__c11_atomic_signal_fence)
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001837 SSID = llvm::SyncScope::SingleThread;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001838 else
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001839 SSID = llvm::SyncScope::System;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001840 Value *Order = EmitScalarExpr(E->getArg(0));
1841 if (isa<llvm::ConstantInt>(Order)) {
1842 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1843 switch (ord) {
1844 case 0: // memory_order_relaxed
1845 default: // invalid order
1846 break;
1847 case 1: // memory_order_consume
1848 case 2: // memory_order_acquire
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001849 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001850 break;
1851 case 3: // memory_order_release
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001852 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001853 break;
1854 case 4: // memory_order_acq_rel
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001855 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001856 break;
1857 case 5: // memory_order_seq_cst
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001858 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001859 break;
1860 }
Craig Topper8a13c412014-05-21 05:09:00 +00001861 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001862 }
1863
1864 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB;
1865 AcquireBB = createBasicBlock("acquire", CurFn);
1866 ReleaseBB = createBasicBlock("release", CurFn);
1867 AcqRelBB = createBasicBlock("acqrel", CurFn);
1868 SeqCstBB = createBasicBlock("seqcst", CurFn);
1869 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1870
1871 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1872 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB);
1873
1874 Builder.SetInsertPoint(AcquireBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001875 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001876 Builder.CreateBr(ContBB);
1877 SI->addCase(Builder.getInt32(1), AcquireBB);
1878 SI->addCase(Builder.getInt32(2), AcquireBB);
1879
1880 Builder.SetInsertPoint(ReleaseBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001881 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001882 Builder.CreateBr(ContBB);
1883 SI->addCase(Builder.getInt32(3), ReleaseBB);
1884
1885 Builder.SetInsertPoint(AcqRelBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001886 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001887 Builder.CreateBr(ContBB);
1888 SI->addCase(Builder.getInt32(4), AcqRelBB);
1889
1890 Builder.SetInsertPoint(SeqCstBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00001891 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001892 Builder.CreateBr(ContBB);
1893 SI->addCase(Builder.getInt32(5), SeqCstBB);
1894
1895 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00001896 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00001897 }
1898
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001899 // Library functions with special handling.
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001900 case Builtin::BIsqrt:
1901 case Builtin::BIsqrtf:
1902 case Builtin::BIsqrtl: {
Hal Finkel28b2ae32013-09-12 23:57:55 +00001903 // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only
1904 // in finite- or unsafe-math mode (the intrinsic has different semantics
1905 // for handling negative numbers compared to the library function, so
1906 // -fmath-errno=0 is not enough).
1907 if (!FD->hasAttr<ConstAttr>())
1908 break;
1909 if (!(CGM.getCodeGenOpts().UnsafeFPMath ||
1910 CGM.getCodeGenOpts().NoNaNsFPMath))
1911 break;
1912 Value *Arg0 = EmitScalarExpr(E->getArg(0));
1913 llvm::Type *ArgType = Arg0->getType();
1914 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType);
1915 return RValue::get(Builder.CreateCall(F, Arg0));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001916 }
1917
Reid Kleckner8a8c1292015-02-05 00:18:01 +00001918 case Builtin::BI__builtin_pow:
1919 case Builtin::BI__builtin_powf:
1920 case Builtin::BI__builtin_powl:
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001921 case Builtin::BIpow:
1922 case Builtin::BIpowf:
1923 case Builtin::BIpowl: {
Eli Benderskyc3496b02013-07-24 21:22:01 +00001924 // Transform a call to pow* into a @llvm.pow.* intrinsic call.
1925 if (!FD->hasAttr<ConstAttr>())
1926 break;
1927 Value *Base = EmitScalarExpr(E->getArg(0));
1928 Value *Exponent = EmitScalarExpr(E->getArg(1));
1929 llvm::Type *ArgType = Base->getType();
1930 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001931 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001932 }
Eli Friedman99d20f82010-03-06 02:17:52 +00001933
Cameron Zwarichae7bc982011-07-08 21:39:34 +00001934 case Builtin::BIfma:
1935 case Builtin::BIfmaf:
1936 case Builtin::BIfmal:
1937 case Builtin::BI__builtin_fma:
1938 case Builtin::BI__builtin_fmaf:
1939 case Builtin::BI__builtin_fmal: {
1940 // Rewrite fma to intrinsic.
1941 Value *FirstArg = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001942 llvm::Type *ArgType = FirstArg->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001943 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001944 return RValue::get(
1945 Builder.CreateCall(F, {FirstArg, EmitScalarExpr(E->getArg(1)),
1946 EmitScalarExpr(E->getArg(2))}));
Cameron Zwarichae7bc982011-07-08 21:39:34 +00001947 }
1948
Eli Friedman99d20f82010-03-06 02:17:52 +00001949 case Builtin::BI__builtin_signbit:
1950 case Builtin::BI__builtin_signbitf:
1951 case Builtin::BI__builtin_signbitl: {
Chandler Carruthc66deaf2015-03-19 22:39:51 +00001952 return RValue::get(
1953 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))),
1954 ConvertType(E->getType())));
Eli Friedman99d20f82010-03-06 02:17:52 +00001955 }
Julien Lerouge5a6b6982011-09-09 22:41:49 +00001956 case Builtin::BI__builtin_annotation: {
1957 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0));
1958 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation,
1959 AnnVal->getType());
1960
1961 // Get the annotation string, go through casts. Sema requires this to be a
1962 // non-wide string literal, potentially casted, so the cast<> is safe.
1963 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts();
Dmitri Gribenkof8579502013-01-12 19:30:44 +00001964 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString();
Julien Lerouge5a6b6982011-09-09 22:41:49 +00001965 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc()));
1966 }
Michael Gottesman15343992013-06-18 20:40:40 +00001967 case Builtin::BI__builtin_addcb:
Michael Gottesman54398012013-01-13 02:22:39 +00001968 case Builtin::BI__builtin_addcs:
1969 case Builtin::BI__builtin_addc:
1970 case Builtin::BI__builtin_addcl:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00001971 case Builtin::BI__builtin_addcll:
Michael Gottesman15343992013-06-18 20:40:40 +00001972 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00001973 case Builtin::BI__builtin_subcs:
1974 case Builtin::BI__builtin_subc:
1975 case Builtin::BI__builtin_subcl:
1976 case Builtin::BI__builtin_subcll: {
Michael Gottesman54398012013-01-13 02:22:39 +00001977
1978 // We translate all of these builtins from expressions of the form:
1979 // int x = ..., y = ..., carryin = ..., carryout, result;
1980 // result = __builtin_addc(x, y, carryin, &carryout);
1981 //
1982 // to LLVM IR of the form:
1983 //
1984 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
1985 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0
1986 // %carry1 = extractvalue {i32, i1} %tmp1, 1
1987 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1,
1988 // i32 %carryin)
1989 // %result = extractvalue {i32, i1} %tmp2, 0
1990 // %carry2 = extractvalue {i32, i1} %tmp2, 1
1991 // %tmp3 = or i1 %carry1, %carry2
1992 // %tmp4 = zext i1 %tmp3 to i32
1993 // store i32 %tmp4, i32* %carryout
1994
1995 // Scalarize our inputs.
1996 llvm::Value *X = EmitScalarExpr(E->getArg(0));
1997 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
1998 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001999 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3));
Michael Gottesman54398012013-01-13 02:22:39 +00002000
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002001 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow.
2002 llvm::Intrinsic::ID IntrinsicId;
2003 switch (BuiltinID) {
2004 default: llvm_unreachable("Unknown multiprecision builtin id.");
Michael Gottesman15343992013-06-18 20:40:40 +00002005 case Builtin::BI__builtin_addcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002006 case Builtin::BI__builtin_addcs:
2007 case Builtin::BI__builtin_addc:
2008 case Builtin::BI__builtin_addcl:
2009 case Builtin::BI__builtin_addcll:
2010 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2011 break;
Michael Gottesman15343992013-06-18 20:40:40 +00002012 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002013 case Builtin::BI__builtin_subcs:
2014 case Builtin::BI__builtin_subc:
2015 case Builtin::BI__builtin_subcl:
2016 case Builtin::BI__builtin_subcll:
2017 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2018 break;
2019 }
Michael Gottesman54398012013-01-13 02:22:39 +00002020
2021 // Construct our resulting LLVM IR expression.
2022 llvm::Value *Carry1;
2023 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId,
2024 X, Y, Carry1);
2025 llvm::Value *Carry2;
2026 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId,
2027 Sum1, Carryin, Carry2);
2028 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2),
2029 X->getType());
John McCall7f416cc2015-09-08 08:05:57 +00002030 Builder.CreateStore(CarryOut, CarryOutPtr);
Michael Gottesman54398012013-01-13 02:22:39 +00002031 return RValue::get(Sum2);
2032 }
John McCall03107a42015-10-29 20:48:01 +00002033
2034 case Builtin::BI__builtin_add_overflow:
2035 case Builtin::BI__builtin_sub_overflow:
2036 case Builtin::BI__builtin_mul_overflow: {
2037 const clang::Expr *LeftArg = E->getArg(0);
2038 const clang::Expr *RightArg = E->getArg(1);
2039 const clang::Expr *ResultArg = E->getArg(2);
2040
2041 clang::QualType ResultQTy =
2042 ResultArg->getType()->castAs<PointerType>()->getPointeeType();
2043
2044 WidthAndSignedness LeftInfo =
2045 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType());
2046 WidthAndSignedness RightInfo =
2047 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType());
2048 WidthAndSignedness ResultInfo =
2049 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy);
2050 WidthAndSignedness EncompassingInfo =
2051 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo});
2052
2053 llvm::Type *EncompassingLLVMTy =
2054 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width);
2055
2056 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy);
2057
2058 llvm::Intrinsic::ID IntrinsicId;
2059 switch (BuiltinID) {
2060 default:
2061 llvm_unreachable("Unknown overflow builtin id.");
2062 case Builtin::BI__builtin_add_overflow:
2063 IntrinsicId = EncompassingInfo.Signed
2064 ? llvm::Intrinsic::sadd_with_overflow
2065 : llvm::Intrinsic::uadd_with_overflow;
2066 break;
2067 case Builtin::BI__builtin_sub_overflow:
2068 IntrinsicId = EncompassingInfo.Signed
2069 ? llvm::Intrinsic::ssub_with_overflow
2070 : llvm::Intrinsic::usub_with_overflow;
2071 break;
2072 case Builtin::BI__builtin_mul_overflow:
2073 IntrinsicId = EncompassingInfo.Signed
2074 ? llvm::Intrinsic::smul_with_overflow
2075 : llvm::Intrinsic::umul_with_overflow;
2076 break;
2077 }
2078
2079 llvm::Value *Left = EmitScalarExpr(LeftArg);
2080 llvm::Value *Right = EmitScalarExpr(RightArg);
2081 Address ResultPtr = EmitPointerWithAlignment(ResultArg);
2082
2083 // Extend each operand to the encompassing type.
2084 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed);
2085 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed);
2086
2087 // Perform the operation on the extended values.
2088 llvm::Value *Overflow, *Result;
2089 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow);
2090
2091 if (EncompassingInfo.Width > ResultInfo.Width) {
2092 // The encompassing type is wider than the result type, so we need to
2093 // truncate it.
2094 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy);
2095
2096 // To see if the truncation caused an overflow, we will extend
2097 // the result and then compare it to the original result.
2098 llvm::Value *ResultTruncExt = Builder.CreateIntCast(
2099 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed);
2100 llvm::Value *TruncationOverflow =
2101 Builder.CreateICmpNE(Result, ResultTruncExt);
2102
2103 Overflow = Builder.CreateOr(Overflow, TruncationOverflow);
2104 Result = ResultTrunc;
2105 }
2106
2107 // Finally, store the result using the pointer.
2108 bool isVolatile =
2109 ResultArg->getType()->getPointeeType().isVolatileQualified();
2110 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile);
2111
2112 return RValue::get(Overflow);
2113 }
2114
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002115 case Builtin::BI__builtin_uadd_overflow:
2116 case Builtin::BI__builtin_uaddl_overflow:
2117 case Builtin::BI__builtin_uaddll_overflow:
2118 case Builtin::BI__builtin_usub_overflow:
2119 case Builtin::BI__builtin_usubl_overflow:
2120 case Builtin::BI__builtin_usubll_overflow:
2121 case Builtin::BI__builtin_umul_overflow:
2122 case Builtin::BI__builtin_umull_overflow:
2123 case Builtin::BI__builtin_umulll_overflow:
2124 case Builtin::BI__builtin_sadd_overflow:
2125 case Builtin::BI__builtin_saddl_overflow:
2126 case Builtin::BI__builtin_saddll_overflow:
2127 case Builtin::BI__builtin_ssub_overflow:
2128 case Builtin::BI__builtin_ssubl_overflow:
2129 case Builtin::BI__builtin_ssubll_overflow:
2130 case Builtin::BI__builtin_smul_overflow:
2131 case Builtin::BI__builtin_smull_overflow:
2132 case Builtin::BI__builtin_smulll_overflow: {
2133
2134 // We translate all of these builtins directly to the relevant llvm IR node.
2135
2136 // Scalarize our inputs.
2137 llvm::Value *X = EmitScalarExpr(E->getArg(0));
2138 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00002139 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2));
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002140
2141 // Decide which of the overflow intrinsics we are lowering to:
2142 llvm::Intrinsic::ID IntrinsicId;
2143 switch (BuiltinID) {
John McCall03107a42015-10-29 20:48:01 +00002144 default: llvm_unreachable("Unknown overflow builtin id.");
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002145 case Builtin::BI__builtin_uadd_overflow:
2146 case Builtin::BI__builtin_uaddl_overflow:
2147 case Builtin::BI__builtin_uaddll_overflow:
2148 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2149 break;
2150 case Builtin::BI__builtin_usub_overflow:
2151 case Builtin::BI__builtin_usubl_overflow:
2152 case Builtin::BI__builtin_usubll_overflow:
2153 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2154 break;
2155 case Builtin::BI__builtin_umul_overflow:
2156 case Builtin::BI__builtin_umull_overflow:
2157 case Builtin::BI__builtin_umulll_overflow:
2158 IntrinsicId = llvm::Intrinsic::umul_with_overflow;
2159 break;
2160 case Builtin::BI__builtin_sadd_overflow:
2161 case Builtin::BI__builtin_saddl_overflow:
2162 case Builtin::BI__builtin_saddll_overflow:
2163 IntrinsicId = llvm::Intrinsic::sadd_with_overflow;
2164 break;
2165 case Builtin::BI__builtin_ssub_overflow:
2166 case Builtin::BI__builtin_ssubl_overflow:
2167 case Builtin::BI__builtin_ssubll_overflow:
2168 IntrinsicId = llvm::Intrinsic::ssub_with_overflow;
2169 break;
2170 case Builtin::BI__builtin_smul_overflow:
2171 case Builtin::BI__builtin_smull_overflow:
2172 case Builtin::BI__builtin_smulll_overflow:
2173 IntrinsicId = llvm::Intrinsic::smul_with_overflow;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00002174 break;
2175 }
2176
2177
2178 llvm::Value *Carry;
2179 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry);
2180 Builder.CreateStore(Sum, SumOutPtr);
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002181
2182 return RValue::get(Carry);
2183 }
Richard Smith6cbd65d2013-07-11 02:27:57 +00002184 case Builtin::BI__builtin_addressof:
John McCall7f416cc2015-09-08 08:05:57 +00002185 return RValue::get(EmitLValue(E->getArg(0)).getPointer());
Richard Smith760520b2014-06-03 23:27:44 +00002186 case Builtin::BI__builtin_operator_new:
2187 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2188 E->getArg(0), false);
2189 case Builtin::BI__builtin_operator_delete:
2190 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2191 E->getArg(0), true);
Nico Weber636fc092012-10-13 22:30:41 +00002192 case Builtin::BI__noop:
Reid Klecknered5d4ad2014-07-11 20:22:55 +00002193 // __noop always evaluates to an integer literal zero.
2194 return RValue::get(ConstantInt::get(IntTy, 0));
Peter Collingbournef7706832014-12-12 23:41:25 +00002195 case Builtin::BI__builtin_call_with_static_chain: {
2196 const CallExpr *Call = cast<CallExpr>(E->getArg(0));
2197 const Expr *Chain = E->getArg(1);
2198 return EmitCall(Call->getCallee()->getType(),
John McCallb92ab1a2016-10-26 23:46:34 +00002199 EmitCallee(Call->getCallee()), Call, ReturnValue,
2200 EmitScalarExpr(Chain));
Peter Collingbournef7706832014-12-12 23:41:25 +00002201 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002202 case Builtin::BI_InterlockedExchange8:
2203 case Builtin::BI_InterlockedExchange16:
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002204 case Builtin::BI_InterlockedExchange:
2205 case Builtin::BI_InterlockedExchangePointer:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002206 return RValue::get(
2207 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E));
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002208 case Builtin::BI_InterlockedCompareExchangePointer: {
2209 llvm::Type *RTy;
2210 llvm::IntegerType *IntType =
2211 IntegerType::get(getLLVMContext(),
2212 getContext().getTypeSize(E->getType()));
2213 llvm::Type *IntPtrType = IntType->getPointerTo();
2214
2215 llvm::Value *Destination =
2216 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType);
2217
2218 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
2219 RTy = Exchange->getType();
2220 Exchange = Builder.CreatePtrToInt(Exchange, IntType);
2221
2222 llvm::Value *Comparand =
2223 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
2224
JF Bastien92f4ef12016-04-06 17:26:42 +00002225 auto Result =
2226 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,
2227 AtomicOrdering::SequentiallyConsistent,
2228 AtomicOrdering::SequentiallyConsistent);
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002229 Result->setVolatile(true);
2230
2231 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
2232 0),
2233 RTy));
2234 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002235 case Builtin::BI_InterlockedCompareExchange8:
2236 case Builtin::BI_InterlockedCompareExchange16:
2237 case Builtin::BI_InterlockedCompareExchange:
2238 case Builtin::BI_InterlockedCompareExchange64: {
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002239 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg(
2240 EmitScalarExpr(E->getArg(0)),
2241 EmitScalarExpr(E->getArg(2)),
2242 EmitScalarExpr(E->getArg(1)),
JF Bastien92f4ef12016-04-06 17:26:42 +00002243 AtomicOrdering::SequentiallyConsistent,
2244 AtomicOrdering::SequentiallyConsistent);
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002245 CXI->setVolatile(true);
Tim Northoverb49b04b2014-06-13 14:24:59 +00002246 return RValue::get(Builder.CreateExtractValue(CXI, 0));
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002247 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002248 case Builtin::BI_InterlockedIncrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002249 case Builtin::BI_InterlockedIncrement:
2250 return RValue::get(
2251 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002252 case Builtin::BI_InterlockedDecrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002253 case Builtin::BI_InterlockedDecrement:
2254 return RValue::get(
2255 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002256 case Builtin::BI_InterlockedAnd8:
2257 case Builtin::BI_InterlockedAnd16:
2258 case Builtin::BI_InterlockedAnd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002259 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002260 case Builtin::BI_InterlockedExchangeAdd8:
2261 case Builtin::BI_InterlockedExchangeAdd16:
2262 case Builtin::BI_InterlockedExchangeAdd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002263 return RValue::get(
2264 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002265 case Builtin::BI_InterlockedExchangeSub8:
2266 case Builtin::BI_InterlockedExchangeSub16:
2267 case Builtin::BI_InterlockedExchangeSub:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002268 return RValue::get(
2269 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002270 case Builtin::BI_InterlockedOr8:
2271 case Builtin::BI_InterlockedOr16:
2272 case Builtin::BI_InterlockedOr:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002273 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002274 case Builtin::BI_InterlockedXor8:
2275 case Builtin::BI_InterlockedXor16:
2276 case Builtin::BI_InterlockedXor:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002277 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E));
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002278 case Builtin::BI_interlockedbittestandset:
2279 return RValue::get(
2280 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E));
Reid Kleckner1d59f992015-01-22 01:36:17 +00002281
2282 case Builtin::BI__exception_code:
2283 case Builtin::BI_exception_code:
2284 return RValue::get(EmitSEHExceptionCode());
2285 case Builtin::BI__exception_info:
2286 case Builtin::BI_exception_info:
2287 return RValue::get(EmitSEHExceptionInfo());
Reid Kleckneraca01db2015-02-04 22:37:07 +00002288 case Builtin::BI__abnormal_termination:
2289 case Builtin::BI_abnormal_termination:
2290 return RValue::get(EmitSEHAbnormalTermination());
David Majnemer310e3a82015-01-29 09:29:21 +00002291 case Builtin::BI_setjmpex: {
2292 if (getTarget().getTriple().isOSMSVCRT()) {
2293 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
Reid Klecknerde864822017-03-21 16:57:30 +00002294 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2295 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2296 llvm::Attribute::ReturnsTwice);
David Majnemer310e3a82015-01-29 09:29:21 +00002297 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction(
2298 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002299 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true);
David Majnemerc403a1c2015-03-20 17:03:35 +00002300 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2301 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002302 llvm::Value *FrameAddr =
2303 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2304 ConstantInt::get(Int32Ty, 0));
2305 llvm::Value *Args[] = {Buf, FrameAddr};
2306 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args);
2307 CS.setAttributes(ReturnsTwiceAttr);
2308 return RValue::get(CS.getInstruction());
2309 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002310 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002311 }
2312 case Builtin::BI_setjmp: {
2313 if (getTarget().getTriple().isOSMSVCRT()) {
Reid Klecknerde864822017-03-21 16:57:30 +00002314 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2315 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2316 llvm::Attribute::ReturnsTwice);
David Majnemerc403a1c2015-03-20 17:03:35 +00002317 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2318 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002319 llvm::CallSite CS;
2320 if (getTarget().getTriple().getArch() == llvm::Triple::x86) {
2321 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy};
2322 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction(
2323 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002324 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002325 llvm::Value *Count = ConstantInt::get(IntTy, 0);
2326 llvm::Value *Args[] = {Buf, Count};
2327 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args);
2328 } else {
2329 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
2330 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction(
2331 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002332 "_setjmp", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002333 llvm::Value *FrameAddr =
2334 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2335 ConstantInt::get(Int32Ty, 0));
2336 llvm::Value *Args[] = {Buf, FrameAddr};
2337 CS = EmitRuntimeCallOrInvoke(SetJmp, Args);
2338 }
2339 CS.setAttributes(ReturnsTwiceAttr);
2340 return RValue::get(CS.getInstruction());
2341 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002342 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002343 }
David Majnemerba3e5ec2015-03-13 18:26:17 +00002344
2345 case Builtin::BI__GetExceptionInfo: {
2346 if (llvm::GlobalVariable *GV =
2347 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType()))
2348 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy));
2349 break;
2350 }
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002351
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002352 case Builtin::BI__fastfail:
Reid Kleckner04f9f912017-02-09 18:31:06 +00002353 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E));
Reid Kleckner04f9f912017-02-09 18:31:06 +00002354
Gor Nishanov97e3b6d2016-10-03 22:44:48 +00002355 case Builtin::BI__builtin_coro_size: {
2356 auto & Context = getContext();
2357 auto SizeTy = Context.getSizeType();
2358 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
2359 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T);
2360 return RValue::get(Builder.CreateCall(F));
2361 }
2362
2363 case Builtin::BI__builtin_coro_id:
2364 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id);
2365 case Builtin::BI__builtin_coro_promise:
2366 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise);
2367 case Builtin::BI__builtin_coro_resume:
2368 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume);
2369 case Builtin::BI__builtin_coro_frame:
2370 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame);
2371 case Builtin::BI__builtin_coro_free:
2372 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free);
2373 case Builtin::BI__builtin_coro_destroy:
2374 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy);
2375 case Builtin::BI__builtin_coro_done:
2376 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done);
2377 case Builtin::BI__builtin_coro_alloc:
2378 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc);
2379 case Builtin::BI__builtin_coro_begin:
2380 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin);
2381 case Builtin::BI__builtin_coro_end:
2382 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end);
2383 case Builtin::BI__builtin_coro_suspend:
2384 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend);
2385 case Builtin::BI__builtin_coro_param:
2386 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param);
2387
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002388 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions
2389 case Builtin::BIread_pipe:
2390 case Builtin::BIwrite_pipe: {
2391 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2392 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002393 CGOpenCLRuntime OpenCLRT(CGM);
2394 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2395 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002396
2397 // Type of the generic packet parameter.
2398 unsigned GenericAS =
2399 getContext().getTargetAddressSpace(LangAS::opencl_generic);
2400 llvm::Type *I8PTy = llvm::PointerType::get(
2401 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS);
2402
2403 // Testing which overloaded version we should generate the call for.
2404 if (2U == E->getNumArgs()) {
2405 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2"
2406 : "__write_pipe_2";
2407 // Creating a generic function type to be able to call with any builtin or
2408 // user defined type.
Alexey Bader465c1892016-09-23 14:20:00 +00002409 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002410 llvm::FunctionType *FTy = llvm::FunctionType::get(
2411 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2412 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002413 return RValue::get(
2414 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2415 {Arg0, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002416 } else {
2417 assert(4 == E->getNumArgs() &&
2418 "Illegal number of parameters to pipe function");
2419 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4"
2420 : "__write_pipe_4";
2421
Alexey Bader465c1892016-09-23 14:20:00 +00002422 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy,
2423 Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002424 Value *Arg2 = EmitScalarExpr(E->getArg(2)),
2425 *Arg3 = EmitScalarExpr(E->getArg(3));
2426 llvm::FunctionType *FTy = llvm::FunctionType::get(
2427 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2428 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy);
2429 // We know the third argument is an integer type, but we may need to cast
2430 // it to i32.
2431 if (Arg2->getType() != Int32Ty)
2432 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty);
2433 return RValue::get(Builder.CreateCall(
Alexey Bader465c1892016-09-23 14:20:00 +00002434 CGM.CreateRuntimeFunction(FTy, Name),
2435 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002436 }
2437 }
2438 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write
2439 // functions
2440 case Builtin::BIreserve_read_pipe:
2441 case Builtin::BIreserve_write_pipe:
2442 case Builtin::BIwork_group_reserve_read_pipe:
2443 case Builtin::BIwork_group_reserve_write_pipe:
2444 case Builtin::BIsub_group_reserve_read_pipe:
2445 case Builtin::BIsub_group_reserve_write_pipe: {
2446 // Composing the mangled name for the function.
2447 const char *Name;
2448 if (BuiltinID == Builtin::BIreserve_read_pipe)
2449 Name = "__reserve_read_pipe";
2450 else if (BuiltinID == Builtin::BIreserve_write_pipe)
2451 Name = "__reserve_write_pipe";
2452 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe)
2453 Name = "__work_group_reserve_read_pipe";
2454 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe)
2455 Name = "__work_group_reserve_write_pipe";
2456 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe)
2457 Name = "__sub_group_reserve_read_pipe";
2458 else
2459 Name = "__sub_group_reserve_write_pipe";
2460
2461 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2462 *Arg1 = EmitScalarExpr(E->getArg(1));
2463 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002464 CGOpenCLRuntime OpenCLRT(CGM);
2465 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2466 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002467
2468 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002469 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002470 llvm::FunctionType *FTy = llvm::FunctionType::get(
2471 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2472 // We know the second argument is an integer type, but we may need to cast
2473 // it to i32.
2474 if (Arg1->getType() != Int32Ty)
2475 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty);
2476 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002477 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2478 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002479 }
Anastasia Stulova7f8d6dc2016-07-04 16:07:18 +00002480 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002481 // functions
2482 case Builtin::BIcommit_read_pipe:
2483 case Builtin::BIcommit_write_pipe:
2484 case Builtin::BIwork_group_commit_read_pipe:
2485 case Builtin::BIwork_group_commit_write_pipe:
2486 case Builtin::BIsub_group_commit_read_pipe:
2487 case Builtin::BIsub_group_commit_write_pipe: {
2488 const char *Name;
2489 if (BuiltinID == Builtin::BIcommit_read_pipe)
2490 Name = "__commit_read_pipe";
2491 else if (BuiltinID == Builtin::BIcommit_write_pipe)
2492 Name = "__commit_write_pipe";
2493 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe)
2494 Name = "__work_group_commit_read_pipe";
2495 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe)
2496 Name = "__work_group_commit_write_pipe";
2497 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe)
2498 Name = "__sub_group_commit_read_pipe";
2499 else
2500 Name = "__sub_group_commit_write_pipe";
2501
2502 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2503 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002504 CGOpenCLRuntime OpenCLRT(CGM);
2505 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2506 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002507
2508 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002509 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002510 llvm::FunctionType *FTy =
2511 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
2512 llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2513
2514 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002515 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2516 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002517 }
2518 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions
2519 case Builtin::BIget_pipe_num_packets:
2520 case Builtin::BIget_pipe_max_packets: {
2521 const char *Name;
2522 if (BuiltinID == Builtin::BIget_pipe_num_packets)
2523 Name = "__get_pipe_num_packets";
2524 else
2525 Name = "__get_pipe_max_packets";
2526
2527 // Building the generic function prototype.
2528 Value *Arg0 = EmitScalarExpr(E->getArg(0));
Alexey Bader465c1892016-09-23 14:20:00 +00002529 CGOpenCLRuntime OpenCLRT(CGM);
2530 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2531 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
2532 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002533 llvm::FunctionType *FTy = llvm::FunctionType::get(
2534 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2535
Alexey Bader465c1892016-09-23 14:20:00 +00002536 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2537 {Arg0, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002538 }
2539
Yaxun Liuf7449a12016-05-20 19:54:38 +00002540 // OpenCL v2.0 s6.13.9 - Address space qualifier functions.
2541 case Builtin::BIto_global:
2542 case Builtin::BIto_local:
2543 case Builtin::BIto_private: {
2544 auto Arg0 = EmitScalarExpr(E->getArg(0));
2545 auto NewArgT = llvm::PointerType::get(Int8Ty,
2546 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
2547 auto NewRetT = llvm::PointerType::get(Int8Ty,
2548 CGM.getContext().getTargetAddressSpace(
2549 E->getType()->getPointeeType().getAddressSpace()));
2550 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false);
2551 llvm::Value *NewArg;
2552 if (Arg0->getType()->getPointerAddressSpace() !=
2553 NewArgT->getPointerAddressSpace())
2554 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT);
2555 else
2556 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT);
Alexey Baderd81623262016-08-04 18:06:27 +00002557 auto NewName = std::string("__") + E->getDirectCallee()->getName().str();
2558 auto NewCall =
2559 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg});
Yaxun Liuf7449a12016-05-20 19:54:38 +00002560 return RValue::get(Builder.CreateBitOrPointerCast(NewCall,
2561 ConvertType(E->getType())));
2562 }
2563
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002564 // OpenCL v2.0, s6.13.17 - Enqueue kernel function.
2565 // It contains four different overload formats specified in Table 6.13.17.1.
2566 case Builtin::BIenqueue_kernel: {
2567 StringRef Name; // Generated function call name
2568 unsigned NumArgs = E->getNumArgs();
2569
2570 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002571 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2572 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002573
2574 llvm::Value *Queue = EmitScalarExpr(E->getArg(0));
2575 llvm::Value *Flags = EmitScalarExpr(E->getArg(1));
Anastasia Stulova58984e72017-02-16 12:27:47 +00002576 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2));
2577 llvm::Value *Range = NDRangeL.getAddress().getPointer();
2578 llvm::Type *RangeTy = NDRangeL.getAddress().getType();
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002579
2580 if (NumArgs == 4) {
2581 // The most basic form of the call with parameters:
2582 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void)
2583 Name = "__enqueue_kernel_basic";
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002584 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002585 llvm::FunctionType *FTy = llvm::FunctionType::get(
2586 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys, 4), false);
2587
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002588 llvm::Value *Block = Builder.CreatePointerCast(
2589 EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002590
Anastasia Stulova58984e72017-02-16 12:27:47 +00002591 AttrBuilder B;
2592 B.addAttribute(Attribute::ByVal);
Reid Klecknerde864822017-03-21 16:57:30 +00002593 llvm::AttributeList ByValAttrSet =
2594 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B);
Anastasia Stulova58984e72017-02-16 12:27:47 +00002595
2596 auto RTCall =
2597 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet),
2598 {Queue, Flags, Range, Block});
2599 RTCall->setAttributes(ByValAttrSet);
2600 return RValue::get(RTCall);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002601 }
2602 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature");
2603
2604 // Could have events and/or vaargs.
2605 if (E->getArg(3)->getType()->isBlockPointerType()) {
2606 // No events passed, but has variadic arguments.
2607 Name = "__enqueue_kernel_vaargs";
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002608 llvm::Value *Block = Builder.CreatePointerCast(
2609 EmitScalarExpr(E->getArg(3)), GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002610 // Create a vector of the arguments, as well as a constant value to
2611 // express to the runtime the number of variadic arguments.
2612 std::vector<llvm::Value *> Args = {Queue, Flags, Range, Block,
2613 ConstantInt::get(IntTy, NumArgs - 4)};
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002614 std::vector<llvm::Type *> ArgTys = {QueueTy, IntTy, RangeTy,
2615 GenericVoidPtrTy, IntTy};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002616
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002617 // Each of the following arguments specifies the size of the corresponding
2618 // argument passed to the enqueued block.
2619 for (unsigned I = 4/*Position of the first size arg*/; I < NumArgs; ++I)
2620 Args.push_back(
2621 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002622
2623 llvm::FunctionType *FTy = llvm::FunctionType::get(
2624 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), true);
2625 return RValue::get(
2626 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2627 llvm::ArrayRef<llvm::Value *>(Args)));
2628 }
2629 // Any calls now have event arguments passed.
2630 if (NumArgs >= 7) {
2631 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy);
Anastasia Stulova2b461202016-11-14 15:34:01 +00002632 llvm::Type *EventPtrTy = EventTy->getPointerTo(
2633 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002634
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002635 llvm::Value *NumEvents =
2636 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002637 llvm::Value *EventList =
2638 E->getArg(4)->getType()->isArrayType()
2639 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer()
2640 : EmitScalarExpr(E->getArg(4));
2641 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5));
Anastasia Stulova2b461202016-11-14 15:34:01 +00002642 // Convert to generic address space.
2643 EventList = Builder.CreatePointerCast(EventList, EventPtrTy);
2644 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002645 llvm::Value *Block = Builder.CreatePointerCast(
2646 EmitScalarExpr(E->getArg(6)), GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002647
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002648 std::vector<llvm::Type *> ArgTys = {
2649 QueueTy, Int32Ty, RangeTy, Int32Ty,
2650 EventPtrTy, EventPtrTy, GenericVoidPtrTy};
Anastasia Stulova2b461202016-11-14 15:34:01 +00002651
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002652 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents,
2653 EventList, ClkEvent, Block};
2654
2655 if (NumArgs == 7) {
2656 // Has events but no variadics.
2657 Name = "__enqueue_kernel_basic_events";
2658 llvm::FunctionType *FTy = llvm::FunctionType::get(
2659 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2660 return RValue::get(
2661 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2662 llvm::ArrayRef<llvm::Value *>(Args)));
2663 }
2664 // Has event info and variadics
2665 // Pass the number of variadics to the runtime function too.
2666 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7));
2667 ArgTys.push_back(Int32Ty);
2668 Name = "__enqueue_kernel_events_vaargs";
2669
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002670 // Each of the following arguments specifies the size of the corresponding
2671 // argument passed to the enqueued block.
2672 for (unsigned I = 7/*Position of the first size arg*/; I < NumArgs; ++I)
2673 Args.push_back(
2674 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy));
2675
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002676 llvm::FunctionType *FTy = llvm::FunctionType::get(
2677 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), true);
2678 return RValue::get(
2679 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2680 llvm::ArrayRef<llvm::Value *>(Args)));
2681 }
Galina Kistanova0872d6c2017-06-03 06:30:46 +00002682 LLVM_FALLTHROUGH;
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002683 }
2684 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
2685 // parameter.
2686 case Builtin::BIget_kernel_work_group_size: {
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002687 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2688 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002689 Value *Arg = EmitScalarExpr(E->getArg(0));
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002690 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002691 return RValue::get(Builder.CreateCall(
2692 CGM.CreateRuntimeFunction(
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002693 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
2694 "__get_kernel_work_group_size_impl"),
2695 Arg));
2696 }
2697 case Builtin::BIget_kernel_preferred_work_group_size_multiple: {
2698 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2699 getContext().getTargetAddressSpace(LangAS::opencl_generic));
2700 Value *Arg = EmitScalarExpr(E->getArg(0));
2701 Arg = Builder.CreatePointerCast(Arg, GenericVoidPtrTy);
2702 return RValue::get(Builder.CreateCall(
2703 CGM.CreateRuntimeFunction(
2704 llvm::FunctionType::get(IntTy, GenericVoidPtrTy, false),
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002705 "__get_kernel_preferred_work_group_multiple_impl"),
2706 Arg));
2707 }
Joey Goulyfa76b492017-08-01 13:27:09 +00002708 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2709 case Builtin::BIget_kernel_sub_group_count_for_ndrange: {
2710 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2711 getContext().getTargetAddressSpace(LangAS::opencl_generic));
2712 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0));
2713 llvm::Value *NDRange = NDRangeL.getAddress().getPointer();
2714 Value *Block = EmitScalarExpr(E->getArg(1));
2715 Block = Builder.CreatePointerCast(Block, GenericVoidPtrTy);
2716 const char *Name =
2717 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange
2718 ? "__get_kernel_max_sub_group_size_for_ndrange_impl"
2719 : "__get_kernel_sub_group_count_for_ndrange_impl";
2720 return RValue::get(Builder.CreateCall(
2721 CGM.CreateRuntimeFunction(
2722 llvm::FunctionType::get(
2723 IntTy, {NDRange->getType(), GenericVoidPtrTy}, false),
2724 Name),
2725 {NDRange, Block}));
2726 }
Justin Lebar3039a592016-01-23 21:28:14 +00002727 case Builtin::BIprintf:
Arpith Chacko Jacobcdda3daa2017-01-29 20:49:31 +00002728 if (getTarget().getTriple().isNVPTX())
2729 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue);
Matt Arsenault2d933982016-02-27 09:06:18 +00002730 break;
2731 case Builtin::BI__builtin_canonicalize:
2732 case Builtin::BI__builtin_canonicalizef:
2733 case Builtin::BI__builtin_canonicalizel:
2734 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize));
Marcin Koscielnickia46fade2016-06-16 13:41:54 +00002735
2736 case Builtin::BI__builtin_thread_pointer: {
2737 if (!getContext().getTargetInfo().isTLSSupported())
2738 CGM.ErrorUnsupported(E, "__builtin_thread_pointer");
2739 // Fall through - it's already mapped to the intrinsic by GCCBuiltin.
2740 break;
2741 }
Mehdi Amini06d367c2016-10-24 20:39:34 +00002742 case Builtin::BI__builtin_os_log_format: {
2743 assert(E->getNumArgs() >= 2 &&
2744 "__builtin_os_log_format takes at least 2 arguments");
2745 analyze_os_log::OSLogBufferLayout Layout;
2746 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);
2747 Address BufAddr = EmitPointerWithAlignment(E->getArg(0));
2748 // Ignore argument 1, the format string. It is not currently used.
2749 CharUnits Offset;
2750 Builder.CreateStore(
2751 Builder.getInt8(Layout.getSummaryByte()),
2752 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary"));
2753 Builder.CreateStore(
2754 Builder.getInt8(Layout.getNumArgsByte()),
2755 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs"));
2756
2757 llvm::SmallVector<llvm::Value *, 4> RetainableOperands;
2758 for (const auto &Item : Layout.Items) {
2759 Builder.CreateStore(
2760 Builder.getInt8(Item.getDescriptorByte()),
2761 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor"));
2762 Builder.CreateStore(
2763 Builder.getInt8(Item.getSizeByte()),
2764 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize"));
2765 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset);
2766 if (const Expr *TheExpr = Item.getExpr()) {
2767 Addr = Builder.CreateElementBitCast(
2768 Addr, ConvertTypeForMem(TheExpr->getType()));
2769 // Check if this is a retainable type.
2770 if (TheExpr->getType()->isObjCRetainableType()) {
2771 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar &&
2772 "Only scalar can be a ObjC retainable type");
2773 llvm::Value *SV = EmitScalarExpr(TheExpr, /*Ignore*/ false);
2774 RValue RV = RValue::get(SV);
2775 LValue LV = MakeAddrLValue(Addr, TheExpr->getType());
2776 EmitStoreThroughLValue(RV, LV);
2777 // Check if the object is constant, if not, save it in
2778 // RetainableOperands.
2779 if (!isa<Constant>(SV))
2780 RetainableOperands.push_back(SV);
2781 } else {
2782 EmitAnyExprToMem(TheExpr, Addr, Qualifiers(), /*isInit*/ true);
2783 }
2784 } else {
2785 Addr = Builder.CreateElementBitCast(Addr, Int32Ty);
2786 Builder.CreateStore(
2787 Builder.getInt32(Item.getConstValue().getQuantity()), Addr);
2788 }
2789 Offset += Item.size();
2790 }
2791
2792 // Push a clang.arc.use cleanup for each object in RetainableOperands. The
2793 // cleanup will cause the use to appear after the final log call, keeping
Nico Weber050af672017-05-05 17:16:58 +00002794 // the object valid while it's held in the log buffer. Note that if there's
Mehdi Amini06d367c2016-10-24 20:39:34 +00002795 // a release cleanup on the object, it will already be active; since
2796 // cleanups are emitted in reverse order, the use will occur before the
2797 // object is released.
2798 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount &&
2799 CGM.getCodeGenOpts().OptimizationLevel != 0)
2800 for (llvm::Value *object : RetainableOperands)
2801 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), object);
2802
2803 return RValue::get(BufAddr.getPointer());
2804 }
2805
2806 case Builtin::BI__builtin_os_log_format_buffer_size: {
2807 analyze_os_log::OSLogBufferLayout Layout;
2808 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);
2809 return RValue::get(ConstantInt::get(ConvertType(E->getType()),
2810 Layout.size().getQuantity()));
2811 }
Dean Michael Berris42af6512017-05-09 00:45:40 +00002812
2813 case Builtin::BI__xray_customevent: {
2814 if (!ShouldXRayInstrumentFunction())
2815 return RValue::getIgnored();
2816 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
2817 if (XRayAttr->neverXRayInstrument())
2818 return RValue::getIgnored();
2819 }
2820 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
2821 auto FTy = F->getFunctionType();
2822 auto Arg0 = E->getArg(0);
2823 auto Arg0Val = EmitScalarExpr(Arg0);
2824 auto Arg0Ty = Arg0->getType();
2825 auto PTy0 = FTy->getParamType(0);
2826 if (PTy0 != Arg0Val->getType()) {
2827 if (Arg0Ty->isArrayType())
2828 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer();
2829 else
2830 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0);
2831 }
2832 auto Arg1 = EmitScalarExpr(E->getArg(1));
2833 auto PTy1 = FTy->getParamType(1);
2834 if (PTy1 != Arg1->getType())
2835 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
2836 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
2837 }
Martin Storsjo022e7822017-07-17 20:49:45 +00002838
2839 case Builtin::BI__builtin_ms_va_start:
2840 case Builtin::BI__builtin_ms_va_end:
2841 return RValue::get(
2842 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(),
2843 BuiltinID == Builtin::BI__builtin_ms_va_start));
2844
2845 case Builtin::BI__builtin_ms_va_copy: {
2846 // Lower this manually. We can't reliably determine whether or not any
2847 // given va_copy() is for a Win64 va_list from the calling convention
2848 // alone, because it's legal to do this from a System V ABI function.
2849 // With opaque pointer types, we won't have enough information in LLVM
2850 // IR to determine this from the argument types, either. Best to do it
2851 // now, while we have enough information.
2852 Address DestAddr = EmitMSVAListRef(E->getArg(0));
2853 Address SrcAddr = EmitMSVAListRef(E->getArg(1));
2854
2855 llvm::Type *BPP = Int8PtrPtrTy;
2856
2857 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"),
2858 DestAddr.getAlignment());
2859 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"),
2860 SrcAddr.getAlignment());
2861
2862 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val");
2863 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr));
2864 }
Nate Begeman6c591322008-05-15 07:38:03 +00002865 }
Mike Stump11289f42009-09-09 15:08:12 +00002866
John McCall30e4efd2011-09-13 23:05:03 +00002867 // If this is an alias for a lib function (e.g. __builtin_sin), emit
2868 // the call using the normal call path, but using the unmangled
2869 // version of the function name.
2870 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
2871 return emitLibraryCall(*this, FD, E,
2872 CGM.getBuiltinLibFunction(FD, BuiltinID));
Jim Grosbachd3608f42012-09-21 00:18:27 +00002873
John McCall30e4efd2011-09-13 23:05:03 +00002874 // If this is a predefined lib function (e.g. malloc), emit the call
2875 // using exactly the normal call path.
2876 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
John McCallb92ab1a2016-10-26 23:46:34 +00002877 return emitLibraryCall(*this, FD, E,
2878 cast<llvm::Constant>(EmitScalarExpr(E->getCallee())));
Mike Stump11289f42009-09-09 15:08:12 +00002879
Eric Christopher15709992015-10-15 23:47:11 +00002880 // Check that a call to a target specific builtin has the correct target
2881 // features.
2882 // This is down here to avoid non-target specific builtins, however, if
2883 // generic builtins start to require generic target features then we
2884 // can move this up to the beginning of the function.
Eric Christopherc7e79db2015-11-12 00:44:04 +00002885 checkTargetFeatures(E, FD);
Eric Christopher15709992015-10-15 23:47:11 +00002886
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002887 // See if we have a target specific intrinsic.
Mehdi Amini7186a432016-10-11 19:04:24 +00002888 const char *Name = getContext().BuiltinInfo.getName(BuiltinID);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002889 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
Mehdi Aminib7fb1242016-10-01 01:16:22 +00002890 StringRef Prefix =
2891 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
2892 if (!Prefix.empty()) {
2893 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00002894 // NOTE we dont need to perform a compatibility flag check here since the
2895 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
2896 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
2897 if (IntrinsicID == Intrinsic::not_intrinsic)
Mehdi Aminib7fb1242016-10-01 01:16:22 +00002898 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00002899 }
Mike Stump11289f42009-09-09 15:08:12 +00002900
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002901 if (IntrinsicID != Intrinsic::not_intrinsic) {
2902 SmallVector<Value*, 16> Args;
Mike Stump11289f42009-09-09 15:08:12 +00002903
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002904 // Find out if any arguments are required to be integer constant
2905 // expressions.
2906 unsigned ICEArguments = 0;
2907 ASTContext::GetBuiltinTypeError Error;
2908 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
2909 assert(Error == ASTContext::GE_None && "Should not codegen an error");
2910
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002911 Function *F = CGM.getIntrinsic(IntrinsicID);
Chris Lattner2192fe52011-07-18 04:24:23 +00002912 llvm::FunctionType *FTy = F->getFunctionType();
Mike Stump11289f42009-09-09 15:08:12 +00002913
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002914 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002915 Value *ArgValue;
2916 // If this is a normal argument, just emit it as a scalar.
2917 if ((ICEArguments & (1 << i)) == 0) {
2918 ArgValue = EmitScalarExpr(E->getArg(i));
2919 } else {
Jim Grosbachd3608f42012-09-21 00:18:27 +00002920 // If this is required to be a constant, constant fold it so that we
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002921 // know that the generated intrinsic gets a ConstantInt.
2922 llvm::APSInt Result;
2923 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext());
2924 assert(IsConst && "Constant arg isn't actually constant?");
2925 (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00002926 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result);
Chris Lattner64d7f2a2010-10-02 00:09:12 +00002927 }
Mike Stump11289f42009-09-09 15:08:12 +00002928
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002929 // If the intrinsic arg type is different from the builtin arg type
2930 // we need to do a bit cast.
Chris Lattner2192fe52011-07-18 04:24:23 +00002931 llvm::Type *PTy = FTy->getParamType(i);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002932 if (PTy != ArgValue->getType()) {
2933 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
2934 "Must be able to losslessly bit cast to param");
2935 ArgValue = Builder.CreateBitCast(ArgValue, PTy);
2936 }
Mike Stump11289f42009-09-09 15:08:12 +00002937
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002938 Args.push_back(ArgValue);
2939 }
Mike Stump11289f42009-09-09 15:08:12 +00002940
Jay Foad5bd375a2011-07-15 08:37:34 +00002941 Value *V = Builder.CreateCall(F, Args);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002942 QualType BuiltinRetType = E->getType();
Mike Stump11289f42009-09-09 15:08:12 +00002943
Chris Lattnerece04092012-02-07 00:39:47 +00002944 llvm::Type *RetTy = VoidTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00002945 if (!BuiltinRetType->isVoidType())
Chris Lattnerece04092012-02-07 00:39:47 +00002946 RetTy = ConvertType(BuiltinRetType);
Mike Stump11289f42009-09-09 15:08:12 +00002947
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002948 if (RetTy != V->getType()) {
2949 assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
2950 "Must be able to losslessly bit cast result type");
2951 V = Builder.CreateBitCast(V, RetTy);
2952 }
Mike Stump11289f42009-09-09 15:08:12 +00002953
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002954 return RValue::get(V);
2955 }
Mike Stump11289f42009-09-09 15:08:12 +00002956
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002957 // See if we have a target specific builtin that needs to be lowered.
Daniel Dunbareca513d2008-10-10 00:24:54 +00002958 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002959 return RValue::get(V);
Mike Stump11289f42009-09-09 15:08:12 +00002960
Daniel Dunbara7c8cf62008-08-16 00:56:44 +00002961 ErrorUnsupported(E, "builtin function");
Mike Stump11289f42009-09-09 15:08:12 +00002962
Chris Lattner9a8d1d92008-06-30 18:32:54 +00002963 // Unknown builtin, for now just dump it out and return undef.
John McCall47fb9502013-03-07 21:37:08 +00002964 return GetUndefRValue(E->getType());
Mike Stump11289f42009-09-09 15:08:12 +00002965}
Anders Carlsson895af082007-12-09 23:17:02 +00002966
Artem Belevichb5bc9232015-09-22 17:23:22 +00002967static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
2968 unsigned BuiltinID, const CallExpr *E,
2969 llvm::Triple::ArchType Arch) {
2970 switch (Arch) {
Chris Lattner5cc15e02010-03-03 19:03:45 +00002971 case llvm::Triple::arm:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00002972 case llvm::Triple::armeb:
Chris Lattner5cc15e02010-03-03 19:03:45 +00002973 case llvm::Triple::thumb:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00002974 case llvm::Triple::thumbeb:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002975 return CGF->EmitARMBuiltinExpr(BuiltinID, E);
Tim Northover25e8a672014-05-24 12:51:25 +00002976 case llvm::Triple::aarch64:
2977 case llvm::Triple::aarch64_be:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002978 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002979 case llvm::Triple::x86:
2980 case llvm::Triple::x86_64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002981 return CGF->EmitX86BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002982 case llvm::Triple::ppc:
2983 case llvm::Triple::ppc64:
Bill Schmidt778d3872013-07-26 01:36:11 +00002984 case llvm::Triple::ppc64le:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002985 return CGF->EmitPPCBuiltinExpr(BuiltinID, E);
Matt Arsenault56f008d2014-06-24 20:45:01 +00002986 case llvm::Triple::r600:
Tom Stellardd8e38a32015-01-06 20:34:47 +00002987 case llvm::Triple::amdgcn:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002988 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00002989 case llvm::Triple::systemz:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002990 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00002991 case llvm::Triple::nvptx:
2992 case llvm::Triple::nvptx64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002993 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E);
Dan Gohmanc2853072015-09-03 22:51:53 +00002994 case llvm::Triple::wasm32:
2995 case llvm::Triple::wasm64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00002996 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002997 default:
Craig Topper8a13c412014-05-21 05:09:00 +00002998 return nullptr;
Daniel Dunbar576d90d2009-08-24 09:54:37 +00002999 }
Daniel Dunbareca513d2008-10-10 00:24:54 +00003000}
3001
Artem Belevichb5bc9232015-09-22 17:23:22 +00003002Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
3003 const CallExpr *E) {
3004 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3005 assert(getContext().getAuxTargetInfo() && "Missing aux target info");
3006 return EmitTargetArchBuiltinExpr(
3007 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E,
3008 getContext().getAuxTargetInfo()->getTriple().getArch());
3009 }
3010
3011 return EmitTargetArchBuiltinExpr(this, BuiltinID, E,
3012 getTarget().getTriple().getArch());
3013}
3014
Chris Lattnerece04092012-02-07 00:39:47 +00003015static llvm::VectorType *GetNeonType(CodeGenFunction *CGF,
Jiangning Liu036f16d2013-09-24 02:48:06 +00003016 NeonTypeFlags TypeFlags,
3017 bool V1Ty=false) {
NAKAMURA Takumidabda6b2011-11-08 03:27:04 +00003018 int IsQuad = TypeFlags.isQuad();
3019 switch (TypeFlags.getEltType()) {
Bob Wilson98bc98c2011-11-08 01:16:11 +00003020 case NeonTypeFlags::Int8:
3021 case NeonTypeFlags::Poly8:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003022 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003023 case NeonTypeFlags::Int16:
3024 case NeonTypeFlags::Poly16:
Abderrazek Zaafranif10ca932017-06-20 18:54:57 +00003025 case NeonTypeFlags::Float16:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003026 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003027 case NeonTypeFlags::Int32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003028 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003029 case NeonTypeFlags::Int64:
Kevin Qincaac85e2013-11-14 03:29:16 +00003030 case NeonTypeFlags::Poly64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003031 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad));
Kevin Qinfb79d7f2013-12-10 06:49:01 +00003032 case NeonTypeFlags::Poly128:
3033 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm.
3034 // There is a lot of i128 and f128 API missing.
3035 // so we use v16i8 to represent poly128 and get pattern matched.
3036 return llvm::VectorType::get(CGF->Int8Ty, 16);
Bob Wilson98bc98c2011-11-08 01:16:11 +00003037 case NeonTypeFlags::Float32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003038 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad));
Tim Northover2fe823a2013-08-01 09:23:19 +00003039 case NeonTypeFlags::Float64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003040 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad));
David Blaikief47fa302012-01-17 02:30:50 +00003041 }
Benjamin Kramer9b1dfe82013-09-26 16:36:08 +00003042 llvm_unreachable("Unknown vector element type!");
Nate Begeman5968eb22010-06-07 16:01:56 +00003043}
3044
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003045static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF,
3046 NeonTypeFlags IntTypeFlags) {
3047 int IsQuad = IntTypeFlags.isQuad();
3048 switch (IntTypeFlags.getEltType()) {
3049 case NeonTypeFlags::Int32:
3050 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad));
3051 case NeonTypeFlags::Int64:
3052 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad));
3053 default:
3054 llvm_unreachable("Type can't be converted to floating-point!");
3055 }
3056}
3057
Bob Wilson210f6dd2010-12-07 22:40:02 +00003058Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) {
Craig Topperf2f1a092016-07-08 02:17:35 +00003059 unsigned nElts = V->getType()->getVectorNumElements();
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003060 Value* SV = llvm::ConstantVector::getSplat(nElts, C);
Nate Begeman4a04b462010-06-10 00:17:56 +00003061 return Builder.CreateShuffleVector(V, V, SV, "lane");
3062}
3063
Nate Begemanae6b1d82010-06-08 06:03:01 +00003064Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops,
Bob Wilson482afae2010-12-08 22:37:56 +00003065 const char *name,
Nate Begeman91e1fea2010-06-14 05:21:25 +00003066 unsigned shift, bool rightshift) {
Nate Begemanae6b1d82010-06-08 06:03:01 +00003067 unsigned j = 0;
3068 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3069 ai != ae; ++ai, ++j)
Nate Begeman91e1fea2010-06-14 05:21:25 +00003070 if (shift > 0 && shift == j)
3071 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift);
3072 else
3073 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003074
Jay Foad5bd375a2011-07-15 08:37:34 +00003075 return Builder.CreateCall(F, Ops, name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003076}
3077
Jim Grosbachd3608f42012-09-21 00:18:27 +00003078Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty,
Nate Begeman8ed060b2010-06-11 22:57:12 +00003079 bool neg) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003080 int SV = cast<ConstantInt>(V)->getSExtValue();
Benjamin Kramerc385a802015-07-28 15:40:11 +00003081 return ConstantInt::get(Ty, neg ? -SV : SV);
Nate Begeman8ed060b2010-06-11 22:57:12 +00003082}
3083
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003084// \brief Right-shift a vector by a constant.
3085Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift,
3086 llvm::Type *Ty, bool usgn,
3087 const char *name) {
3088 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
3089
3090 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue();
3091 int EltSize = VTy->getScalarSizeInBits();
3092
3093 Vec = Builder.CreateBitCast(Vec, Ty);
3094
3095 // lshr/ashr are undefined when the shift amount is equal to the vector
3096 // element size.
3097 if (ShiftAmt == EltSize) {
3098 if (usgn) {
3099 // Right-shifting an unsigned value by its size yields 0.
Benjamin Kramerc385a802015-07-28 15:40:11 +00003100 return llvm::ConstantAggregateZero::get(VTy);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003101 } else {
3102 // Right-shifting a signed value by its size is equivalent
3103 // to a shift of size-1.
3104 --ShiftAmt;
3105 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt);
3106 }
3107 }
3108
3109 Shift = EmitNeonShiftVector(Shift, Ty, false);
3110 if (usgn)
3111 return Builder.CreateLShr(Vec, Shift, name);
3112 else
3113 return Builder.CreateAShr(Vec, Shift, name);
3114}
3115
Tim Northover2d837962014-02-21 11:57:20 +00003116enum {
3117 AddRetType = (1 << 0),
3118 Add1ArgType = (1 << 1),
3119 Add2ArgTypes = (1 << 2),
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003120
Tim Northover2d837962014-02-21 11:57:20 +00003121 VectorizeRetType = (1 << 3),
3122 VectorizeArgTypes = (1 << 4),
3123
3124 InventFloatType = (1 << 5),
Tim Northover8fe03d62014-02-21 11:57:24 +00003125 UnsignedAlts = (1 << 6),
Tim Northover2d837962014-02-21 11:57:20 +00003126
Tim Northovera2ee4332014-03-29 15:09:45 +00003127 Use64BitVectors = (1 << 7),
3128 Use128BitVectors = (1 << 8),
3129
Tim Northover2d837962014-02-21 11:57:20 +00003130 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes,
3131 VectorRet = AddRetType | VectorizeRetType,
3132 VectorRetGetArgs01 =
3133 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes,
3134 FpCmpzModifiers =
Tim Northovera0c95eb2014-02-21 12:16:59 +00003135 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003136};
3137
Benjamin Kramere003ca22015-10-28 13:54:16 +00003138namespace {
3139struct NeonIntrinsicInfo {
Ben Craigcd7e9f12015-12-14 21:54:11 +00003140 const char *NameHint;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003141 unsigned BuiltinID;
3142 unsigned LLVMIntrinsic;
Tim Northover8fe03d62014-02-21 11:57:24 +00003143 unsigned AltLLVMIntrinsic;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003144 unsigned TypeModifier;
3145
3146 bool operator<(unsigned RHSBuiltinID) const {
3147 return BuiltinID < RHSBuiltinID;
3148 }
Eric Christophered60b432015-11-11 02:04:08 +00003149 bool operator<(const NeonIntrinsicInfo &TE) const {
3150 return BuiltinID < TE.BuiltinID;
3151 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003152};
Benjamin Kramere003ca22015-10-28 13:54:16 +00003153} // end anonymous namespace
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003154
Tim Northover8fe03d62014-02-21 11:57:24 +00003155#define NEONMAP0(NameBase) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003156 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003157
Tim Northover8fe03d62014-02-21 11:57:24 +00003158#define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003159 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
3160 Intrinsic::LLVMIntrinsic, 0, TypeModifier }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003161
Tim Northover8fe03d62014-02-21 11:57:24 +00003162#define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003163 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
Tim Northover8fe03d62014-02-21 11:57:24 +00003164 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003165 TypeModifier }
Tim Northover8fe03d62014-02-21 11:57:24 +00003166
Craig Topper273dbc62015-10-18 05:29:26 +00003167static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = {
Tim Northover8fe03d62014-02-21 11:57:24 +00003168 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3169 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3170 NEONMAP1(vabs_v, arm_neon_vabs, 0),
3171 NEONMAP1(vabsq_v, arm_neon_vabs, 0),
3172 NEONMAP0(vaddhn_v),
3173 NEONMAP1(vaesdq_v, arm_neon_aesd, 0),
3174 NEONMAP1(vaeseq_v, arm_neon_aese, 0),
3175 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0),
3176 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0),
3177 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType),
3178 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType),
3179 NEONMAP1(vcage_v, arm_neon_vacge, 0),
3180 NEONMAP1(vcageq_v, arm_neon_vacge, 0),
3181 NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
3182 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
3183 NEONMAP1(vcale_v, arm_neon_vacge, 0),
3184 NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
3185 NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
3186 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
3187 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType),
3188 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType),
3189 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3190 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3191 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3192 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003193 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003194 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0),
3195 NEONMAP0(vcvt_f32_v),
3196 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3197 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3198 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3199 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3200 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3201 NEONMAP0(vcvt_s32_v),
3202 NEONMAP0(vcvt_s64_v),
3203 NEONMAP0(vcvt_u32_v),
3204 NEONMAP0(vcvt_u64_v),
3205 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
3206 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
3207 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
3208 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
3209 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
3210 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
3211 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
3212 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
3213 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
3214 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
3215 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
3216 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
3217 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
3218 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
3219 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
3220 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
3221 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
3222 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
3223 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
3224 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
3225 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
3226 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
3227 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
3228 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
3229 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
3230 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
3231 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
3232 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
3233 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
3234 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
3235 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
3236 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
3237 NEONMAP0(vcvtq_f32_v),
3238 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3239 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3240 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3241 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3242 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3243 NEONMAP0(vcvtq_s32_v),
3244 NEONMAP0(vcvtq_s64_v),
3245 NEONMAP0(vcvtq_u32_v),
3246 NEONMAP0(vcvtq_u64_v),
3247 NEONMAP0(vext_v),
3248 NEONMAP0(vextq_v),
3249 NEONMAP0(vfma_v),
3250 NEONMAP0(vfmaq_v),
3251 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3252 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3253 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3254 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3255 NEONMAP0(vld1_dup_v),
3256 NEONMAP1(vld1_v, arm_neon_vld1, 0),
3257 NEONMAP0(vld1q_dup_v),
3258 NEONMAP1(vld1q_v, arm_neon_vld1, 0),
3259 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
3260 NEONMAP1(vld2_v, arm_neon_vld2, 0),
3261 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
3262 NEONMAP1(vld2q_v, arm_neon_vld2, 0),
3263 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
3264 NEONMAP1(vld3_v, arm_neon_vld3, 0),
3265 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
3266 NEONMAP1(vld3q_v, arm_neon_vld3, 0),
3267 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
3268 NEONMAP1(vld4_v, arm_neon_vld4, 0),
3269 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
3270 NEONMAP1(vld4q_v, arm_neon_vld4, 0),
3271 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003272 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType),
3273 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003274 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
3275 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003276 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType),
3277 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003278 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
3279 NEONMAP0(vmovl_v),
3280 NEONMAP0(vmovn_v),
3281 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType),
3282 NEONMAP0(vmull_v),
3283 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType),
3284 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3285 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3286 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType),
3287 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3288 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3289 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType),
3290 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts),
3291 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts),
3292 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType),
3293 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType),
3294 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3295 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3296 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0),
3297 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0),
3298 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType),
3299 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType),
3300 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType),
3301 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts),
3302 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType),
3303 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType),
3304 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType),
3305 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType),
3306 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType),
3307 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3308 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3309 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3310 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
3311 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3312 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003313 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0),
3314 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003315 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3316 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3317 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType),
3318 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3319 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3320 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType),
3321 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType),
3322 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
3323 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003324 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType),
3325 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType),
3326 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType),
3327 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType),
3328 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType),
3329 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType),
3330 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType),
3331 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType),
3332 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType),
3333 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType),
3334 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType),
3335 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003336 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
3337 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003338 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
3339 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
Tim Northover8fe03d62014-02-21 11:57:24 +00003340 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3341 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3342 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType),
3343 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType),
3344 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType),
3345 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0),
3346 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0),
3347 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0),
3348 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0),
3349 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0),
3350 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0),
3351 NEONMAP0(vshl_n_v),
3352 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3353 NEONMAP0(vshll_n_v),
3354 NEONMAP0(vshlq_n_v),
3355 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3356 NEONMAP0(vshr_n_v),
3357 NEONMAP0(vshrn_n_v),
3358 NEONMAP0(vshrq_n_v),
3359 NEONMAP1(vst1_v, arm_neon_vst1, 0),
3360 NEONMAP1(vst1q_v, arm_neon_vst1, 0),
3361 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
3362 NEONMAP1(vst2_v, arm_neon_vst2, 0),
3363 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
3364 NEONMAP1(vst2q_v, arm_neon_vst2, 0),
3365 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
3366 NEONMAP1(vst3_v, arm_neon_vst3, 0),
3367 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
3368 NEONMAP1(vst3q_v, arm_neon_vst3, 0),
3369 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
3370 NEONMAP1(vst4_v, arm_neon_vst4, 0),
3371 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
3372 NEONMAP1(vst4q_v, arm_neon_vst4, 0),
3373 NEONMAP0(vsubhn_v),
3374 NEONMAP0(vtrn_v),
3375 NEONMAP0(vtrnq_v),
3376 NEONMAP0(vtst_v),
3377 NEONMAP0(vtstq_v),
3378 NEONMAP0(vuzp_v),
3379 NEONMAP0(vuzpq_v),
3380 NEONMAP0(vzip_v),
Tim Northovera0c95eb2014-02-21 12:16:59 +00003381 NEONMAP0(vzipq_v)
Tim Northover8fe03d62014-02-21 11:57:24 +00003382};
3383
Craig Topper273dbc62015-10-18 05:29:26 +00003384static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003385 NEONMAP1(vabs_v, aarch64_neon_abs, 0),
3386 NEONMAP1(vabsq_v, aarch64_neon_abs, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003387 NEONMAP0(vaddhn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003388 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0),
3389 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0),
3390 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0),
3391 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0),
3392 NEONMAP1(vcage_v, aarch64_neon_facge, 0),
3393 NEONMAP1(vcageq_v, aarch64_neon_facge, 0),
3394 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0),
3395 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0),
3396 NEONMAP1(vcale_v, aarch64_neon_facge, 0),
3397 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0),
3398 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0),
3399 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0),
3400 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType),
3401 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003402 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3403 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3404 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3405 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003406 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003407 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003408 NEONMAP0(vcvt_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003409 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3410 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3411 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3412 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3413 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3414 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003415 NEONMAP0(vcvtq_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003416 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3417 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3418 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3419 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3420 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3421 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
3422 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003423 NEONMAP0(vext_v),
3424 NEONMAP0(vextq_v),
3425 NEONMAP0(vfma_v),
3426 NEONMAP0(vfmaq_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003427 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3428 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3429 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
3430 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003431 NEONMAP0(vmovl_v),
3432 NEONMAP0(vmovn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003433 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType),
3434 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType),
3435 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType),
3436 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3437 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3438 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType),
3439 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType),
3440 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType),
3441 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3442 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3443 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0),
3444 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0),
3445 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType),
3446 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType),
3447 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType),
3448 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts),
3449 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType),
3450 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType),
3451 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType),
3452 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType),
3453 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType),
3454 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3455 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3456 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts),
3457 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
3458 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts),
3459 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003460 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0),
3461 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003462 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3463 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3464 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType),
3465 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3466 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3467 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType),
3468 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType),
3469 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3470 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3471 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
3472 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003473 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
3474 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
Tim Northover573cbee2014-05-24 12:52:07 +00003475 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3476 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3477 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType),
3478 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType),
3479 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType),
3480 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0),
3481 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0),
3482 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0),
3483 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0),
3484 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0),
3485 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003486 NEONMAP0(vshl_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003487 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003488 NEONMAP0(vshll_n_v),
3489 NEONMAP0(vshlq_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003490 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003491 NEONMAP0(vshr_n_v),
3492 NEONMAP0(vshrn_n_v),
3493 NEONMAP0(vshrq_n_v),
3494 NEONMAP0(vsubhn_v),
3495 NEONMAP0(vtst_v),
3496 NEONMAP0(vtstq_v),
3497};
3498
Craig Topper273dbc62015-10-18 05:29:26 +00003499static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003500 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType),
3501 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType),
3502 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType),
3503 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3504 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3505 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3506 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3507 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3508 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3509 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3510 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3511 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType),
3512 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3513 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType),
3514 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3515 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3516 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3517 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3518 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3519 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3520 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3521 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3522 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3523 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3524 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3525 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3526 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3527 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3528 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3529 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3530 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3531 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3532 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3533 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3534 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3535 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3536 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3537 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3538 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3539 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3540 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3541 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3542 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3543 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3544 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3545 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3546 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3547 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3548 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0),
3549 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3550 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3551 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3552 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3553 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3554 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3555 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3556 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3557 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3558 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3559 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3560 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3561 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3562 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3563 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3564 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3565 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3566 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3567 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3568 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3569 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0),
3570 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType),
3571 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType),
3572 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3573 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3574 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3575 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3576 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3577 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3578 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3579 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3580 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3581 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3582 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3583 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType),
3584 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3585 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType),
3586 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3587 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3588 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType),
3589 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType),
3590 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3591 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3592 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType),
3593 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType),
3594 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors),
3595 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType),
3596 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors),
3597 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0),
3598 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType),
3599 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType),
3600 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3601 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3602 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3603 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3604 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType),
3605 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3606 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3607 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3608 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType),
3609 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3610 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType),
3611 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors),
3612 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType),
3613 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3614 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3615 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType),
3616 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType),
3617 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3618 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3619 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType),
3620 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType),
3621 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType),
3622 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType),
3623 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3624 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3625 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3626 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3627 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType),
3628 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3629 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3630 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3631 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3632 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3633 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3634 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType),
3635 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType),
3636 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3637 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3638 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3639 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3640 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType),
3641 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType),
3642 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType),
3643 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType),
3644 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3645 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3646 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType),
3647 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType),
3648 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType),
3649 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3650 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3651 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3652 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3653 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType),
3654 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3655 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3656 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3657 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3658 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType),
3659 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType),
3660 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3661 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3662 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType),
3663 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType),
3664 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType),
3665 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType),
3666 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType),
3667 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType),
3668 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType),
3669 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType),
3670 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType),
3671 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType),
3672 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType),
3673 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType),
3674 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0),
3675 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0),
3676 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0),
3677 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0),
3678 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType),
3679 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType),
3680 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType),
3681 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType),
3682 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3683 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType),
3684 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3685 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType),
3686 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType),
3687 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType),
3688 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3689 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType),
3690 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3691 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003692};
3693
Tim Northover8fe03d62014-02-21 11:57:24 +00003694#undef NEONMAP0
3695#undef NEONMAP1
3696#undef NEONMAP2
3697
3698static bool NEONSIMDIntrinsicsProvenSorted = false;
Tim Northover8fe03d62014-02-21 11:57:24 +00003699
Tim Northover573cbee2014-05-24 12:52:07 +00003700static bool AArch64SIMDIntrinsicsProvenSorted = false;
3701static bool AArch64SISDIntrinsicsProvenSorted = false;
Tim Northovera2ee4332014-03-29 15:09:45 +00003702
3703
Tim Northover8fe03d62014-02-21 11:57:24 +00003704static const NeonIntrinsicInfo *
Craig Topper00bbdcf2014-06-28 23:22:23 +00003705findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
Tim Northover8fe03d62014-02-21 11:57:24 +00003706 unsigned BuiltinID, bool &MapProvenSorted) {
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003707
3708#ifndef NDEBUG
Tim Northover8fe03d62014-02-21 11:57:24 +00003709 if (!MapProvenSorted) {
Eric Christophered60b432015-11-11 02:04:08 +00003710 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap)));
Tim Northover8fe03d62014-02-21 11:57:24 +00003711 MapProvenSorted = true;
3712 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003713#endif
3714
Tim Northover8fe03d62014-02-21 11:57:24 +00003715 const NeonIntrinsicInfo *Builtin =
3716 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID);
3717
3718 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID)
3719 return Builtin;
3720
Craig Topper8a13c412014-05-21 05:09:00 +00003721 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003722}
3723
3724Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
3725 unsigned Modifier,
3726 llvm::Type *ArgType,
3727 const CallExpr *E) {
Tim Northovera2ee4332014-03-29 15:09:45 +00003728 int VectorSize = 0;
3729 if (Modifier & Use64BitVectors)
3730 VectorSize = 64;
3731 else if (Modifier & Use128BitVectors)
3732 VectorSize = 128;
3733
Tim Northover2d837962014-02-21 11:57:20 +00003734 // Return type.
3735 SmallVector<llvm::Type *, 3> Tys;
3736 if (Modifier & AddRetType) {
David Majnemerced8bdf2015-02-25 17:36:15 +00003737 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northover2d837962014-02-21 11:57:20 +00003738 if (Modifier & VectorizeRetType)
Tim Northovera2ee4332014-03-29 15:09:45 +00003739 Ty = llvm::VectorType::get(
3740 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1);
Tim Northover2d837962014-02-21 11:57:20 +00003741
3742 Tys.push_back(Ty);
3743 }
3744
3745 // Arguments.
Tim Northovera2ee4332014-03-29 15:09:45 +00003746 if (Modifier & VectorizeArgTypes) {
3747 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1;
3748 ArgType = llvm::VectorType::get(ArgType, Elts);
3749 }
Tim Northover2d837962014-02-21 11:57:20 +00003750
3751 if (Modifier & (Add1ArgType | Add2ArgTypes))
3752 Tys.push_back(ArgType);
3753
3754 if (Modifier & Add2ArgTypes)
3755 Tys.push_back(ArgType);
3756
3757 if (Modifier & InventFloatType)
3758 Tys.push_back(FloatTy);
3759
3760 return CGM.getIntrinsic(IntrinsicID, Tys);
3761}
3762
Tim Northovera2ee4332014-03-29 15:09:45 +00003763static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF,
3764 const NeonIntrinsicInfo &SISDInfo,
3765 SmallVectorImpl<Value *> &Ops,
3766 const CallExpr *E) {
Tim Northover0c68faa2014-03-31 15:47:09 +00003767 unsigned BuiltinID = SISDInfo.BuiltinID;
Tim Northovera2ee4332014-03-29 15:09:45 +00003768 unsigned int Int = SISDInfo.LLVMIntrinsic;
3769 unsigned Modifier = SISDInfo.TypeModifier;
3770 const char *s = SISDInfo.NameHint;
3771
Tim Northover0c68faa2014-03-31 15:47:09 +00003772 switch (BuiltinID) {
3773 case NEON::BI__builtin_neon_vcled_s64:
3774 case NEON::BI__builtin_neon_vcled_u64:
3775 case NEON::BI__builtin_neon_vcles_f32:
3776 case NEON::BI__builtin_neon_vcled_f64:
3777 case NEON::BI__builtin_neon_vcltd_s64:
3778 case NEON::BI__builtin_neon_vcltd_u64:
3779 case NEON::BI__builtin_neon_vclts_f32:
3780 case NEON::BI__builtin_neon_vcltd_f64:
3781 case NEON::BI__builtin_neon_vcales_f32:
3782 case NEON::BI__builtin_neon_vcaled_f64:
3783 case NEON::BI__builtin_neon_vcalts_f32:
3784 case NEON::BI__builtin_neon_vcaltd_f64:
3785 // Only one direction of comparisons actually exist, cmle is actually a cmge
3786 // with swapped operands. The table gives us the right intrinsic but we
3787 // still need to do the swap.
3788 std::swap(Ops[0], Ops[1]);
3789 break;
3790 }
3791
Tim Northovera2ee4332014-03-29 15:09:45 +00003792 assert(Int && "Generic code assumes a valid intrinsic");
3793
3794 // Determine the type(s) of this overloaded AArch64 intrinsic.
3795 const Expr *Arg = E->getArg(0);
3796 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType());
3797 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E);
3798
3799 int j = 0;
Michael J. Spencerdd597752014-05-31 00:22:12 +00003800 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00003801 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3802 ai != ae; ++ai, ++j) {
3803 llvm::Type *ArgTy = ai->getType();
3804 if (Ops[j]->getType()->getPrimitiveSizeInBits() ==
3805 ArgTy->getPrimitiveSizeInBits())
3806 continue;
3807
3808 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy());
3809 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate
3810 // it before inserting.
3811 Ops[j] =
3812 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType());
3813 Ops[j] =
3814 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0);
3815 }
3816
3817 Value *Result = CGF.EmitNeonCall(F, Ops, s);
3818 llvm::Type *ResultType = CGF.ConvertType(E->getType());
3819 if (ResultType->getPrimitiveSizeInBits() <
3820 Result->getType()->getPrimitiveSizeInBits())
3821 return CGF.Builder.CreateExtractElement(Result, C0);
3822
3823 return CGF.Builder.CreateBitCast(Result, ResultType, s);
3824}
Tim Northover8fe03d62014-02-21 11:57:24 +00003825
Tim Northover8fe03d62014-02-21 11:57:24 +00003826Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
3827 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic,
3828 const char *NameHint, unsigned Modifier, const CallExpr *E,
John McCall7f416cc2015-09-08 08:05:57 +00003829 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) {
Tim Northover8fe03d62014-02-21 11:57:24 +00003830 // Get the last argument, which specifies the vector type.
3831 llvm::APSInt NeonTypeConst;
3832 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
3833 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00003834 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003835
3836 // Determine the type of this overloaded NEON intrinsic.
3837 NeonTypeFlags Type(NeonTypeConst.getZExtValue());
3838 bool Usgn = Type.isUnsigned();
3839 bool Quad = Type.isQuad();
3840
3841 llvm::VectorType *VTy = GetNeonType(this, Type);
3842 llvm::Type *Ty = VTy;
3843 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00003844 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003845
John McCall7f416cc2015-09-08 08:05:57 +00003846 auto getAlignmentValue32 = [&](Address addr) -> Value* {
3847 return Builder.getInt32(addr.getAlignment().getQuantity());
3848 };
3849
Tim Northover8fe03d62014-02-21 11:57:24 +00003850 unsigned Int = LLVMIntrinsic;
3851 if ((Modifier & UnsignedAlts) && !Usgn)
3852 Int = AltLLVMIntrinsic;
3853
3854 switch (BuiltinID) {
3855 default: break;
3856 case NEON::BI__builtin_neon_vabs_v:
3857 case NEON::BI__builtin_neon_vabsq_v:
3858 if (VTy->getElementType()->isFloatingPointTy())
3859 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs");
3860 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs");
3861 case NEON::BI__builtin_neon_vaddhn_v: {
3862 llvm::VectorType *SrcTy =
3863 llvm::VectorType::getExtendedElementVectorType(VTy);
3864
3865 // %sum = add <4 x i32> %lhs, %rhs
3866 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
3867 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
3868 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn");
3869
3870 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00003871 Constant *ShiftAmt =
3872 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00003873 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn");
3874
3875 // %res = trunc <4 x i32> %high to <4 x i16>
3876 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn");
3877 }
3878 case NEON::BI__builtin_neon_vcale_v:
3879 case NEON::BI__builtin_neon_vcaleq_v:
3880 case NEON::BI__builtin_neon_vcalt_v:
3881 case NEON::BI__builtin_neon_vcaltq_v:
3882 std::swap(Ops[0], Ops[1]);
Galina Kistanova0872d6c2017-06-03 06:30:46 +00003883 LLVM_FALLTHROUGH;
Tim Northover8fe03d62014-02-21 11:57:24 +00003884 case NEON::BI__builtin_neon_vcage_v:
3885 case NEON::BI__builtin_neon_vcageq_v:
3886 case NEON::BI__builtin_neon_vcagt_v:
3887 case NEON::BI__builtin_neon_vcagtq_v: {
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003888 llvm::Type *VecFlt = llvm::VectorType::get(
3889 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy,
3890 VTy->getNumElements());
Tim Northover8fe03d62014-02-21 11:57:24 +00003891 llvm::Type *Tys[] = { VTy, VecFlt };
3892 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
3893 return EmitNeonCall(F, Ops, NameHint);
3894 }
3895 case NEON::BI__builtin_neon_vclz_v:
3896 case NEON::BI__builtin_neon_vclzq_v:
3897 // We generate target-independent intrinsic, which needs a second argument
3898 // for whether or not clz of zero is undefined; on ARM it isn't.
3899 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef()));
3900 break;
3901 case NEON::BI__builtin_neon_vcvt_f32_v:
3902 case NEON::BI__builtin_neon_vcvtq_f32_v:
3903 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
3904 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad));
3905 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
3906 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
3907 case NEON::BI__builtin_neon_vcvt_n_f32_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00003908 case NEON::BI__builtin_neon_vcvt_n_f64_v:
3909 case NEON::BI__builtin_neon_vcvtq_n_f32_v:
3910 case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003911 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty };
Tim Northover8fe03d62014-02-21 11:57:24 +00003912 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
3913 Function *F = CGM.getIntrinsic(Int, Tys);
3914 return EmitNeonCall(F, Ops, "vcvt_n");
3915 }
3916 case NEON::BI__builtin_neon_vcvt_n_s32_v:
3917 case NEON::BI__builtin_neon_vcvt_n_u32_v:
3918 case NEON::BI__builtin_neon_vcvt_n_s64_v:
3919 case NEON::BI__builtin_neon_vcvt_n_u64_v:
3920 case NEON::BI__builtin_neon_vcvtq_n_s32_v:
3921 case NEON::BI__builtin_neon_vcvtq_n_u32_v:
3922 case NEON::BI__builtin_neon_vcvtq_n_s64_v:
3923 case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003924 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00003925 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
3926 return EmitNeonCall(F, Ops, "vcvt_n");
3927 }
3928 case NEON::BI__builtin_neon_vcvt_s32_v:
3929 case NEON::BI__builtin_neon_vcvt_u32_v:
3930 case NEON::BI__builtin_neon_vcvt_s64_v:
3931 case NEON::BI__builtin_neon_vcvt_u64_v:
3932 case NEON::BI__builtin_neon_vcvtq_s32_v:
3933 case NEON::BI__builtin_neon_vcvtq_u32_v:
3934 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003935 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003936 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northover8fe03d62014-02-21 11:57:24 +00003937 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt")
3938 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
3939 }
3940 case NEON::BI__builtin_neon_vcvta_s32_v:
3941 case NEON::BI__builtin_neon_vcvta_s64_v:
3942 case NEON::BI__builtin_neon_vcvta_u32_v:
3943 case NEON::BI__builtin_neon_vcvta_u64_v:
3944 case NEON::BI__builtin_neon_vcvtaq_s32_v:
3945 case NEON::BI__builtin_neon_vcvtaq_s64_v:
3946 case NEON::BI__builtin_neon_vcvtaq_u32_v:
3947 case NEON::BI__builtin_neon_vcvtaq_u64_v:
3948 case NEON::BI__builtin_neon_vcvtn_s32_v:
3949 case NEON::BI__builtin_neon_vcvtn_s64_v:
3950 case NEON::BI__builtin_neon_vcvtn_u32_v:
3951 case NEON::BI__builtin_neon_vcvtn_u64_v:
3952 case NEON::BI__builtin_neon_vcvtnq_s32_v:
3953 case NEON::BI__builtin_neon_vcvtnq_s64_v:
3954 case NEON::BI__builtin_neon_vcvtnq_u32_v:
3955 case NEON::BI__builtin_neon_vcvtnq_u64_v:
3956 case NEON::BI__builtin_neon_vcvtp_s32_v:
3957 case NEON::BI__builtin_neon_vcvtp_s64_v:
3958 case NEON::BI__builtin_neon_vcvtp_u32_v:
3959 case NEON::BI__builtin_neon_vcvtp_u64_v:
3960 case NEON::BI__builtin_neon_vcvtpq_s32_v:
3961 case NEON::BI__builtin_neon_vcvtpq_s64_v:
3962 case NEON::BI__builtin_neon_vcvtpq_u32_v:
3963 case NEON::BI__builtin_neon_vcvtpq_u64_v:
3964 case NEON::BI__builtin_neon_vcvtm_s32_v:
3965 case NEON::BI__builtin_neon_vcvtm_s64_v:
3966 case NEON::BI__builtin_neon_vcvtm_u32_v:
3967 case NEON::BI__builtin_neon_vcvtm_u64_v:
3968 case NEON::BI__builtin_neon_vcvtmq_s32_v:
3969 case NEON::BI__builtin_neon_vcvtmq_s64_v:
3970 case NEON::BI__builtin_neon_vcvtmq_u32_v:
3971 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003972 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00003973 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
3974 }
3975 case NEON::BI__builtin_neon_vext_v:
3976 case NEON::BI__builtin_neon_vextq_v: {
3977 int CV = cast<ConstantInt>(Ops[2])->getSExtValue();
Craig Topperd1cb4ce2016-06-12 00:41:24 +00003978 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00003979 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00003980 Indices.push_back(i+CV);
Tim Northover8fe03d62014-02-21 11:57:24 +00003981
3982 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
3983 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Craig Topper832caf02016-05-29 02:39:30 +00003984 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext");
Tim Northover8fe03d62014-02-21 11:57:24 +00003985 }
3986 case NEON::BI__builtin_neon_vfma_v:
3987 case NEON::BI__builtin_neon_vfmaq_v: {
3988 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
3989 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
3990 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
3991 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
3992
3993 // NEON intrinsic puts accumulator first, unlike the LLVM fma.
David Blaikie43f9bb72015-05-18 22:14:03 +00003994 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northover8fe03d62014-02-21 11:57:24 +00003995 }
3996 case NEON::BI__builtin_neon_vld1_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00003997 case NEON::BI__builtin_neon_vld1q_v: {
3998 llvm::Type *Tys[] = {Ty, Int8PtrTy};
John McCall7f416cc2015-09-08 08:05:57 +00003999 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004000 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1");
4001 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004002 case NEON::BI__builtin_neon_vld2_v:
4003 case NEON::BI__builtin_neon_vld2q_v:
4004 case NEON::BI__builtin_neon_vld3_v:
4005 case NEON::BI__builtin_neon_vld3q_v:
4006 case NEON::BI__builtin_neon_vld4_v:
4007 case NEON::BI__builtin_neon_vld4q_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004008 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4009 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00004010 Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00004011 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004012 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4013 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004014 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004015 }
4016 case NEON::BI__builtin_neon_vld1_dup_v:
4017 case NEON::BI__builtin_neon_vld1q_dup_v: {
4018 Value *V = UndefValue::get(Ty);
4019 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00004020 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty);
4021 LoadInst *Ld = Builder.CreateLoad(PtrOp0);
Michael J. Spencerdd597752014-05-31 00:22:12 +00004022 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northover8fe03d62014-02-21 11:57:24 +00004023 Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
4024 return EmitNeonSplat(Ops[0], CI);
4025 }
4026 case NEON::BI__builtin_neon_vld2_lane_v:
4027 case NEON::BI__builtin_neon_vld2q_lane_v:
4028 case NEON::BI__builtin_neon_vld3_lane_v:
4029 case NEON::BI__builtin_neon_vld3q_lane_v:
4030 case NEON::BI__builtin_neon_vld4_lane_v:
4031 case NEON::BI__builtin_neon_vld4q_lane_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004032 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4033 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
Tim Northover8fe03d62014-02-21 11:57:24 +00004034 for (unsigned I = 2; I < Ops.size() - 1; ++I)
4035 Ops[I] = Builder.CreateBitCast(Ops[I], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004036 Ops.push_back(getAlignmentValue32(PtrOp1));
Tim Northover8fe03d62014-02-21 11:57:24 +00004037 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint);
4038 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4039 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004040 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004041 }
4042 case NEON::BI__builtin_neon_vmovl_v: {
4043 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy);
4044 Ops[0] = Builder.CreateBitCast(Ops[0], DTy);
4045 if (Usgn)
4046 return Builder.CreateZExt(Ops[0], Ty, "vmovl");
4047 return Builder.CreateSExt(Ops[0], Ty, "vmovl");
4048 }
4049 case NEON::BI__builtin_neon_vmovn_v: {
4050 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4051 Ops[0] = Builder.CreateBitCast(Ops[0], QTy);
4052 return Builder.CreateTrunc(Ops[0], Ty, "vmovn");
4053 }
4054 case NEON::BI__builtin_neon_vmull_v:
4055 // FIXME: the integer vmull operations could be emitted in terms of pure
4056 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of
4057 // hoisting the exts outside loops. Until global ISel comes along that can
4058 // see through such movement this leads to bad CodeGen. So we need an
4059 // intrinsic for now.
4060 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
4061 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
4062 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
4063 case NEON::BI__builtin_neon_vpadal_v:
4064 case NEON::BI__builtin_neon_vpadalq_v: {
4065 // The source operand type has twice as many elements of half the size.
4066 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4067 llvm::Type *EltTy =
4068 llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4069 llvm::Type *NarrowTy =
4070 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4071 llvm::Type *Tys[2] = { Ty, NarrowTy };
4072 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint);
4073 }
4074 case NEON::BI__builtin_neon_vpaddl_v:
4075 case NEON::BI__builtin_neon_vpaddlq_v: {
4076 // The source operand type has twice as many elements of half the size.
4077 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4078 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4079 llvm::Type *NarrowTy =
4080 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4081 llvm::Type *Tys[2] = { Ty, NarrowTy };
4082 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl");
4083 }
4084 case NEON::BI__builtin_neon_vqdmlal_v:
4085 case NEON::BI__builtin_neon_vqdmlsl_v: {
4086 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end());
Benjamin Kramerc385a802015-07-28 15:40:11 +00004087 Ops[1] =
4088 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal");
4089 Ops.resize(2);
4090 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004091 }
4092 case NEON::BI__builtin_neon_vqshl_n_v:
4093 case NEON::BI__builtin_neon_vqshlq_n_v:
4094 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n",
4095 1, false);
Yi Kong1083eb52014-07-29 09:25:17 +00004096 case NEON::BI__builtin_neon_vqshlu_n_v:
4097 case NEON::BI__builtin_neon_vqshluq_n_v:
4098 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n",
4099 1, false);
Tim Northover8fe03d62014-02-21 11:57:24 +00004100 case NEON::BI__builtin_neon_vrecpe_v:
4101 case NEON::BI__builtin_neon_vrecpeq_v:
4102 case NEON::BI__builtin_neon_vrsqrte_v:
4103 case NEON::BI__builtin_neon_vrsqrteq_v:
4104 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
4105 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint);
4106
Yi Kong1083eb52014-07-29 09:25:17 +00004107 case NEON::BI__builtin_neon_vrshr_n_v:
4108 case NEON::BI__builtin_neon_vrshrq_n_v:
4109 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n",
4110 1, true);
Tim Northover8fe03d62014-02-21 11:57:24 +00004111 case NEON::BI__builtin_neon_vshl_n_v:
4112 case NEON::BI__builtin_neon_vshlq_n_v:
4113 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
4114 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1],
4115 "vshl_n");
4116 case NEON::BI__builtin_neon_vshll_n_v: {
4117 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy);
4118 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4119 if (Usgn)
4120 Ops[0] = Builder.CreateZExt(Ops[0], VTy);
4121 else
4122 Ops[0] = Builder.CreateSExt(Ops[0], VTy);
4123 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false);
4124 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n");
4125 }
4126 case NEON::BI__builtin_neon_vshrn_n_v: {
4127 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4128 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4129 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false);
4130 if (Usgn)
4131 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]);
4132 else
4133 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]);
4134 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n");
4135 }
4136 case NEON::BI__builtin_neon_vshr_n_v:
4137 case NEON::BI__builtin_neon_vshrq_n_v:
4138 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n");
4139 case NEON::BI__builtin_neon_vst1_v:
4140 case NEON::BI__builtin_neon_vst1q_v:
4141 case NEON::BI__builtin_neon_vst2_v:
4142 case NEON::BI__builtin_neon_vst2q_v:
4143 case NEON::BI__builtin_neon_vst3_v:
4144 case NEON::BI__builtin_neon_vst3q_v:
4145 case NEON::BI__builtin_neon_vst4_v:
4146 case NEON::BI__builtin_neon_vst4q_v:
4147 case NEON::BI__builtin_neon_vst2_lane_v:
4148 case NEON::BI__builtin_neon_vst2q_lane_v:
4149 case NEON::BI__builtin_neon_vst3_lane_v:
4150 case NEON::BI__builtin_neon_vst3q_lane_v:
4151 case NEON::BI__builtin_neon_vst4_lane_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004152 case NEON::BI__builtin_neon_vst4q_lane_v: {
4153 llvm::Type *Tys[] = {Int8PtrTy, Ty};
John McCall7f416cc2015-09-08 08:05:57 +00004154 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004155 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
4156 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004157 case NEON::BI__builtin_neon_vsubhn_v: {
4158 llvm::VectorType *SrcTy =
4159 llvm::VectorType::getExtendedElementVectorType(VTy);
4160
4161 // %sum = add <4 x i32> %lhs, %rhs
4162 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4163 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
4164 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn");
4165
4166 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00004167 Constant *ShiftAmt =
4168 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00004169 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn");
4170
4171 // %res = trunc <4 x i32> %high to <4 x i16>
4172 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn");
4173 }
4174 case NEON::BI__builtin_neon_vtrn_v:
4175 case NEON::BI__builtin_neon_vtrnq_v: {
4176 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4177 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4178 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004179 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004180
4181 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004182 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004183 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004184 Indices.push_back(i+vi);
4185 Indices.push_back(i+e+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004186 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004187 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004188 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00004189 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004190 }
4191 return SV;
4192 }
4193 case NEON::BI__builtin_neon_vtst_v:
4194 case NEON::BI__builtin_neon_vtstq_v: {
4195 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4196 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4197 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
4198 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
4199 ConstantAggregateZero::get(Ty));
4200 return Builder.CreateSExt(Ops[0], Ty, "vtst");
4201 }
4202 case NEON::BI__builtin_neon_vuzp_v:
4203 case NEON::BI__builtin_neon_vuzpq_v: {
4204 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4205 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4206 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004207 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004208
4209 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004210 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004211 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00004212 Indices.push_back(2*i+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004213
David Blaikiefb901c7a2015-04-04 15:12:29 +00004214 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004215 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00004216 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004217 }
4218 return SV;
4219 }
4220 case NEON::BI__builtin_neon_vzip_v:
4221 case NEON::BI__builtin_neon_vzipq_v: {
4222 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4223 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4224 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004225 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004226
4227 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004228 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004229 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004230 Indices.push_back((i + vi*e) >> 1);
4231 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northover8fe03d62014-02-21 11:57:24 +00004232 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004233 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004234 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00004235 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004236 }
4237 return SV;
4238 }
4239 }
4240
4241 assert(Int && "Expected valid intrinsic number");
4242
4243 // Determine the type(s) of this overloaded AArch64 intrinsic.
4244 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E);
4245
4246 Value *Result = EmitNeonCall(F, Ops, NameHint);
4247 llvm::Type *ResultType = ConvertType(E->getType());
4248 // AArch64 intrinsic one-element vector type cast to
4249 // scalar type expected by the builtin
4250 return Builder.CreateBitCast(Result, ResultType, NameHint);
4251}
4252
Kevin Qin1718af62013-11-14 02:45:18 +00004253Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr(
4254 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp,
4255 const CmpInst::Predicate Ip, const Twine &Name) {
Tim Northovera2ee4332014-03-29 15:09:45 +00004256 llvm::Type *OTy = Op->getType();
4257
4258 // FIXME: this is utterly horrific. We should not be looking at previous
4259 // codegen context to find out what needs doing. Unfortunately TableGen
4260 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32
4261 // (etc).
4262 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op))
4263 OTy = BI->getOperand(0)->getType();
4264
Kevin Qin1718af62013-11-14 02:45:18 +00004265 Op = Builder.CreateBitCast(Op, OTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00004266 if (OTy->getScalarType()->isFloatingPointTy()) {
4267 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004268 } else {
Tim Northovera2ee4332014-03-29 15:09:45 +00004269 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004270 }
Hao Liuf96fd372013-12-23 02:44:00 +00004271 return Builder.CreateSExt(Op, Ty, Name);
Kevin Qin1718af62013-11-14 02:45:18 +00004272}
4273
Jiangning Liu18b707c2013-11-14 01:57:55 +00004274static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops,
4275 Value *ExtOp, Value *IndexOp,
4276 llvm::Type *ResTy, unsigned IntID,
4277 const char *Name) {
4278 SmallVector<Value *, 2> TblOps;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004279 if (ExtOp)
4280 TblOps.push_back(ExtOp);
4281
4282 // Build a vector containing sequential number like (0, 1, 2, ..., 15)
4283 SmallVector<uint32_t, 16> Indices;
4284 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType());
4285 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) {
Craig Topper832caf02016-05-29 02:39:30 +00004286 Indices.push_back(2*i);
4287 Indices.push_back(2*i+1);
Jiangning Liu18b707c2013-11-14 01:57:55 +00004288 }
Jiangning Liu18b707c2013-11-14 01:57:55 +00004289
4290 int PairPos = 0, End = Ops.size() - 1;
4291 while (PairPos < End) {
4292 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004293 Ops[PairPos+1], Indices,
4294 Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004295 PairPos += 2;
4296 }
4297
4298 // If there's an odd number of 64-bit lookup table, fill the high 64-bit
4299 // of the 128-bit lookup table with zero.
4300 if (PairPos == End) {
4301 Value *ZeroTbl = ConstantAggregateZero::get(TblTy);
4302 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004303 ZeroTbl, Indices, Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004304 }
4305
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004306 Function *TblF;
4307 TblOps.push_back(IndexOp);
4308 TblF = CGF.CGM.getIntrinsic(IntID, ResTy);
4309
4310 return CGF.EmitNeonCall(TblF, TblOps, Name);
4311}
4312
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004313Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) {
Benjamin Kramerc385a802015-07-28 15:40:11 +00004314 unsigned Value;
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004315 switch (BuiltinID) {
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004316 default:
4317 return nullptr;
Yi Kong4d5e23f2014-07-14 15:20:09 +00004318 case ARM::BI__builtin_arm_nop:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004319 Value = 0;
4320 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004321 case ARM::BI__builtin_arm_yield:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004322 case ARM::BI__yield:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004323 Value = 1;
4324 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004325 case ARM::BI__builtin_arm_wfe:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004326 case ARM::BI__wfe:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004327 Value = 2;
4328 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004329 case ARM::BI__builtin_arm_wfi:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004330 case ARM::BI__wfi:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004331 Value = 3;
4332 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004333 case ARM::BI__builtin_arm_sev:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004334 case ARM::BI__sev:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004335 Value = 4;
4336 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004337 case ARM::BI__builtin_arm_sevl:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004338 case ARM::BI__sevl:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004339 Value = 5;
4340 break;
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004341 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00004342
4343 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint),
4344 llvm::ConstantInt::get(Int32Ty, Value));
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004345}
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004346
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004347// Generates the IR for the read/write special register builtin,
4348// ValueType is the type of the value that is to be written or read,
4349// RegisterType is the type of the register being written to or read from.
4350static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF,
4351 const CallExpr *E,
4352 llvm::Type *RegisterType,
Matt Arsenault64665bc2016-06-28 00:13:17 +00004353 llvm::Type *ValueType,
4354 bool IsRead,
4355 StringRef SysReg = "") {
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004356 // write and register intrinsics only support 32 and 64 bit operations.
4357 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64))
4358 && "Unsupported size for register.");
4359
4360 CodeGen::CGBuilderTy &Builder = CGF.Builder;
4361 CodeGen::CodeGenModule &CGM = CGF.CGM;
4362 LLVMContext &Context = CGM.getLLVMContext();
4363
Matt Arsenault64665bc2016-06-28 00:13:17 +00004364 if (SysReg.empty()) {
4365 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts();
Zachary Turner26dab122016-12-13 17:10:16 +00004366 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString();
Matt Arsenault64665bc2016-06-28 00:13:17 +00004367 }
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004368
4369 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) };
4370 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4371 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4372
4373 llvm::Type *Types[] = { RegisterType };
4374
4375 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32);
4376 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64))
4377 && "Can't fit 64-bit value in 32-bit register");
4378
4379 if (IsRead) {
4380 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
4381 llvm::Value *Call = Builder.CreateCall(F, Metadata);
4382
4383 if (MixedTypes)
4384 // Read into 64 bit register and then truncate result to 32 bit.
4385 return Builder.CreateTrunc(Call, ValueType);
4386
4387 if (ValueType->isPointerTy())
4388 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*).
4389 return Builder.CreateIntToPtr(Call, ValueType);
4390
4391 return Call;
4392 }
4393
4394 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
4395 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1));
4396 if (MixedTypes) {
4397 // Extend 32 bit write value to 64 bit to pass to write.
4398 ArgValue = Builder.CreateZExt(ArgValue, RegisterType);
4399 return Builder.CreateCall(F, { Metadata, ArgValue });
4400 }
4401
4402 if (ValueType->isPointerTy()) {
4403 // Have VoidPtrTy ArgValue but want to return an i32/i64.
4404 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType);
4405 return Builder.CreateCall(F, { Metadata, ArgValue });
4406 }
4407
4408 return Builder.CreateCall(F, { Metadata, ArgValue });
4409}
4410
Bob Wilson63c93142015-06-24 06:05:20 +00004411/// Return true if BuiltinID is an overloaded Neon intrinsic with an extra
4412/// argument that specifies the vector type.
4413static bool HasExtraNeonArgument(unsigned BuiltinID) {
4414 switch (BuiltinID) {
4415 default: break;
4416 case NEON::BI__builtin_neon_vget_lane_i8:
4417 case NEON::BI__builtin_neon_vget_lane_i16:
4418 case NEON::BI__builtin_neon_vget_lane_i32:
4419 case NEON::BI__builtin_neon_vget_lane_i64:
4420 case NEON::BI__builtin_neon_vget_lane_f32:
4421 case NEON::BI__builtin_neon_vgetq_lane_i8:
4422 case NEON::BI__builtin_neon_vgetq_lane_i16:
4423 case NEON::BI__builtin_neon_vgetq_lane_i32:
4424 case NEON::BI__builtin_neon_vgetq_lane_i64:
4425 case NEON::BI__builtin_neon_vgetq_lane_f32:
4426 case NEON::BI__builtin_neon_vset_lane_i8:
4427 case NEON::BI__builtin_neon_vset_lane_i16:
4428 case NEON::BI__builtin_neon_vset_lane_i32:
4429 case NEON::BI__builtin_neon_vset_lane_i64:
4430 case NEON::BI__builtin_neon_vset_lane_f32:
4431 case NEON::BI__builtin_neon_vsetq_lane_i8:
4432 case NEON::BI__builtin_neon_vsetq_lane_i16:
4433 case NEON::BI__builtin_neon_vsetq_lane_i32:
4434 case NEON::BI__builtin_neon_vsetq_lane_i64:
4435 case NEON::BI__builtin_neon_vsetq_lane_f32:
4436 case NEON::BI__builtin_neon_vsha1h_u32:
4437 case NEON::BI__builtin_neon_vsha1cq_u32:
4438 case NEON::BI__builtin_neon_vsha1pq_u32:
4439 case NEON::BI__builtin_neon_vsha1mq_u32:
4440 case ARM::BI_MoveToCoprocessor:
4441 case ARM::BI_MoveToCoprocessor2:
4442 return false;
4443 }
4444 return true;
4445}
4446
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004447Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
4448 const CallExpr *E) {
4449 if (auto Hint = GetValueForARMHint(BuiltinID))
4450 return Hint;
Saleem Abdulrasool38ed6de2014-05-02 06:53:57 +00004451
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004452 if (BuiltinID == ARM::BI__emit) {
4453 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb;
4454 llvm::FunctionType *FTy =
4455 llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
4456
4457 APSInt Value;
4458 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
4459 llvm_unreachable("Sema will ensure that the parameter is constant");
4460
4461 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
4462
4463 llvm::InlineAsm *Emit =
4464 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "",
4465 /*SideEffects=*/true)
4466 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "",
4467 /*SideEffects=*/true);
4468
David Blaikie4ba525b2015-07-14 17:27:39 +00004469 return Builder.CreateCall(Emit);
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004470 }
4471
Yi Kong1d268af2014-08-26 12:48:06 +00004472 if (BuiltinID == ARM::BI__builtin_arm_dbg) {
4473 Value *Option = EmitScalarExpr(E->getArg(0));
4474 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
4475 }
4476
Yi Kong26d104a2014-08-13 19:18:14 +00004477 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
4478 Value *Address = EmitScalarExpr(E->getArg(0));
4479 Value *RW = EmitScalarExpr(E->getArg(1));
4480 Value *IsData = EmitScalarExpr(E->getArg(2));
4481
4482 // Locality is not supported on ARM target
4483 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3);
4484
4485 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00004486 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Kong26d104a2014-08-13 19:18:14 +00004487 }
4488
Jim Grosbach171ec342014-06-16 21:55:58 +00004489 if (BuiltinID == ARM::BI__builtin_arm_rbit) {
Chad Rosierc22abb32017-01-10 18:55:11 +00004490 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
4491 return Builder.CreateCall(
4492 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach171ec342014-06-16 21:55:58 +00004493 }
4494
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004495 if (BuiltinID == ARM::BI__clear_cache) {
Rafael Espindola2219fc52013-05-14 12:45:47 +00004496 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
Rafael Espindolaa54062e2010-06-07 17:26:50 +00004497 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00004498 Value *Ops[2];
Rafael Espindola2219fc52013-05-14 12:45:47 +00004499 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00004500 Ops[i] = EmitScalarExpr(E->getArg(i));
Chris Lattner2192fe52011-07-18 04:24:23 +00004501 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
4502 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004503 StringRef Name = FD->getName();
John McCall882987f2013-02-28 19:01:20 +00004504 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
Chris Lattner5cc15e02010-03-03 19:03:45 +00004505 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004506
Ranjeet Singhca2b3e7b2016-06-17 00:59:41 +00004507 if (BuiltinID == ARM::BI__builtin_arm_mcrr ||
4508 BuiltinID == ARM::BI__builtin_arm_mcrr2) {
4509 Function *F;
4510
4511 switch (BuiltinID) {
4512 default: llvm_unreachable("unexpected builtin");
4513 case ARM::BI__builtin_arm_mcrr:
4514 F = CGM.getIntrinsic(Intrinsic::arm_mcrr);
4515 break;
4516 case ARM::BI__builtin_arm_mcrr2:
4517 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2);
4518 break;
4519 }
4520
4521 // MCRR{2} instruction has 5 operands but
4522 // the intrinsic has 4 because Rt and Rt2
4523 // are represented as a single unsigned 64
4524 // bit integer in the intrinsic definition
4525 // but internally it's represented as 2 32
4526 // bit integers.
4527
4528 Value *Coproc = EmitScalarExpr(E->getArg(0));
4529 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4530 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2));
4531 Value *CRm = EmitScalarExpr(E->getArg(3));
4532
4533 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4534 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty);
4535 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1);
4536 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty);
4537
4538 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm});
4539 }
4540
4541 if (BuiltinID == ARM::BI__builtin_arm_mrrc ||
4542 BuiltinID == ARM::BI__builtin_arm_mrrc2) {
4543 Function *F;
4544
4545 switch (BuiltinID) {
4546 default: llvm_unreachable("unexpected builtin");
4547 case ARM::BI__builtin_arm_mrrc:
4548 F = CGM.getIntrinsic(Intrinsic::arm_mrrc);
4549 break;
4550 case ARM::BI__builtin_arm_mrrc2:
4551 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2);
4552 break;
4553 }
4554
4555 Value *Coproc = EmitScalarExpr(E->getArg(0));
4556 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4557 Value *CRm = EmitScalarExpr(E->getArg(2));
4558 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm});
4559
4560 // Returns an unsigned 64 bit integer, represented
4561 // as two 32 bit integers.
4562
4563 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1);
4564 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0);
4565 Rt = Builder.CreateZExt(Rt, Int64Ty);
4566 Rt1 = Builder.CreateZExt(Rt1, Int64Ty);
4567
4568 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32);
4569 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true);
4570 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1);
4571
4572 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType()));
4573 }
4574
Tim Northover6aacd492013-07-16 09:47:53 +00004575 if (BuiltinID == ARM::BI__builtin_arm_ldrexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004576 ((BuiltinID == ARM::BI__builtin_arm_ldrex ||
4577 BuiltinID == ARM::BI__builtin_arm_ldaex) &&
Saleem Abdulrasoole700cab2014-07-05 20:10:05 +00004578 getContext().getTypeSize(E->getType()) == 64) ||
4579 BuiltinID == ARM::BI__ldrexd) {
4580 Function *F;
4581
4582 switch (BuiltinID) {
4583 default: llvm_unreachable("unexpected builtin");
4584 case ARM::BI__builtin_arm_ldaex:
4585 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd);
4586 break;
4587 case ARM::BI__builtin_arm_ldrexd:
4588 case ARM::BI__builtin_arm_ldrex:
4589 case ARM::BI__ldrexd:
4590 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
4591 break;
4592 }
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004593
4594 Value *LdPtr = EmitScalarExpr(E->getArg(0));
Tim Northover6aacd492013-07-16 09:47:53 +00004595 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
4596 "ldrexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004597
4598 Value *Val0 = Builder.CreateExtractValue(Val, 1);
4599 Value *Val1 = Builder.CreateExtractValue(Val, 0);
4600 Val0 = Builder.CreateZExt(Val0, Int64Ty);
4601 Val1 = Builder.CreateZExt(Val1, Int64Ty);
4602
4603 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32);
4604 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
Tim Northover6aacd492013-07-16 09:47:53 +00004605 Val = Builder.CreateOr(Val, Val1);
4606 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004607 }
4608
Tim Northover3acd6bd2014-07-02 12:56:02 +00004609 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
4610 BuiltinID == ARM::BI__builtin_arm_ldaex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004611 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
4612
4613 QualType Ty = E->getType();
4614 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004615 llvm::Type *PtrTy = llvm::IntegerType::get(
4616 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
4617 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004618
Tim Northover3acd6bd2014-07-02 12:56:02 +00004619 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
4620 ? Intrinsic::arm_ldaex
4621 : Intrinsic::arm_ldrex,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004622 PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004623 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
4624
4625 if (RealResTy->isPointerTy())
4626 return Builder.CreateIntToPtr(Val, RealResTy);
4627 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004628 llvm::Type *IntResTy = llvm::IntegerType::get(
4629 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northover6aacd492013-07-16 09:47:53 +00004630 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
4631 return Builder.CreateBitCast(Val, RealResTy);
4632 }
4633 }
4634
4635 if (BuiltinID == ARM::BI__builtin_arm_strexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004636 ((BuiltinID == ARM::BI__builtin_arm_stlex ||
4637 BuiltinID == ARM::BI__builtin_arm_strex) &&
Tim Northover6aacd492013-07-16 09:47:53 +00004638 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00004639 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4640 ? Intrinsic::arm_stlexd
4641 : Intrinsic::arm_strexd);
Serge Guelton1d993272017-05-09 19:31:30 +00004642 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty);
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004643
John McCall7f416cc2015-09-08 08:05:57 +00004644 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004645 Value *Val = EmitScalarExpr(E->getArg(0));
4646 Builder.CreateStore(Val, Tmp);
4647
John McCall7f416cc2015-09-08 08:05:57 +00004648 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004649 Val = Builder.CreateLoad(LdPtr);
4650
4651 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
4652 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
Tim Northover6aacd492013-07-16 09:47:53 +00004653 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00004654 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004655 }
4656
Tim Northover3acd6bd2014-07-02 12:56:02 +00004657 if (BuiltinID == ARM::BI__builtin_arm_strex ||
4658 BuiltinID == ARM::BI__builtin_arm_stlex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004659 Value *StoreVal = EmitScalarExpr(E->getArg(0));
4660 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
4661
4662 QualType Ty = E->getArg(0)->getType();
4663 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
4664 getContext().getTypeSize(Ty));
4665 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
4666
4667 if (StoreVal->getType()->isPointerTy())
4668 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty);
4669 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004670 llvm::Type *IntTy = llvm::IntegerType::get(
4671 getLLVMContext(),
4672 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
4673 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004674 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
4675 }
4676
Tim Northover3acd6bd2014-07-02 12:56:02 +00004677 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4678 ? Intrinsic::arm_stlex
4679 : Intrinsic::arm_strex,
4680 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00004681 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex");
Tim Northover6aacd492013-07-16 09:47:53 +00004682 }
4683
Martin Storsjoed95a082016-09-30 19:13:46 +00004684 switch (BuiltinID) {
4685 case ARM::BI__iso_volatile_load8:
4686 case ARM::BI__iso_volatile_load16:
4687 case ARM::BI__iso_volatile_load32:
4688 case ARM::BI__iso_volatile_load64: {
4689 Value *Ptr = EmitScalarExpr(E->getArg(0));
4690 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4691 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy);
4692 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4693 LoadSize.getQuantity() * 8);
4694 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4695 llvm::LoadInst *Load =
4696 Builder.CreateAlignedLoad(Ptr, LoadSize);
4697 Load->setVolatile(true);
4698 return Load;
4699 }
4700 case ARM::BI__iso_volatile_store8:
4701 case ARM::BI__iso_volatile_store16:
4702 case ARM::BI__iso_volatile_store32:
4703 case ARM::BI__iso_volatile_store64: {
4704 Value *Ptr = EmitScalarExpr(E->getArg(0));
4705 Value *Value = EmitScalarExpr(E->getArg(1));
4706 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4707 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
4708 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4709 StoreSize.getQuantity() * 8);
4710 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4711 llvm::StoreInst *Store =
4712 Builder.CreateAlignedStore(Value, Ptr,
4713 StoreSize);
4714 Store->setVolatile(true);
4715 return Store;
4716 }
4717 }
4718
Tim Northover6aacd492013-07-16 09:47:53 +00004719 if (BuiltinID == ARM::BI__builtin_arm_clrex) {
4720 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00004721 return Builder.CreateCall(F);
Tim Northover6aacd492013-07-16 09:47:53 +00004722 }
4723
Joey Gouly1e8637b2013-09-18 10:07:09 +00004724 // CRC32
4725 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
4726 switch (BuiltinID) {
4727 case ARM::BI__builtin_arm_crc32b:
4728 CRCIntrinsicID = Intrinsic::arm_crc32b; break;
4729 case ARM::BI__builtin_arm_crc32cb:
4730 CRCIntrinsicID = Intrinsic::arm_crc32cb; break;
4731 case ARM::BI__builtin_arm_crc32h:
4732 CRCIntrinsicID = Intrinsic::arm_crc32h; break;
4733 case ARM::BI__builtin_arm_crc32ch:
4734 CRCIntrinsicID = Intrinsic::arm_crc32ch; break;
4735 case ARM::BI__builtin_arm_crc32w:
4736 case ARM::BI__builtin_arm_crc32d:
4737 CRCIntrinsicID = Intrinsic::arm_crc32w; break;
4738 case ARM::BI__builtin_arm_crc32cw:
4739 case ARM::BI__builtin_arm_crc32cd:
4740 CRCIntrinsicID = Intrinsic::arm_crc32cw; break;
4741 }
4742
4743 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
4744 Value *Arg0 = EmitScalarExpr(E->getArg(0));
4745 Value *Arg1 = EmitScalarExpr(E->getArg(1));
4746
4747 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w
4748 // intrinsics, hence we need different codegen for these cases.
4749 if (BuiltinID == ARM::BI__builtin_arm_crc32d ||
4750 BuiltinID == ARM::BI__builtin_arm_crc32cd) {
4751 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4752 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty);
4753 Value *Arg1b = Builder.CreateLShr(Arg1, C1);
4754 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty);
4755
4756 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004757 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a});
4758 return Builder.CreateCall(F, {Res, Arg1b});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004759 } else {
4760 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty);
4761
4762 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004763 return Builder.CreateCall(F, {Arg0, Arg1});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004764 }
4765 }
4766
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004767 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
4768 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4769 BuiltinID == ARM::BI__builtin_arm_rsrp ||
4770 BuiltinID == ARM::BI__builtin_arm_wsr ||
4771 BuiltinID == ARM::BI__builtin_arm_wsr64 ||
4772 BuiltinID == ARM::BI__builtin_arm_wsrp) {
4773
4774 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr ||
4775 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4776 BuiltinID == ARM::BI__builtin_arm_rsrp;
4777
4778 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp ||
4779 BuiltinID == ARM::BI__builtin_arm_wsrp;
4780
4781 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4782 BuiltinID == ARM::BI__builtin_arm_wsr64;
4783
4784 llvm::Type *ValueType;
4785 llvm::Type *RegisterType;
4786 if (IsPointerBuiltin) {
4787 ValueType = VoidPtrTy;
4788 RegisterType = Int32Ty;
4789 } else if (Is64Bit) {
4790 ValueType = RegisterType = Int64Ty;
4791 } else {
4792 ValueType = RegisterType = Int32Ty;
4793 }
4794
4795 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
4796 }
4797
Ahmed Bougacha94df7302015-06-04 01:43:41 +00004798 // Find out if any arguments are required to be integer constant
4799 // expressions.
4800 unsigned ICEArguments = 0;
4801 ASTContext::GetBuiltinTypeError Error;
4802 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
4803 assert(Error == ASTContext::GE_None && "Should not codegen an error");
4804
John McCall7f416cc2015-09-08 08:05:57 +00004805 auto getAlignmentValue32 = [&](Address addr) -> Value* {
4806 return Builder.getInt32(addr.getAlignment().getQuantity());
4807 };
4808
4809 Address PtrOp0 = Address::invalid();
4810 Address PtrOp1 = Address::invalid();
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004811 SmallVector<Value*, 4> Ops;
Bob Wilson63c93142015-06-24 06:05:20 +00004812 bool HasExtraArg = HasExtraNeonArgument(BuiltinID);
4813 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0);
4814 for (unsigned i = 0, e = NumArgs; i != e; i++) {
Eli Friedmana5dd5682012-08-23 03:10:17 +00004815 if (i == 0) {
4816 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00004817 case NEON::BI__builtin_neon_vld1_v:
4818 case NEON::BI__builtin_neon_vld1q_v:
4819 case NEON::BI__builtin_neon_vld1q_lane_v:
4820 case NEON::BI__builtin_neon_vld1_lane_v:
4821 case NEON::BI__builtin_neon_vld1_dup_v:
4822 case NEON::BI__builtin_neon_vld1q_dup_v:
4823 case NEON::BI__builtin_neon_vst1_v:
4824 case NEON::BI__builtin_neon_vst1q_v:
4825 case NEON::BI__builtin_neon_vst1q_lane_v:
4826 case NEON::BI__builtin_neon_vst1_lane_v:
4827 case NEON::BI__builtin_neon_vst2_v:
4828 case NEON::BI__builtin_neon_vst2q_v:
4829 case NEON::BI__builtin_neon_vst2_lane_v:
4830 case NEON::BI__builtin_neon_vst2q_lane_v:
4831 case NEON::BI__builtin_neon_vst3_v:
4832 case NEON::BI__builtin_neon_vst3q_v:
4833 case NEON::BI__builtin_neon_vst3_lane_v:
4834 case NEON::BI__builtin_neon_vst3q_lane_v:
4835 case NEON::BI__builtin_neon_vst4_v:
4836 case NEON::BI__builtin_neon_vst4q_v:
4837 case NEON::BI__builtin_neon_vst4_lane_v:
4838 case NEON::BI__builtin_neon_vst4q_lane_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00004839 // Get the alignment for the argument in addition to the value;
4840 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00004841 PtrOp0 = EmitPointerWithAlignment(E->getArg(0));
4842 Ops.push_back(PtrOp0.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00004843 continue;
4844 }
4845 }
4846 if (i == 1) {
4847 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00004848 case NEON::BI__builtin_neon_vld2_v:
4849 case NEON::BI__builtin_neon_vld2q_v:
4850 case NEON::BI__builtin_neon_vld3_v:
4851 case NEON::BI__builtin_neon_vld3q_v:
4852 case NEON::BI__builtin_neon_vld4_v:
4853 case NEON::BI__builtin_neon_vld4q_v:
4854 case NEON::BI__builtin_neon_vld2_lane_v:
4855 case NEON::BI__builtin_neon_vld2q_lane_v:
4856 case NEON::BI__builtin_neon_vld3_lane_v:
4857 case NEON::BI__builtin_neon_vld3q_lane_v:
4858 case NEON::BI__builtin_neon_vld4_lane_v:
4859 case NEON::BI__builtin_neon_vld4q_lane_v:
4860 case NEON::BI__builtin_neon_vld2_dup_v:
4861 case NEON::BI__builtin_neon_vld3_dup_v:
4862 case NEON::BI__builtin_neon_vld4_dup_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00004863 // Get the alignment for the argument in addition to the value;
4864 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00004865 PtrOp1 = EmitPointerWithAlignment(E->getArg(1));
4866 Ops.push_back(PtrOp1.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00004867 continue;
4868 }
4869 }
Ahmed Bougacha94df7302015-06-04 01:43:41 +00004870
4871 if ((ICEArguments & (1 << i)) == 0) {
4872 Ops.push_back(EmitScalarExpr(E->getArg(i)));
4873 } else {
4874 // If this is required to be a constant, constant fold it so that we know
4875 // that the generated intrinsic gets a ConstantInt.
4876 llvm::APSInt Result;
4877 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
4878 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
4879 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
4880 }
Eli Friedmana5dd5682012-08-23 03:10:17 +00004881 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004882
Bob Wilson445c24f2011-08-13 05:03:46 +00004883 switch (BuiltinID) {
4884 default: break;
Bob Wilson63c93142015-06-24 06:05:20 +00004885
Tim Northoverc322f832014-01-30 14:47:51 +00004886 case NEON::BI__builtin_neon_vget_lane_i8:
4887 case NEON::BI__builtin_neon_vget_lane_i16:
4888 case NEON::BI__builtin_neon_vget_lane_i32:
4889 case NEON::BI__builtin_neon_vget_lane_i64:
4890 case NEON::BI__builtin_neon_vget_lane_f32:
4891 case NEON::BI__builtin_neon_vgetq_lane_i8:
4892 case NEON::BI__builtin_neon_vgetq_lane_i16:
4893 case NEON::BI__builtin_neon_vgetq_lane_i32:
4894 case NEON::BI__builtin_neon_vgetq_lane_i64:
4895 case NEON::BI__builtin_neon_vgetq_lane_f32:
Bob Wilson63c93142015-06-24 06:05:20 +00004896 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane");
4897
Tim Northoverc322f832014-01-30 14:47:51 +00004898 case NEON::BI__builtin_neon_vset_lane_i8:
4899 case NEON::BI__builtin_neon_vset_lane_i16:
4900 case NEON::BI__builtin_neon_vset_lane_i32:
4901 case NEON::BI__builtin_neon_vset_lane_i64:
4902 case NEON::BI__builtin_neon_vset_lane_f32:
4903 case NEON::BI__builtin_neon_vsetq_lane_i8:
4904 case NEON::BI__builtin_neon_vsetq_lane_i16:
4905 case NEON::BI__builtin_neon_vsetq_lane_i32:
4906 case NEON::BI__builtin_neon_vsetq_lane_i64:
4907 case NEON::BI__builtin_neon_vsetq_lane_f32:
Bob Wilson445c24f2011-08-13 05:03:46 +00004908 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
Tim Northover02e38602014-02-03 17:28:04 +00004909
Tim Northover02e38602014-02-03 17:28:04 +00004910 case NEON::BI__builtin_neon_vsha1h_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004911 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops,
4912 "vsha1h");
4913 case NEON::BI__builtin_neon_vsha1cq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004914 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops,
4915 "vsha1h");
4916 case NEON::BI__builtin_neon_vsha1pq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004917 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops,
4918 "vsha1h");
4919 case NEON::BI__builtin_neon_vsha1mq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00004920 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops,
4921 "vsha1h");
Bob Wilson63c93142015-06-24 06:05:20 +00004922
4923 // The ARM _MoveToCoprocessor builtins put the input register value as
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004924 // the first argument, but the LLVM intrinsic expects it as the third one.
4925 case ARM::BI_MoveToCoprocessor:
4926 case ARM::BI_MoveToCoprocessor2: {
4927 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ?
4928 Intrinsic::arm_mcr : Intrinsic::arm_mcr2);
4929 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0],
4930 Ops[3], Ops[4], Ops[5]});
Bob Wilson63c93142015-06-24 06:05:20 +00004931 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00004932 case ARM::BI_BitScanForward:
4933 case ARM::BI_BitScanForward64:
4934 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
4935 case ARM::BI_BitScanReverse:
4936 case ARM::BI_BitScanReverse64:
4937 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00004938
4939 case ARM::BI_InterlockedAnd64:
4940 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
4941 case ARM::BI_InterlockedExchange64:
4942 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
4943 case ARM::BI_InterlockedExchangeAdd64:
4944 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
4945 case ARM::BI_InterlockedExchangeSub64:
4946 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
4947 case ARM::BI_InterlockedOr64:
4948 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
4949 case ARM::BI_InterlockedXor64:
4950 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
4951 case ARM::BI_InterlockedDecrement64:
4952 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
4953 case ARM::BI_InterlockedIncrement64:
4954 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
Bob Wilson445c24f2011-08-13 05:03:46 +00004955 }
4956
4957 // Get the last argument, which specifies the vector type.
Bob Wilson63c93142015-06-24 06:05:20 +00004958 assert(HasExtraArg);
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004959 llvm::APSInt Result;
4960 const Expr *Arg = E->getArg(E->getNumArgs()-1);
4961 if (!Arg->isIntegerConstantExpr(Result, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00004962 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004963
Nate Begemanf568b072010-08-03 21:32:34 +00004964 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f ||
4965 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) {
4966 // Determine the overloaded type of this builtin.
Chris Lattnera5f58b02011-07-09 17:41:47 +00004967 llvm::Type *Ty;
Nate Begemanf568b072010-08-03 21:32:34 +00004968 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f)
Chris Lattnerece04092012-02-07 00:39:47 +00004969 Ty = FloatTy;
Nate Begemanf568b072010-08-03 21:32:34 +00004970 else
Chris Lattnerece04092012-02-07 00:39:47 +00004971 Ty = DoubleTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00004972
Nate Begemanf568b072010-08-03 21:32:34 +00004973 // Determine whether this is an unsigned conversion or not.
4974 bool usgn = Result.getZExtValue() == 1;
4975 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
4976
4977 // Call the appropriate intrinsic.
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00004978 Function *F = CGM.getIntrinsic(Int, Ty);
Jay Foad5bd375a2011-07-15 08:37:34 +00004979 return Builder.CreateCall(F, Ops, "vcvtr");
Nate Begemanf568b072010-08-03 21:32:34 +00004980 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00004981
Nate Begemanf568b072010-08-03 21:32:34 +00004982 // Determine the type of this overloaded NEON intrinsic.
Bob Wilson98bc98c2011-11-08 01:16:11 +00004983 NeonTypeFlags Type(Result.getZExtValue());
4984 bool usgn = Type.isUnsigned();
Bob Wilson4fa993f2010-12-03 17:10:22 +00004985 bool rightShift = false;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004986
Chris Lattnerece04092012-02-07 00:39:47 +00004987 llvm::VectorType *VTy = GetNeonType(this, Type);
Chris Lattnera5f58b02011-07-09 17:41:47 +00004988 llvm::Type *Ty = VTy;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004989 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00004990 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004991
Tim Northoverac85c342014-01-30 14:47:57 +00004992 // Many NEON builtins have identical semantics and uses in ARM and
4993 // AArch64. Emit these in a single function.
Craig Topper5fc8fc22014-08-27 06:28:36 +00004994 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap);
Tim Northover8fe03d62014-02-21 11:57:24 +00004995 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
4996 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
4997 if (Builtin)
4998 return EmitCommonNeonBuiltinExpr(
4999 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00005000 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1);
Tim Northoverac85c342014-01-30 14:47:57 +00005001
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005002 unsigned Int;
5003 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00005004 default: return nullptr;
Tim Northoverc322f832014-01-30 14:47:51 +00005005 case NEON::BI__builtin_neon_vld1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005006 // Handle 64-bit integer elements as a special case. Use shuffles of
5007 // one-element vectors to avoid poor code for i64 in the backend.
5008 if (VTy->getElementType()->isIntegerTy(64)) {
5009 // Extract the other lane.
5010 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00005011 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue();
Bob Wilson2605fef2012-08-14 17:27:04 +00005012 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane));
5013 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
5014 // Load the value as a one-element vector.
5015 Ty = llvm::VectorType::get(VTy->getElementType(), 1);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005016 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5017 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005018 Value *Align = getAlignmentValue32(PtrOp0);
David Blaikie43f9bb72015-05-18 22:14:03 +00005019 Value *Ld = Builder.CreateCall(F, {Ops[0], Align});
Bob Wilson2605fef2012-08-14 17:27:04 +00005020 // Combine them.
Benjamin Kramerc385a802015-07-28 15:40:11 +00005021 uint32_t Indices[] = {1 - Lane, Lane};
5022 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices);
Bob Wilson2605fef2012-08-14 17:27:04 +00005023 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane");
5024 }
5025 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005026 case NEON::BI__builtin_neon_vld1_lane_v: {
Nate Begemaned48c852010-06-20 23:05:28 +00005027 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Steven Wu0d22f2d2015-09-09 01:37:18 +00005028 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00005029 Value *Ld = Builder.CreateLoad(PtrOp0);
Bob Wilson49708d42012-02-04 23:58:08 +00005030 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
5031 }
Tim Northoverc322f832014-01-30 14:47:51 +00005032 case NEON::BI__builtin_neon_vld2_dup_v:
5033 case NEON::BI__builtin_neon_vld3_dup_v:
5034 case NEON::BI__builtin_neon_vld4_dup_v: {
Bob Wilson0348af62010-12-10 22:54:58 +00005035 // Handle 64-bit elements as a special-case. There is no "dup" needed.
5036 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) {
5037 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005038 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005039 Int = Intrinsic::arm_neon_vld2;
Bob Wilson0348af62010-12-10 22:54:58 +00005040 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005041 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005042 Int = Intrinsic::arm_neon_vld3;
Bob Wilson0348af62010-12-10 22:54:58 +00005043 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005044 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005045 Int = Intrinsic::arm_neon_vld4;
Bob Wilson0348af62010-12-10 22:54:58 +00005046 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005047 default: llvm_unreachable("unknown vld_dup intrinsic?");
Bob Wilson0348af62010-12-10 22:54:58 +00005048 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005049 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5050 Function *F = CGM.getIntrinsic(Int, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005051 llvm::Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00005052 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup");
Bob Wilson0348af62010-12-10 22:54:58 +00005053 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5054 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005055 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Bob Wilson0348af62010-12-10 22:54:58 +00005056 }
Nate Begemaned48c852010-06-20 23:05:28 +00005057 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005058 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005059 Int = Intrinsic::arm_neon_vld2lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005060 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005061 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005062 Int = Intrinsic::arm_neon_vld3lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005063 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005064 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005065 Int = Intrinsic::arm_neon_vld4lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005066 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005067 default: llvm_unreachable("unknown vld_dup intrinsic?");
Nate Begemaned48c852010-06-20 23:05:28 +00005068 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005069 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5070 Function *F = CGM.getIntrinsic(Int, Tys);
Chris Lattner2192fe52011-07-18 04:24:23 +00005071 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType());
Jim Grosbachd3608f42012-09-21 00:18:27 +00005072
Nate Begemaned48c852010-06-20 23:05:28 +00005073 SmallVector<Value*, 6> Args;
5074 Args.push_back(Ops[1]);
5075 Args.append(STy->getNumElements(), UndefValue::get(Ty));
5076
Chris Lattner5e016ae2010-06-27 07:15:29 +00005077 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Nate Begemaned48c852010-06-20 23:05:28 +00005078 Args.push_back(CI);
John McCall7f416cc2015-09-08 08:05:57 +00005079 Args.push_back(getAlignmentValue32(PtrOp1));
Jim Grosbachd3608f42012-09-21 00:18:27 +00005080
Jay Foad5bd375a2011-07-15 08:37:34 +00005081 Ops[1] = Builder.CreateCall(F, Args, "vld_dup");
Nate Begemaned48c852010-06-20 23:05:28 +00005082 // splat lane 0 to all elts in each vector of the result.
5083 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5084 Value *Val = Builder.CreateExtractValue(Ops[1], i);
5085 Value *Elt = Builder.CreateBitCast(Val, Ty);
5086 Elt = EmitNeonSplat(Elt, CI);
5087 Elt = Builder.CreateBitCast(Elt, Val->getType());
5088 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i);
5089 }
5090 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5091 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005092 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begemaned48c852010-06-20 23:05:28 +00005093 }
Tim Northoverc322f832014-01-30 14:47:51 +00005094 case NEON::BI__builtin_neon_vqrshrn_n_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005095 Int =
5096 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005097 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005098 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005099 case NEON::BI__builtin_neon_vqrshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005100 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005101 Ops, "vqrshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005102 case NEON::BI__builtin_neon_vqshrn_n_v:
Nate Begeman91e1fea2010-06-14 05:21:25 +00005103 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005104 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005105 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005106 case NEON::BI__builtin_neon_vqshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005107 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005108 Ops, "vqshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005109 case NEON::BI__builtin_neon_vrecpe_v:
5110 case NEON::BI__builtin_neon_vrecpeq_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005111 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005112 Ops, "vrecpe");
Tim Northoverc322f832014-01-30 14:47:51 +00005113 case NEON::BI__builtin_neon_vrshrn_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005114 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005115 Ops, "vrshrn_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005116 case NEON::BI__builtin_neon_vrsra_n_v:
5117 case NEON::BI__builtin_neon_vrsraq_n_v:
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005118 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
5119 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5120 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true);
5121 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
David Blaikie43f9bb72015-05-18 22:14:03 +00005122 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]});
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005123 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005124 case NEON::BI__builtin_neon_vsri_n_v:
5125 case NEON::BI__builtin_neon_vsriq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005126 rightShift = true;
Galina Kistanova0872d6c2017-06-03 06:30:46 +00005127 LLVM_FALLTHROUGH;
Tim Northoverc322f832014-01-30 14:47:51 +00005128 case NEON::BI__builtin_neon_vsli_n_v:
5129 case NEON::BI__builtin_neon_vsliq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005130 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005131 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005132 Ops, "vsli_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005133 case NEON::BI__builtin_neon_vsra_n_v:
5134 case NEON::BI__builtin_neon_vsraq_n_v:
Nate Begeman8ed060b2010-06-11 22:57:12 +00005135 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00005136 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
Nate Begeman8ed060b2010-06-11 22:57:12 +00005137 return Builder.CreateAdd(Ops[0], Ops[1]);
Tim Northoverc322f832014-01-30 14:47:51 +00005138 case NEON::BI__builtin_neon_vst1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005139 // Handle 64-bit integer elements as a special case. Use a shuffle to get
5140 // a one-element vector and avoid poor code for i64 in the backend.
5141 if (VTy->getElementType()->isIntegerTy(64)) {
5142 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5143 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2]));
5144 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
John McCall7f416cc2015-09-08 08:05:57 +00005145 Ops[2] = getAlignmentValue32(PtrOp0);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005146 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()};
Bob Wilson2605fef2012-08-14 17:27:04 +00005147 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005148 Tys), Ops);
Bob Wilson2605fef2012-08-14 17:27:04 +00005149 }
5150 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005151 case NEON::BI__builtin_neon_vst1_lane_v: {
Nate Begeman8ed060b2010-06-11 22:57:12 +00005152 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5153 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
5154 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00005155 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty));
Bob Wilson49708d42012-02-04 23:58:08 +00005156 return St;
5157 }
Tim Northoverc322f832014-01-30 14:47:51 +00005158 case NEON::BI__builtin_neon_vtbl1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005159 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),
5160 Ops, "vtbl1");
Tim Northoverc322f832014-01-30 14:47:51 +00005161 case NEON::BI__builtin_neon_vtbl2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005162 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2),
5163 Ops, "vtbl2");
Tim Northoverc322f832014-01-30 14:47:51 +00005164 case NEON::BI__builtin_neon_vtbl3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005165 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3),
5166 Ops, "vtbl3");
Tim Northoverc322f832014-01-30 14:47:51 +00005167 case NEON::BI__builtin_neon_vtbl4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005168 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4),
5169 Ops, "vtbl4");
Tim Northoverc322f832014-01-30 14:47:51 +00005170 case NEON::BI__builtin_neon_vtbx1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005171 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1),
5172 Ops, "vtbx1");
Tim Northoverc322f832014-01-30 14:47:51 +00005173 case NEON::BI__builtin_neon_vtbx2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005174 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2),
5175 Ops, "vtbx2");
Tim Northoverc322f832014-01-30 14:47:51 +00005176 case NEON::BI__builtin_neon_vtbx3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005177 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3),
5178 Ops, "vtbx3");
Tim Northoverc322f832014-01-30 14:47:51 +00005179 case NEON::BI__builtin_neon_vtbx4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005180 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4),
5181 Ops, "vtbx4");
Chris Lattner5cc15e02010-03-03 19:03:45 +00005182 }
5183}
5184
Tim Northover573cbee2014-05-24 12:52:07 +00005185static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID,
Tim Northovera2ee4332014-03-29 15:09:45 +00005186 const CallExpr *E,
5187 SmallVectorImpl<Value *> &Ops) {
5188 unsigned int Int = 0;
Craig Topper8a13c412014-05-21 05:09:00 +00005189 const char *s = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005190
Tim Northovera2ee4332014-03-29 15:09:45 +00005191 switch (BuiltinID) {
5192 default:
Craig Topper8a13c412014-05-21 05:09:00 +00005193 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005194 case NEON::BI__builtin_neon_vtbl1_v:
5195 case NEON::BI__builtin_neon_vqtbl1_v:
5196 case NEON::BI__builtin_neon_vqtbl1q_v:
5197 case NEON::BI__builtin_neon_vtbl2_v:
5198 case NEON::BI__builtin_neon_vqtbl2_v:
5199 case NEON::BI__builtin_neon_vqtbl2q_v:
5200 case NEON::BI__builtin_neon_vtbl3_v:
5201 case NEON::BI__builtin_neon_vqtbl3_v:
5202 case NEON::BI__builtin_neon_vqtbl3q_v:
5203 case NEON::BI__builtin_neon_vtbl4_v:
5204 case NEON::BI__builtin_neon_vqtbl4_v:
5205 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005206 break;
5207 case NEON::BI__builtin_neon_vtbx1_v:
5208 case NEON::BI__builtin_neon_vqtbx1_v:
5209 case NEON::BI__builtin_neon_vqtbx1q_v:
5210 case NEON::BI__builtin_neon_vtbx2_v:
5211 case NEON::BI__builtin_neon_vqtbx2_v:
5212 case NEON::BI__builtin_neon_vqtbx2q_v:
5213 case NEON::BI__builtin_neon_vtbx3_v:
5214 case NEON::BI__builtin_neon_vqtbx3_v:
5215 case NEON::BI__builtin_neon_vqtbx3q_v:
5216 case NEON::BI__builtin_neon_vtbx4_v:
5217 case NEON::BI__builtin_neon_vqtbx4_v:
5218 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005219 break;
5220 }
5221
5222 assert(E->getNumArgs() >= 3);
5223
5224 // Get the last argument, which specifies the vector type.
5225 llvm::APSInt Result;
5226 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
5227 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00005228 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005229
5230 // Determine the type of this overloaded NEON intrinsic.
5231 NeonTypeFlags Type(Result.getZExtValue());
Benjamin Kramerc385a802015-07-28 15:40:11 +00005232 llvm::VectorType *Ty = GetNeonType(&CGF, Type);
Tim Northovera2ee4332014-03-29 15:09:45 +00005233 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00005234 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005235
Tim Northovera2ee4332014-03-29 15:09:45 +00005236 CodeGen::CGBuilderTy &Builder = CGF.Builder;
5237
5238 // AArch64 scalar builtins are not overloaded, they do not have an extra
5239 // argument that specifies the vector type, need to handle each case.
Tim Northovera2ee4332014-03-29 15:09:45 +00005240 switch (BuiltinID) {
5241 case NEON::BI__builtin_neon_vtbl1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005242 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr,
5243 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1,
5244 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005245 }
5246 case NEON::BI__builtin_neon_vtbl2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005247 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr,
5248 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1,
5249 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005250 }
5251 case NEON::BI__builtin_neon_vtbl3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005252 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr,
5253 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2,
5254 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005255 }
5256 case NEON::BI__builtin_neon_vtbl4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005257 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr,
5258 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2,
5259 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005260 }
5261 case NEON::BI__builtin_neon_vtbx1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005262 Value *TblRes =
5263 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2],
5264 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005265
Benjamin Kramerc385a802015-07-28 15:40:11 +00005266 llvm::Constant *EightV = ConstantInt::get(Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00005267 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV);
5268 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5269
5270 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5271 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5272 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5273 }
5274 case NEON::BI__builtin_neon_vtbx2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005275 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0],
5276 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1,
5277 "vtbx1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005278 }
5279 case NEON::BI__builtin_neon_vtbx3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005280 Value *TblRes =
5281 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4],
5282 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005283
Benjamin Kramerc385a802015-07-28 15:40:11 +00005284 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24);
Tim Northovera2ee4332014-03-29 15:09:45 +00005285 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4],
5286 TwentyFourV);
5287 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5288
5289 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5290 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5291 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5292 }
5293 case NEON::BI__builtin_neon_vtbx4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005294 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0],
5295 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2,
5296 "vtbx2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005297 }
5298 case NEON::BI__builtin_neon_vqtbl1_v:
5299 case NEON::BI__builtin_neon_vqtbl1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005300 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005301 case NEON::BI__builtin_neon_vqtbl2_v:
5302 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00005303 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005304 case NEON::BI__builtin_neon_vqtbl3_v:
5305 case NEON::BI__builtin_neon_vqtbl3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005306 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005307 case NEON::BI__builtin_neon_vqtbl4_v:
5308 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005309 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005310 case NEON::BI__builtin_neon_vqtbx1_v:
5311 case NEON::BI__builtin_neon_vqtbx1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005312 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005313 case NEON::BI__builtin_neon_vqtbx2_v:
5314 case NEON::BI__builtin_neon_vqtbx2q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005315 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005316 case NEON::BI__builtin_neon_vqtbx3_v:
5317 case NEON::BI__builtin_neon_vqtbx3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005318 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005319 case NEON::BI__builtin_neon_vqtbx4_v:
5320 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005321 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005322 }
5323 }
5324
5325 if (!Int)
Craig Topper8a13c412014-05-21 05:09:00 +00005326 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005327
5328 Function *F = CGF.CGM.getIntrinsic(Int, Ty);
5329 return CGF.EmitNeonCall(F, Ops, s);
5330}
5331
5332Value *CodeGenFunction::vectorWrapScalar16(Value *Op) {
5333 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
5334 Op = Builder.CreateBitCast(Op, Int16Ty);
5335 Value *V = UndefValue::get(VTy);
Michael J. Spencerdd597752014-05-31 00:22:12 +00005336 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00005337 Op = Builder.CreateInsertElement(V, Op, CI);
5338 return Op;
5339}
5340
Tim Northover573cbee2014-05-24 12:52:07 +00005341Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
5342 const CallExpr *E) {
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005343 unsigned HintID = static_cast<unsigned>(-1);
5344 switch (BuiltinID) {
5345 default: break;
Yi Kong4d5e23f2014-07-14 15:20:09 +00005346 case AArch64::BI__builtin_arm_nop:
5347 HintID = 0;
5348 break;
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005349 case AArch64::BI__builtin_arm_yield:
5350 HintID = 1;
5351 break;
5352 case AArch64::BI__builtin_arm_wfe:
5353 HintID = 2;
5354 break;
5355 case AArch64::BI__builtin_arm_wfi:
5356 HintID = 3;
5357 break;
5358 case AArch64::BI__builtin_arm_sev:
5359 HintID = 4;
5360 break;
5361 case AArch64::BI__builtin_arm_sevl:
5362 HintID = 5;
5363 break;
5364 }
5365
5366 if (HintID != static_cast<unsigned>(-1)) {
5367 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint);
5368 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
5369 }
5370
Yi Konga5548432014-08-13 19:18:20 +00005371 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
5372 Value *Address = EmitScalarExpr(E->getArg(0));
5373 Value *RW = EmitScalarExpr(E->getArg(1));
5374 Value *CacheLevel = EmitScalarExpr(E->getArg(2));
5375 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3));
5376 Value *IsData = EmitScalarExpr(E->getArg(4));
5377
5378 Value *Locality = nullptr;
5379 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) {
5380 // Temporal fetch, needs to convert cache level to locality.
5381 Locality = llvm::ConstantInt::get(Int32Ty,
5382 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3);
5383 } else {
5384 // Streaming fetch.
5385 Locality = llvm::ConstantInt::get(Int32Ty, 0);
5386 }
5387
5388 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify
5389 // PLDL3STRM or PLDL2STRM.
5390 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00005391 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Konga5548432014-08-13 19:18:20 +00005392 }
5393
Jim Grosbach79140822014-06-16 21:56:02 +00005394 if (BuiltinID == AArch64::BI__builtin_arm_rbit) {
5395 assert((getContext().getTypeSize(E->getType()) == 32) &&
5396 "rbit of unusual size!");
5397 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5398 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005399 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005400 }
5401 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) {
5402 assert((getContext().getTypeSize(E->getType()) == 64) &&
5403 "rbit of unusual size!");
5404 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5405 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005406 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005407 }
5408
Tim Northover573cbee2014-05-24 12:52:07 +00005409 if (BuiltinID == AArch64::BI__clear_cache) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005410 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
5411 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00005412 Value *Ops[2];
Tim Northovera2ee4332014-03-29 15:09:45 +00005413 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00005414 Ops[i] = EmitScalarExpr(E->getArg(i));
Tim Northovera2ee4332014-03-29 15:09:45 +00005415 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
5416 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
5417 StringRef Name = FD->getName();
5418 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
5419 }
5420
Tim Northover3acd6bd2014-07-02 12:56:02 +00005421 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5422 BuiltinID == AArch64::BI__builtin_arm_ldaex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005423 getContext().getTypeSize(E->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005424 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5425 ? Intrinsic::aarch64_ldaxp
5426 : Intrinsic::aarch64_ldxp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005427
5428 Value *LdPtr = EmitScalarExpr(E->getArg(0));
5429 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
5430 "ldxp");
5431
5432 Value *Val0 = Builder.CreateExtractValue(Val, 1);
5433 Value *Val1 = Builder.CreateExtractValue(Val, 0);
5434 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
5435 Val0 = Builder.CreateZExt(Val0, Int128Ty);
5436 Val1 = Builder.CreateZExt(Val1, Int128Ty);
5437
5438 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
5439 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
5440 Val = Builder.CreateOr(Val, Val1);
5441 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Tim Northover3acd6bd2014-07-02 12:56:02 +00005442 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5443 BuiltinID == AArch64::BI__builtin_arm_ldaex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005444 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
5445
5446 QualType Ty = E->getType();
5447 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005448 llvm::Type *PtrTy = llvm::IntegerType::get(
5449 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
5450 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005451
Tim Northover3acd6bd2014-07-02 12:56:02 +00005452 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5453 ? Intrinsic::aarch64_ldaxr
5454 : Intrinsic::aarch64_ldxr,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005455 PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005456 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
5457
5458 if (RealResTy->isPointerTy())
5459 return Builder.CreateIntToPtr(Val, RealResTy);
5460
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005461 llvm::Type *IntResTy = llvm::IntegerType::get(
5462 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northovera2ee4332014-03-29 15:09:45 +00005463 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
5464 return Builder.CreateBitCast(Val, RealResTy);
5465 }
5466
Tim Northover3acd6bd2014-07-02 12:56:02 +00005467 if ((BuiltinID == AArch64::BI__builtin_arm_strex ||
5468 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005469 getContext().getTypeSize(E->getArg(0)->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005470 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5471 ? Intrinsic::aarch64_stlxp
5472 : Intrinsic::aarch64_stxp);
Serge Guelton1d993272017-05-09 19:31:30 +00005473 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005474
John McCall7f416cc2015-09-08 08:05:57 +00005475 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
5476 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true);
Tim Northovera2ee4332014-03-29 15:09:45 +00005477
John McCall7f416cc2015-09-08 08:05:57 +00005478 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy));
5479 llvm::Value *Val = Builder.CreateLoad(Tmp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005480
5481 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
5482 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
5483 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)),
5484 Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00005485 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp");
5486 }
5487
5488 if (BuiltinID == AArch64::BI__builtin_arm_strex ||
5489 BuiltinID == AArch64::BI__builtin_arm_stlex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005490 Value *StoreVal = EmitScalarExpr(E->getArg(0));
5491 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
5492
5493 QualType Ty = E->getArg(0)->getType();
5494 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
5495 getContext().getTypeSize(Ty));
5496 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
5497
5498 if (StoreVal->getType()->isPointerTy())
5499 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty);
5500 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005501 llvm::Type *IntTy = llvm::IntegerType::get(
5502 getLLVMContext(),
5503 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
5504 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005505 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
5506 }
5507
Tim Northover3acd6bd2014-07-02 12:56:02 +00005508 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5509 ? Intrinsic::aarch64_stlxr
5510 : Intrinsic::aarch64_stxr,
5511 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00005512 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
Tim Northovera2ee4332014-03-29 15:09:45 +00005513 }
5514
Tim Northover573cbee2014-05-24 12:52:07 +00005515 if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
5516 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00005517 return Builder.CreateCall(F);
Tim Northovera2ee4332014-03-29 15:09:45 +00005518 }
5519
5520 // CRC32
5521 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
5522 switch (BuiltinID) {
Tim Northover573cbee2014-05-24 12:52:07 +00005523 case AArch64::BI__builtin_arm_crc32b:
5524 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break;
5525 case AArch64::BI__builtin_arm_crc32cb:
5526 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break;
5527 case AArch64::BI__builtin_arm_crc32h:
5528 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break;
5529 case AArch64::BI__builtin_arm_crc32ch:
5530 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break;
5531 case AArch64::BI__builtin_arm_crc32w:
5532 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break;
5533 case AArch64::BI__builtin_arm_crc32cw:
5534 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break;
5535 case AArch64::BI__builtin_arm_crc32d:
5536 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break;
5537 case AArch64::BI__builtin_arm_crc32cd:
5538 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005539 }
5540
5541 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
5542 Value *Arg0 = EmitScalarExpr(E->getArg(0));
5543 Value *Arg1 = EmitScalarExpr(E->getArg(1));
5544 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
5545
5546 llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
5547 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy);
5548
David Blaikie43f9bb72015-05-18 22:14:03 +00005549 return Builder.CreateCall(F, {Arg0, Arg1});
Tim Northovera2ee4332014-03-29 15:09:45 +00005550 }
5551
Luke Cheeseman59b2d832015-06-15 17:51:01 +00005552 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
5553 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5554 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5555 BuiltinID == AArch64::BI__builtin_arm_wsr ||
5556 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
5557 BuiltinID == AArch64::BI__builtin_arm_wsrp) {
5558
5559 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr ||
5560 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5561 BuiltinID == AArch64::BI__builtin_arm_rsrp;
5562
5563 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5564 BuiltinID == AArch64::BI__builtin_arm_wsrp;
5565
5566 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr &&
5567 BuiltinID != AArch64::BI__builtin_arm_wsr;
5568
5569 llvm::Type *ValueType;
5570 llvm::Type *RegisterType = Int64Ty;
5571 if (IsPointerBuiltin) {
5572 ValueType = VoidPtrTy;
5573 } else if (Is64Bit) {
5574 ValueType = Int64Ty;
5575 } else {
5576 ValueType = Int32Ty;
5577 }
5578
5579 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
5580 }
5581
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005582 // Find out if any arguments are required to be integer constant
5583 // expressions.
5584 unsigned ICEArguments = 0;
5585 ASTContext::GetBuiltinTypeError Error;
5586 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
5587 assert(Error == ASTContext::GE_None && "Should not codegen an error");
5588
Tim Northovera2ee4332014-03-29 15:09:45 +00005589 llvm::SmallVector<Value*, 4> Ops;
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005590 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
5591 if ((ICEArguments & (1 << i)) == 0) {
5592 Ops.push_back(EmitScalarExpr(E->getArg(i)));
5593 } else {
5594 // If this is required to be a constant, constant fold it so that we know
5595 // that the generated intrinsic gets a ConstantInt.
5596 llvm::APSInt Result;
5597 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
5598 assert(IsConst && "Constant arg isn't actually constant?");
5599 (void)IsConst;
5600 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
5601 }
5602 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005603
Craig Topper5fc8fc22014-08-27 06:28:36 +00005604 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
Tim Northovera2ee4332014-03-29 15:09:45 +00005605 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
Tim Northover573cbee2014-05-24 12:52:07 +00005606 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00005607
5608 if (Builtin) {
5609 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1)));
5610 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E);
5611 assert(Result && "SISD intrinsic should have been handled");
5612 return Result;
5613 }
5614
5615 llvm::APSInt Result;
5616 const Expr *Arg = E->getArg(E->getNumArgs()-1);
5617 NeonTypeFlags Type(0);
5618 if (Arg->isIntegerConstantExpr(Result, getContext()))
5619 // Determine the type of this overloaded NEON intrinsic.
5620 Type = NeonTypeFlags(Result.getZExtValue());
5621
5622 bool usgn = Type.isUnsigned();
5623 bool quad = Type.isQuad();
5624
5625 // Handle non-overloaded intrinsics first.
5626 switch (BuiltinID) {
5627 default: break;
Tim Northoverb17f9a42014-04-01 12:23:08 +00005628 case NEON::BI__builtin_neon_vldrq_p128: {
Peter Collingbourneb367c562016-11-28 22:30:21 +00005629 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128);
5630 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005631 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy);
Peter Collingbourneb367c562016-11-28 22:30:21 +00005632 return Builder.CreateAlignedLoad(Int128Ty, Ptr,
5633 CharUnits::fromQuantity(16));
Tim Northoverb17f9a42014-04-01 12:23:08 +00005634 }
5635 case NEON::BI__builtin_neon_vstrq_p128: {
5636 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128);
5637 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy);
John McCall7f416cc2015-09-08 08:05:57 +00005638 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005639 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005640 case NEON::BI__builtin_neon_vcvts_u32_f32:
5641 case NEON::BI__builtin_neon_vcvtd_u64_f64:
5642 usgn = true;
5643 // FALL THROUGH
5644 case NEON::BI__builtin_neon_vcvts_s32_f32:
5645 case NEON::BI__builtin_neon_vcvtd_s64_f64: {
5646 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5647 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5648 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5649 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5650 Ops[0] = Builder.CreateBitCast(Ops[0], FTy);
5651 if (usgn)
5652 return Builder.CreateFPToUI(Ops[0], InTy);
5653 return Builder.CreateFPToSI(Ops[0], InTy);
5654 }
5655 case NEON::BI__builtin_neon_vcvts_f32_u32:
5656 case NEON::BI__builtin_neon_vcvtd_f64_u64:
5657 usgn = true;
5658 // FALL THROUGH
5659 case NEON::BI__builtin_neon_vcvts_f32_s32:
5660 case NEON::BI__builtin_neon_vcvtd_f64_s64: {
5661 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5662 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5663 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5664 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5665 Ops[0] = Builder.CreateBitCast(Ops[0], InTy);
5666 if (usgn)
5667 return Builder.CreateUIToFP(Ops[0], FTy);
5668 return Builder.CreateSIToFP(Ops[0], FTy);
5669 }
5670 case NEON::BI__builtin_neon_vpaddd_s64: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005671 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005672 Value *Vec = EmitScalarExpr(E->getArg(0));
5673 // The vector is v2f64, so make sure it's bitcast to that.
5674 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005675 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5676 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005677 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5678 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5679 // Pairwise addition of a v2f64 into a scalar f64.
5680 return Builder.CreateAdd(Op0, Op1, "vpaddd");
5681 }
5682 case NEON::BI__builtin_neon_vpaddd_f64: {
5683 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005684 llvm::VectorType::get(DoubleTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005685 Value *Vec = EmitScalarExpr(E->getArg(0));
5686 // The vector is v2f64, so make sure it's bitcast to that.
5687 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005688 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5689 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005690 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5691 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5692 // Pairwise addition of a v2f64 into a scalar f64.
5693 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5694 }
5695 case NEON::BI__builtin_neon_vpadds_f32: {
5696 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005697 llvm::VectorType::get(FloatTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005698 Value *Vec = EmitScalarExpr(E->getArg(0));
5699 // The vector is v2f32, so make sure it's bitcast to that.
5700 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005701 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5702 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005703 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5704 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5705 // Pairwise addition of a v2f32 into a scalar f32.
5706 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5707 }
5708 case NEON::BI__builtin_neon_vceqzd_s64:
5709 case NEON::BI__builtin_neon_vceqzd_f64:
5710 case NEON::BI__builtin_neon_vceqzs_f32:
5711 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5712 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005713 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5714 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005715 case NEON::BI__builtin_neon_vcgezd_s64:
5716 case NEON::BI__builtin_neon_vcgezd_f64:
5717 case NEON::BI__builtin_neon_vcgezs_f32:
5718 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5719 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005720 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5721 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005722 case NEON::BI__builtin_neon_vclezd_s64:
5723 case NEON::BI__builtin_neon_vclezd_f64:
5724 case NEON::BI__builtin_neon_vclezs_f32:
5725 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5726 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005727 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5728 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005729 case NEON::BI__builtin_neon_vcgtzd_s64:
5730 case NEON::BI__builtin_neon_vcgtzd_f64:
5731 case NEON::BI__builtin_neon_vcgtzs_f32:
5732 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5733 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005734 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5735 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005736 case NEON::BI__builtin_neon_vcltzd_s64:
5737 case NEON::BI__builtin_neon_vcltzd_f64:
5738 case NEON::BI__builtin_neon_vcltzs_f32:
5739 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5740 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005741 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5742 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005743
5744 case NEON::BI__builtin_neon_vceqzd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00005745 Ops.push_back(EmitScalarExpr(E->getArg(0)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00005746 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5747 Ops[0] =
5748 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty));
5749 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005750 }
5751 case NEON::BI__builtin_neon_vceqd_f64:
5752 case NEON::BI__builtin_neon_vcled_f64:
5753 case NEON::BI__builtin_neon_vcltd_f64:
5754 case NEON::BI__builtin_neon_vcged_f64:
5755 case NEON::BI__builtin_neon_vcgtd_f64: {
5756 llvm::CmpInst::Predicate P;
5757 switch (BuiltinID) {
5758 default: llvm_unreachable("missing builtin ID in switch!");
5759 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break;
5760 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break;
5761 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break;
5762 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break;
5763 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break;
5764 }
5765 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5766 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
5767 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
5768 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5769 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd");
5770 }
5771 case NEON::BI__builtin_neon_vceqs_f32:
5772 case NEON::BI__builtin_neon_vcles_f32:
5773 case NEON::BI__builtin_neon_vclts_f32:
5774 case NEON::BI__builtin_neon_vcges_f32:
5775 case NEON::BI__builtin_neon_vcgts_f32: {
5776 llvm::CmpInst::Predicate P;
5777 switch (BuiltinID) {
5778 default: llvm_unreachable("missing builtin ID in switch!");
5779 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break;
5780 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break;
5781 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break;
5782 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break;
5783 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break;
5784 }
5785 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5786 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
5787 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy);
5788 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5789 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd");
5790 }
5791 case NEON::BI__builtin_neon_vceqd_s64:
5792 case NEON::BI__builtin_neon_vceqd_u64:
5793 case NEON::BI__builtin_neon_vcgtd_s64:
5794 case NEON::BI__builtin_neon_vcgtd_u64:
5795 case NEON::BI__builtin_neon_vcltd_s64:
5796 case NEON::BI__builtin_neon_vcltd_u64:
5797 case NEON::BI__builtin_neon_vcged_u64:
5798 case NEON::BI__builtin_neon_vcged_s64:
5799 case NEON::BI__builtin_neon_vcled_u64:
5800 case NEON::BI__builtin_neon_vcled_s64: {
5801 llvm::CmpInst::Predicate P;
5802 switch (BuiltinID) {
5803 default: llvm_unreachable("missing builtin ID in switch!");
5804 case NEON::BI__builtin_neon_vceqd_s64:
5805 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break;
5806 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break;
5807 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break;
5808 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break;
5809 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break;
5810 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break;
5811 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break;
5812 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break;
5813 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break;
5814 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005815 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Tim Northover0c68faa2014-03-31 15:47:09 +00005816 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5817 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005818 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]);
Tim Northover0c68faa2014-03-31 15:47:09 +00005819 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005820 }
5821 case NEON::BI__builtin_neon_vtstd_s64:
5822 case NEON::BI__builtin_neon_vtstd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00005823 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00005824 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5825 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005826 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
5827 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
Benjamin Kramerc385a802015-07-28 15:40:11 +00005828 llvm::Constant::getNullValue(Int64Ty));
5829 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005830 }
5831 case NEON::BI__builtin_neon_vset_lane_i8:
5832 case NEON::BI__builtin_neon_vset_lane_i16:
5833 case NEON::BI__builtin_neon_vset_lane_i32:
5834 case NEON::BI__builtin_neon_vset_lane_i64:
5835 case NEON::BI__builtin_neon_vset_lane_f32:
5836 case NEON::BI__builtin_neon_vsetq_lane_i8:
5837 case NEON::BI__builtin_neon_vsetq_lane_i16:
5838 case NEON::BI__builtin_neon_vsetq_lane_i32:
5839 case NEON::BI__builtin_neon_vsetq_lane_i64:
5840 case NEON::BI__builtin_neon_vsetq_lane_f32:
5841 Ops.push_back(EmitScalarExpr(E->getArg(2)));
5842 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
5843 case NEON::BI__builtin_neon_vset_lane_f64:
5844 // The vector type needs a cast for the v1f64 variant.
5845 Ops[1] = Builder.CreateBitCast(Ops[1],
5846 llvm::VectorType::get(DoubleTy, 1));
5847 Ops.push_back(EmitScalarExpr(E->getArg(2)));
5848 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
5849 case NEON::BI__builtin_neon_vsetq_lane_f64:
5850 // The vector type needs a cast for the v2f64 variant.
5851 Ops[1] = Builder.CreateBitCast(Ops[1],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005852 llvm::VectorType::get(DoubleTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005853 Ops.push_back(EmitScalarExpr(E->getArg(2)));
5854 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
5855
5856 case NEON::BI__builtin_neon_vget_lane_i8:
5857 case NEON::BI__builtin_neon_vdupb_lane_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005858 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00005859 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5860 "vget_lane");
5861 case NEON::BI__builtin_neon_vgetq_lane_i8:
5862 case NEON::BI__builtin_neon_vdupb_laneq_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005863 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16));
Tim Northovera2ee4332014-03-29 15:09:45 +00005864 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5865 "vgetq_lane");
5866 case NEON::BI__builtin_neon_vget_lane_i16:
5867 case NEON::BI__builtin_neon_vduph_lane_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005868 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00005869 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5870 "vget_lane");
5871 case NEON::BI__builtin_neon_vgetq_lane_i16:
5872 case NEON::BI__builtin_neon_vduph_laneq_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005873 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00005874 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5875 "vgetq_lane");
5876 case NEON::BI__builtin_neon_vget_lane_i32:
5877 case NEON::BI__builtin_neon_vdups_lane_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005878 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005879 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5880 "vget_lane");
5881 case NEON::BI__builtin_neon_vdups_lane_f32:
5882 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005883 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005884 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5885 "vdups_lane");
5886 case NEON::BI__builtin_neon_vgetq_lane_i32:
5887 case NEON::BI__builtin_neon_vdups_laneq_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005888 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00005889 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5890 "vgetq_lane");
5891 case NEON::BI__builtin_neon_vget_lane_i64:
5892 case NEON::BI__builtin_neon_vdupd_lane_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005893 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00005894 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5895 "vget_lane");
5896 case NEON::BI__builtin_neon_vdupd_lane_f64:
5897 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005898 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00005899 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5900 "vdupd_lane");
5901 case NEON::BI__builtin_neon_vgetq_lane_i64:
5902 case NEON::BI__builtin_neon_vdupd_laneq_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00005903 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005904 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5905 "vgetq_lane");
5906 case NEON::BI__builtin_neon_vget_lane_f32:
5907 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005908 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00005909 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5910 "vget_lane");
5911 case NEON::BI__builtin_neon_vget_lane_f64:
5912 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005913 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00005914 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5915 "vget_lane");
5916 case NEON::BI__builtin_neon_vgetq_lane_f32:
5917 case NEON::BI__builtin_neon_vdups_laneq_f32:
5918 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005919 llvm::VectorType::get(FloatTy, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00005920 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
5921 "vgetq_lane");
5922 case NEON::BI__builtin_neon_vgetq_lane_f64:
5923 case NEON::BI__builtin_neon_vdupd_laneq_f64:
5924 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005925 llvm::VectorType::get(DoubleTy, 2));
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_vaddd_s64:
5929 case NEON::BI__builtin_neon_vaddd_u64:
5930 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd");
5931 case NEON::BI__builtin_neon_vsubd_s64:
5932 case NEON::BI__builtin_neon_vsubd_u64:
5933 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd");
5934 case NEON::BI__builtin_neon_vqdmlalh_s16:
5935 case NEON::BI__builtin_neon_vqdmlslh_s16: {
5936 SmallVector<Value *, 2> ProductOps;
5937 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
5938 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2))));
5939 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00005940 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00005941 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005942 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00005943 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
5944
5945 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
Tim Northover573cbee2014-05-24 12:52:07 +00005946 ? Intrinsic::aarch64_neon_sqadd
5947 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00005948 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl");
5949 }
5950 case NEON::BI__builtin_neon_vqshlud_n_s64: {
5951 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5952 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Tim Northover573cbee2014-05-24 12:52:07 +00005953 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty),
Hao Liua19a2e22014-04-28 07:36:12 +00005954 Ops, "vqshlu_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00005955 }
5956 case NEON::BI__builtin_neon_vqshld_n_u64:
5957 case NEON::BI__builtin_neon_vqshld_n_s64: {
5958 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00005959 ? Intrinsic::aarch64_neon_uqshl
5960 : Intrinsic::aarch64_neon_sqshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00005961 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5962 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Hao Liua19a2e22014-04-28 07:36:12 +00005963 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00005964 }
5965 case NEON::BI__builtin_neon_vrshrd_n_u64:
5966 case NEON::BI__builtin_neon_vrshrd_n_s64: {
5967 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00005968 ? Intrinsic::aarch64_neon_urshl
5969 : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00005970 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Hao Liua19a2e22014-04-28 07:36:12 +00005971 int SV = cast<ConstantInt>(Ops[1])->getSExtValue();
5972 Ops[1] = ConstantInt::get(Int64Ty, -SV);
5973 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00005974 }
5975 case NEON::BI__builtin_neon_vrsrad_n_u64:
5976 case NEON::BI__builtin_neon_vrsrad_n_s64: {
5977 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00005978 ? Intrinsic::aarch64_neon_urshl
5979 : Intrinsic::aarch64_neon_srshl;
Tim Northover0c68faa2014-03-31 15:47:09 +00005980 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
5981 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2))));
David Blaikie43f9bb72015-05-18 22:14:03 +00005982 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty),
5983 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)});
Tim Northover0c68faa2014-03-31 15:47:09 +00005984 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00005985 }
5986 case NEON::BI__builtin_neon_vshld_n_s64:
5987 case NEON::BI__builtin_neon_vshld_n_u64: {
5988 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
5989 return Builder.CreateShl(
Hao Liu9f9492b2014-05-14 08:59:30 +00005990 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00005991 }
5992 case NEON::BI__builtin_neon_vshrd_n_s64: {
5993 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
5994 return Builder.CreateAShr(
5995 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
5996 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00005997 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00005998 }
5999 case NEON::BI__builtin_neon_vshrd_n_u64: {
6000 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006001 uint64_t ShiftAmt = Amt->getZExtValue();
6002 // Right-shifting an unsigned value by its size yields 0.
6003 if (ShiftAmt == 64)
6004 return ConstantInt::get(Int64Ty, 0);
6005 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt),
6006 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006007 }
6008 case NEON::BI__builtin_neon_vsrad_n_s64: {
6009 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
6010 Ops[1] = Builder.CreateAShr(
6011 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
6012 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00006013 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006014 return Builder.CreateAdd(Ops[0], Ops[1]);
6015 }
6016 case NEON::BI__builtin_neon_vsrad_n_u64: {
6017 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006018 uint64_t ShiftAmt = Amt->getZExtValue();
6019 // Right-shifting an unsigned value by its size yields 0.
6020 // As Op + 0 = Op, return Ops[0] directly.
6021 if (ShiftAmt == 64)
6022 return Ops[0];
6023 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt),
6024 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006025 return Builder.CreateAdd(Ops[0], Ops[1]);
6026 }
6027 case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
6028 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
6029 case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
6030 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
6031 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6032 "lane");
6033 SmallVector<Value *, 2> ProductOps;
6034 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
6035 ProductOps.push_back(vectorWrapScalar16(Ops[2]));
6036 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00006037 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006038 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00006039 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006040 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
6041 Ops.pop_back();
6042
6043 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
6044 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
Tim Northover573cbee2014-05-24 12:52:07 +00006045 ? Intrinsic::aarch64_neon_sqadd
6046 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006047 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl");
6048 }
6049 case NEON::BI__builtin_neon_vqdmlals_s32:
6050 case NEON::BI__builtin_neon_vqdmlsls_s32: {
6051 SmallVector<Value *, 2> ProductOps;
6052 ProductOps.push_back(Ops[1]);
6053 ProductOps.push_back(EmitScalarExpr(E->getArg(2)));
6054 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006055 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006056 ProductOps, "vqdmlXl");
6057
6058 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
Tim Northover573cbee2014-05-24 12:52:07 +00006059 ? Intrinsic::aarch64_neon_sqadd
6060 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006061 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl");
6062 }
6063 case NEON::BI__builtin_neon_vqdmlals_lane_s32:
6064 case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
6065 case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
6066 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
6067 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6068 "lane");
6069 SmallVector<Value *, 2> ProductOps;
6070 ProductOps.push_back(Ops[1]);
6071 ProductOps.push_back(Ops[2]);
6072 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006073 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006074 ProductOps, "vqdmlXl");
6075 Ops.pop_back();
6076
6077 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
6078 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
Tim Northover573cbee2014-05-24 12:52:07 +00006079 ? Intrinsic::aarch64_neon_sqadd
6080 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006081 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl");
6082 }
6083 }
6084
6085 llvm::VectorType *VTy = GetNeonType(this, Type);
6086 llvm::Type *Ty = VTy;
6087 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00006088 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006089
Tim Northover573cbee2014-05-24 12:52:07 +00006090 // Not all intrinsics handled by the common case work for AArch64 yet, so only
Tim Northovera2ee4332014-03-29 15:09:45 +00006091 // defer to common code if it's been added to our special map.
Tim Northover573cbee2014-05-24 12:52:07 +00006092 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID,
6093 AArch64SIMDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00006094
6095 if (Builtin)
6096 return EmitCommonNeonBuiltinExpr(
6097 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00006098 Builtin->NameHint, Builtin->TypeModifier, E, Ops,
6099 /*never use addresses*/ Address::invalid(), Address::invalid());
Tim Northovera2ee4332014-03-29 15:09:45 +00006100
Tim Northover573cbee2014-05-24 12:52:07 +00006101 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops))
Tim Northovera2ee4332014-03-29 15:09:45 +00006102 return V;
6103
6104 unsigned Int;
6105 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00006106 default: return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006107 case NEON::BI__builtin_neon_vbsl_v:
6108 case NEON::BI__builtin_neon_vbslq_v: {
6109 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
6110 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl");
6111 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl");
6112 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl");
6113
6114 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl");
6115 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl");
6116 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl");
6117 return Builder.CreateBitCast(Ops[0], Ty);
6118 }
6119 case NEON::BI__builtin_neon_vfma_lane_v:
6120 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types
6121 // The ARM builtins (and instructions) have the addend as the first
6122 // operand, but the 'fma' intrinsics have it last. Swap it around here.
6123 Value *Addend = Ops[0];
6124 Value *Multiplicand = Ops[1];
6125 Value *LaneSource = Ops[2];
6126 Ops[0] = Multiplicand;
6127 Ops[1] = LaneSource;
6128 Ops[2] = Addend;
6129
6130 // Now adjust things to handle the lane access.
6131 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ?
6132 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) :
6133 VTy;
6134 llvm::Constant *cst = cast<Constant>(Ops[3]);
6135 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst);
6136 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy);
6137 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane");
6138
6139 Ops.pop_back();
6140 Int = Intrinsic::fma;
6141 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla");
6142 }
6143 case NEON::BI__builtin_neon_vfma_laneq_v: {
6144 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
6145 // v1f64 fma should be mapped to Neon scalar f64 fma
6146 if (VTy && VTy->getElementType() == DoubleTy) {
6147 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6148 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
6149 llvm::Type *VTy = GetNeonType(this,
6150 NeonTypeFlags(NeonTypeFlags::Float64, false, true));
6151 Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
6152 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
6153 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00006154 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006155 return Builder.CreateBitCast(Result, Ty);
6156 }
6157 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6158 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6159 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6160
6161 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(),
6162 VTy->getNumElements() * 2);
6163 Ops[2] = Builder.CreateBitCast(Ops[2], STy);
6164 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(),
6165 cast<ConstantInt>(Ops[3]));
6166 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane");
6167
David Blaikie43f9bb72015-05-18 22:14:03 +00006168 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006169 }
6170 case NEON::BI__builtin_neon_vfmaq_laneq_v: {
6171 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6172 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6173 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6174
6175 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
6176 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3]));
David Blaikie43f9bb72015-05-18 22:14:03 +00006177 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006178 }
6179 case NEON::BI__builtin_neon_vfmas_lane_f32:
6180 case NEON::BI__builtin_neon_vfmas_laneq_f32:
6181 case NEON::BI__builtin_neon_vfmad_lane_f64:
6182 case NEON::BI__builtin_neon_vfmad_laneq_f64: {
6183 Ops.push_back(EmitScalarExpr(E->getArg(3)));
David Majnemerced8bdf2015-02-25 17:36:15 +00006184 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northovera2ee4332014-03-29 15:09:45 +00006185 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6186 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
David Blaikie43f9bb72015-05-18 22:14:03 +00006187 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006188 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006189 case NEON::BI__builtin_neon_vmull_v:
6190 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006191 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
6192 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull;
Tim Northovera2ee4332014-03-29 15:09:45 +00006193 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
6194 case NEON::BI__builtin_neon_vmax_v:
6195 case NEON::BI__builtin_neon_vmaxq_v:
6196 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006197 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax;
6198 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax;
Tim Northovera2ee4332014-03-29 15:09:45 +00006199 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax");
6200 case NEON::BI__builtin_neon_vmin_v:
6201 case NEON::BI__builtin_neon_vminq_v:
6202 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006203 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin;
6204 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin;
Tim Northovera2ee4332014-03-29 15:09:45 +00006205 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin");
6206 case NEON::BI__builtin_neon_vabd_v:
6207 case NEON::BI__builtin_neon_vabdq_v:
6208 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006209 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
6210 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd;
Tim Northovera2ee4332014-03-29 15:09:45 +00006211 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd");
6212 case NEON::BI__builtin_neon_vpadal_v:
6213 case NEON::BI__builtin_neon_vpadalq_v: {
6214 unsigned ArgElts = VTy->getNumElements();
6215 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType());
6216 unsigned BitWidth = EltTy->getBitWidth();
6217 llvm::Type *ArgTy = llvm::VectorType::get(
6218 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts);
6219 llvm::Type* Tys[2] = { VTy, ArgTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006220 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006221 SmallVector<llvm::Value*, 1> TmpOps;
6222 TmpOps.push_back(Ops[1]);
6223 Function *F = CGM.getIntrinsic(Int, Tys);
6224 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal");
6225 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType());
6226 return Builder.CreateAdd(tmp, addend);
6227 }
6228 case NEON::BI__builtin_neon_vpmin_v:
6229 case NEON::BI__builtin_neon_vpminq_v:
6230 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006231 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
6232 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006233 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin");
6234 case NEON::BI__builtin_neon_vpmax_v:
6235 case NEON::BI__builtin_neon_vpmaxq_v:
6236 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006237 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
6238 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006239 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax");
6240 case NEON::BI__builtin_neon_vminnm_v:
6241 case NEON::BI__builtin_neon_vminnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006242 Int = Intrinsic::aarch64_neon_fminnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006243 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm");
6244 case NEON::BI__builtin_neon_vmaxnm_v:
6245 case NEON::BI__builtin_neon_vmaxnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006246 Int = Intrinsic::aarch64_neon_fmaxnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006247 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm");
6248 case NEON::BI__builtin_neon_vrecpss_f32: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006249 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006250 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006251 Ops, "vrecps");
6252 }
6253 case NEON::BI__builtin_neon_vrecpsd_f64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006254 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006255 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006256 Ops, "vrecps");
6257 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006258 case NEON::BI__builtin_neon_vqshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006259 Int = Intrinsic::aarch64_neon_sqshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006260 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n");
6261 case NEON::BI__builtin_neon_vqrshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006262 Int = Intrinsic::aarch64_neon_sqrshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006263 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n");
6264 case NEON::BI__builtin_neon_vqshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006265 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006266 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n");
6267 case NEON::BI__builtin_neon_vrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006268 Int = Intrinsic::aarch64_neon_rshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006269 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n");
6270 case NEON::BI__builtin_neon_vqrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006271 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006272 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n");
6273 case NEON::BI__builtin_neon_vrnda_v:
6274 case NEON::BI__builtin_neon_vrndaq_v: {
6275 Int = Intrinsic::round;
6276 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda");
6277 }
6278 case NEON::BI__builtin_neon_vrndi_v:
6279 case NEON::BI__builtin_neon_vrndiq_v: {
6280 Int = Intrinsic::nearbyint;
6281 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi");
6282 }
6283 case NEON::BI__builtin_neon_vrndm_v:
6284 case NEON::BI__builtin_neon_vrndmq_v: {
6285 Int = Intrinsic::floor;
6286 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm");
6287 }
6288 case NEON::BI__builtin_neon_vrndn_v:
6289 case NEON::BI__builtin_neon_vrndnq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006290 Int = Intrinsic::aarch64_neon_frintn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006291 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn");
6292 }
6293 case NEON::BI__builtin_neon_vrndp_v:
6294 case NEON::BI__builtin_neon_vrndpq_v: {
6295 Int = Intrinsic::ceil;
6296 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp");
6297 }
6298 case NEON::BI__builtin_neon_vrndx_v:
6299 case NEON::BI__builtin_neon_vrndxq_v: {
6300 Int = Intrinsic::rint;
6301 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx");
6302 }
6303 case NEON::BI__builtin_neon_vrnd_v:
6304 case NEON::BI__builtin_neon_vrndq_v: {
6305 Int = Intrinsic::trunc;
6306 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz");
6307 }
6308 case NEON::BI__builtin_neon_vceqz_v:
6309 case NEON::BI__builtin_neon_vceqzq_v:
6310 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ,
6311 ICmpInst::ICMP_EQ, "vceqz");
6312 case NEON::BI__builtin_neon_vcgez_v:
6313 case NEON::BI__builtin_neon_vcgezq_v:
6314 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE,
6315 ICmpInst::ICMP_SGE, "vcgez");
6316 case NEON::BI__builtin_neon_vclez_v:
6317 case NEON::BI__builtin_neon_vclezq_v:
6318 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE,
6319 ICmpInst::ICMP_SLE, "vclez");
6320 case NEON::BI__builtin_neon_vcgtz_v:
6321 case NEON::BI__builtin_neon_vcgtzq_v:
6322 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT,
6323 ICmpInst::ICMP_SGT, "vcgtz");
6324 case NEON::BI__builtin_neon_vcltz_v:
6325 case NEON::BI__builtin_neon_vcltzq_v:
6326 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT,
6327 ICmpInst::ICMP_SLT, "vcltz");
6328 case NEON::BI__builtin_neon_vcvt_f64_v:
6329 case NEON::BI__builtin_neon_vcvtq_f64_v:
6330 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6331 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad));
6332 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
6333 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
6334 case NEON::BI__builtin_neon_vcvt_f64_f32: {
6335 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad &&
6336 "unexpected vcvt_f64_f32 builtin");
6337 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false);
6338 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6339
6340 return Builder.CreateFPExt(Ops[0], Ty, "vcvt");
6341 }
6342 case NEON::BI__builtin_neon_vcvt_f32_f64: {
6343 assert(Type.getEltType() == NeonTypeFlags::Float32 &&
6344 "unexpected vcvt_f32_f64 builtin");
6345 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true);
6346 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6347
6348 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt");
6349 }
6350 case NEON::BI__builtin_neon_vcvt_s32_v:
6351 case NEON::BI__builtin_neon_vcvt_u32_v:
6352 case NEON::BI__builtin_neon_vcvt_s64_v:
6353 case NEON::BI__builtin_neon_vcvt_u64_v:
6354 case NEON::BI__builtin_neon_vcvtq_s32_v:
6355 case NEON::BI__builtin_neon_vcvtq_u32_v:
6356 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00006357 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006358 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northovera2ee4332014-03-29 15:09:45 +00006359 if (usgn)
6360 return Builder.CreateFPToUI(Ops[0], Ty);
6361 return Builder.CreateFPToSI(Ops[0], Ty);
6362 }
6363 case NEON::BI__builtin_neon_vcvta_s32_v:
6364 case NEON::BI__builtin_neon_vcvtaq_s32_v:
6365 case NEON::BI__builtin_neon_vcvta_u32_v:
6366 case NEON::BI__builtin_neon_vcvtaq_u32_v:
6367 case NEON::BI__builtin_neon_vcvta_s64_v:
6368 case NEON::BI__builtin_neon_vcvtaq_s64_v:
6369 case NEON::BI__builtin_neon_vcvta_u64_v:
6370 case NEON::BI__builtin_neon_vcvtaq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006371 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006372 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006373 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta");
6374 }
6375 case NEON::BI__builtin_neon_vcvtm_s32_v:
6376 case NEON::BI__builtin_neon_vcvtmq_s32_v:
6377 case NEON::BI__builtin_neon_vcvtm_u32_v:
6378 case NEON::BI__builtin_neon_vcvtmq_u32_v:
6379 case NEON::BI__builtin_neon_vcvtm_s64_v:
6380 case NEON::BI__builtin_neon_vcvtmq_s64_v:
6381 case NEON::BI__builtin_neon_vcvtm_u64_v:
6382 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006383 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006384 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006385 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm");
6386 }
6387 case NEON::BI__builtin_neon_vcvtn_s32_v:
6388 case NEON::BI__builtin_neon_vcvtnq_s32_v:
6389 case NEON::BI__builtin_neon_vcvtn_u32_v:
6390 case NEON::BI__builtin_neon_vcvtnq_u32_v:
6391 case NEON::BI__builtin_neon_vcvtn_s64_v:
6392 case NEON::BI__builtin_neon_vcvtnq_s64_v:
6393 case NEON::BI__builtin_neon_vcvtn_u64_v:
6394 case NEON::BI__builtin_neon_vcvtnq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006395 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006396 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006397 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn");
6398 }
6399 case NEON::BI__builtin_neon_vcvtp_s32_v:
6400 case NEON::BI__builtin_neon_vcvtpq_s32_v:
6401 case NEON::BI__builtin_neon_vcvtp_u32_v:
6402 case NEON::BI__builtin_neon_vcvtpq_u32_v:
6403 case NEON::BI__builtin_neon_vcvtp_s64_v:
6404 case NEON::BI__builtin_neon_vcvtpq_s64_v:
6405 case NEON::BI__builtin_neon_vcvtp_u64_v:
6406 case NEON::BI__builtin_neon_vcvtpq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006407 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006408 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006409 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp");
6410 }
6411 case NEON::BI__builtin_neon_vmulx_v:
6412 case NEON::BI__builtin_neon_vmulxq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006413 Int = Intrinsic::aarch64_neon_fmulx;
Tim Northovera2ee4332014-03-29 15:09:45 +00006414 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx");
6415 }
6416 case NEON::BI__builtin_neon_vmul_lane_v:
6417 case NEON::BI__builtin_neon_vmul_laneq_v: {
6418 // v1f64 vmul_lane should be mapped to Neon scalar mul lane
6419 bool Quad = false;
6420 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
6421 Quad = true;
6422 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6423 llvm::Type *VTy = GetNeonType(this,
6424 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad));
6425 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
6426 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract");
6427 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]);
6428 return Builder.CreateBitCast(Result, Ty);
6429 }
Tim Northover0c68faa2014-03-31 15:47:09 +00006430 case NEON::BI__builtin_neon_vnegd_s64:
6431 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd");
Tim Northovera2ee4332014-03-29 15:09:45 +00006432 case NEON::BI__builtin_neon_vpmaxnm_v:
6433 case NEON::BI__builtin_neon_vpmaxnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006434 Int = Intrinsic::aarch64_neon_fmaxnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006435 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm");
6436 }
6437 case NEON::BI__builtin_neon_vpminnm_v:
6438 case NEON::BI__builtin_neon_vpminnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006439 Int = Intrinsic::aarch64_neon_fminnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006440 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm");
6441 }
6442 case NEON::BI__builtin_neon_vsqrt_v:
6443 case NEON::BI__builtin_neon_vsqrtq_v: {
6444 Int = Intrinsic::sqrt;
6445 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6446 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt");
6447 }
6448 case NEON::BI__builtin_neon_vrbit_v:
6449 case NEON::BI__builtin_neon_vrbitq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006450 Int = Intrinsic::aarch64_neon_rbit;
Tim Northovera2ee4332014-03-29 15:09:45 +00006451 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit");
6452 }
6453 case NEON::BI__builtin_neon_vaddv_u8:
6454 // FIXME: These are handled by the AArch64 scalar code.
6455 usgn = true;
6456 // FALLTHROUGH
6457 case NEON::BI__builtin_neon_vaddv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006458 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006459 Ty = Int32Ty;
6460 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006461 llvm::Type *Tys[2] = { Ty, VTy };
6462 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6463 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006464 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006465 }
6466 case NEON::BI__builtin_neon_vaddv_u16:
6467 usgn = true;
6468 // FALLTHROUGH
6469 case NEON::BI__builtin_neon_vaddv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006470 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006471 Ty = Int32Ty;
6472 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006473 llvm::Type *Tys[2] = { Ty, VTy };
6474 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6475 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006476 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006477 }
6478 case NEON::BI__builtin_neon_vaddvq_u8:
6479 usgn = true;
6480 // FALLTHROUGH
6481 case NEON::BI__builtin_neon_vaddvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006482 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006483 Ty = Int32Ty;
6484 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006485 llvm::Type *Tys[2] = { Ty, VTy };
6486 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6487 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006488 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006489 }
6490 case NEON::BI__builtin_neon_vaddvq_u16:
6491 usgn = true;
6492 // FALLTHROUGH
6493 case NEON::BI__builtin_neon_vaddvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006494 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006495 Ty = Int32Ty;
6496 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006497 llvm::Type *Tys[2] = { Ty, VTy };
6498 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6499 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006500 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006501 }
6502 case NEON::BI__builtin_neon_vmaxv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006503 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006504 Ty = Int32Ty;
6505 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006506 llvm::Type *Tys[2] = { Ty, VTy };
6507 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6508 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006509 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006510 }
6511 case NEON::BI__builtin_neon_vmaxv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006512 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006513 Ty = Int32Ty;
6514 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006515 llvm::Type *Tys[2] = { Ty, VTy };
6516 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6517 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006518 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006519 }
6520 case NEON::BI__builtin_neon_vmaxvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006521 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006522 Ty = Int32Ty;
6523 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006524 llvm::Type *Tys[2] = { Ty, VTy };
6525 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6526 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006527 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006528 }
6529 case NEON::BI__builtin_neon_vmaxvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006530 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006531 Ty = Int32Ty;
6532 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006533 llvm::Type *Tys[2] = { Ty, VTy };
6534 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6535 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006536 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006537 }
6538 case NEON::BI__builtin_neon_vmaxv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006539 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006540 Ty = Int32Ty;
6541 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006542 llvm::Type *Tys[2] = { Ty, VTy };
6543 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6544 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006545 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006546 }
6547 case NEON::BI__builtin_neon_vmaxv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006548 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006549 Ty = Int32Ty;
6550 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006551 llvm::Type *Tys[2] = { Ty, VTy };
6552 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6553 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006554 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006555 }
6556 case NEON::BI__builtin_neon_vmaxvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006557 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006558 Ty = Int32Ty;
6559 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006560 llvm::Type *Tys[2] = { Ty, VTy };
6561 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6562 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006563 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006564 }
6565 case NEON::BI__builtin_neon_vmaxvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006566 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006567 Ty = Int32Ty;
6568 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006569 llvm::Type *Tys[2] = { Ty, VTy };
6570 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6571 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006572 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006573 }
6574 case NEON::BI__builtin_neon_vminv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006575 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006576 Ty = Int32Ty;
6577 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006578 llvm::Type *Tys[2] = { Ty, VTy };
6579 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6580 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006581 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006582 }
6583 case NEON::BI__builtin_neon_vminv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006584 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006585 Ty = Int32Ty;
6586 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006587 llvm::Type *Tys[2] = { Ty, VTy };
6588 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6589 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006590 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006591 }
6592 case NEON::BI__builtin_neon_vminvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006593 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006594 Ty = Int32Ty;
6595 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006596 llvm::Type *Tys[2] = { Ty, VTy };
6597 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6598 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006599 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006600 }
6601 case NEON::BI__builtin_neon_vminvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006602 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006603 Ty = Int32Ty;
6604 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006605 llvm::Type *Tys[2] = { Ty, VTy };
6606 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6607 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006608 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006609 }
6610 case NEON::BI__builtin_neon_vminv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006611 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006612 Ty = Int32Ty;
6613 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006614 llvm::Type *Tys[2] = { Ty, VTy };
6615 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6616 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006617 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006618 }
6619 case NEON::BI__builtin_neon_vminv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006620 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006621 Ty = Int32Ty;
6622 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006623 llvm::Type *Tys[2] = { Ty, VTy };
6624 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6625 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006626 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006627 }
6628 case NEON::BI__builtin_neon_vminvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006629 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006630 Ty = Int32Ty;
6631 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006632 llvm::Type *Tys[2] = { Ty, VTy };
6633 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6634 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006635 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006636 }
6637 case NEON::BI__builtin_neon_vminvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006638 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006639 Ty = Int32Ty;
6640 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006641 llvm::Type *Tys[2] = { Ty, VTy };
6642 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6643 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006644 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006645 }
6646 case NEON::BI__builtin_neon_vmul_n_f64: {
6647 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6648 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy);
6649 return Builder.CreateFMul(Ops[0], RHS);
6650 }
6651 case NEON::BI__builtin_neon_vaddlv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006652 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006653 Ty = Int32Ty;
6654 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006655 llvm::Type *Tys[2] = { Ty, VTy };
6656 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6657 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006658 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006659 }
6660 case NEON::BI__builtin_neon_vaddlv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006661 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006662 Ty = Int32Ty;
6663 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006664 llvm::Type *Tys[2] = { Ty, VTy };
6665 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6666 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6667 }
6668 case NEON::BI__builtin_neon_vaddlvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006669 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006670 Ty = Int32Ty;
6671 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006672 llvm::Type *Tys[2] = { Ty, VTy };
6673 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6674 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006675 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006676 }
6677 case NEON::BI__builtin_neon_vaddlvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006678 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006679 Ty = Int32Ty;
6680 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006681 llvm::Type *Tys[2] = { Ty, VTy };
6682 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6683 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6684 }
6685 case NEON::BI__builtin_neon_vaddlv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006686 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006687 Ty = Int32Ty;
6688 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006689 llvm::Type *Tys[2] = { Ty, VTy };
6690 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6691 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006692 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006693 }
6694 case NEON::BI__builtin_neon_vaddlv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006695 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006696 Ty = Int32Ty;
6697 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006698 llvm::Type *Tys[2] = { Ty, VTy };
6699 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6700 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6701 }
6702 case NEON::BI__builtin_neon_vaddlvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006703 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006704 Ty = Int32Ty;
6705 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006706 llvm::Type *Tys[2] = { Ty, VTy };
6707 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6708 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006709 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006710 }
6711 case NEON::BI__builtin_neon_vaddlvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006712 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006713 Ty = Int32Ty;
6714 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006715 llvm::Type *Tys[2] = { Ty, VTy };
6716 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6717 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6718 }
6719 case NEON::BI__builtin_neon_vsri_n_v:
6720 case NEON::BI__builtin_neon_vsriq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006721 Int = Intrinsic::aarch64_neon_vsri;
Tim Northovera2ee4332014-03-29 15:09:45 +00006722 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6723 return EmitNeonCall(Intrin, Ops, "vsri_n");
6724 }
6725 case NEON::BI__builtin_neon_vsli_n_v:
6726 case NEON::BI__builtin_neon_vsliq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006727 Int = Intrinsic::aarch64_neon_vsli;
Tim Northovera2ee4332014-03-29 15:09:45 +00006728 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6729 return EmitNeonCall(Intrin, Ops, "vsli_n");
6730 }
6731 case NEON::BI__builtin_neon_vsra_n_v:
6732 case NEON::BI__builtin_neon_vsraq_n_v:
6733 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6734 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
6735 return Builder.CreateAdd(Ops[0], Ops[1]);
6736 case NEON::BI__builtin_neon_vrsra_n_v:
6737 case NEON::BI__builtin_neon_vrsraq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006738 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006739 SmallVector<llvm::Value*,2> TmpOps;
6740 TmpOps.push_back(Ops[1]);
6741 TmpOps.push_back(Ops[2]);
6742 Function* F = CGM.getIntrinsic(Int, Ty);
6743 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true);
6744 Ops[0] = Builder.CreateBitCast(Ops[0], VTy);
6745 return Builder.CreateAdd(Ops[0], tmp);
6746 }
6747 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence
6748 // of an Align parameter here.
6749 case NEON::BI__builtin_neon_vld1_x2_v:
6750 case NEON::BI__builtin_neon_vld1q_x2_v:
6751 case NEON::BI__builtin_neon_vld1_x3_v:
6752 case NEON::BI__builtin_neon_vld1q_x3_v:
6753 case NEON::BI__builtin_neon_vld1_x4_v:
6754 case NEON::BI__builtin_neon_vld1q_x4_v: {
6755 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6756 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6757 llvm::Type *Tys[2] = { VTy, PTy };
6758 unsigned Int;
6759 switch (BuiltinID) {
6760 case NEON::BI__builtin_neon_vld1_x2_v:
6761 case NEON::BI__builtin_neon_vld1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006762 Int = Intrinsic::aarch64_neon_ld1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006763 break;
6764 case NEON::BI__builtin_neon_vld1_x3_v:
6765 case NEON::BI__builtin_neon_vld1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006766 Int = Intrinsic::aarch64_neon_ld1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006767 break;
6768 case NEON::BI__builtin_neon_vld1_x4_v:
6769 case NEON::BI__builtin_neon_vld1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006770 Int = Intrinsic::aarch64_neon_ld1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006771 break;
6772 }
6773 Function *F = CGM.getIntrinsic(Int, Tys);
6774 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN");
6775 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6776 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006777 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006778 }
6779 case NEON::BI__builtin_neon_vst1_x2_v:
6780 case NEON::BI__builtin_neon_vst1q_x2_v:
6781 case NEON::BI__builtin_neon_vst1_x3_v:
6782 case NEON::BI__builtin_neon_vst1q_x3_v:
6783 case NEON::BI__builtin_neon_vst1_x4_v:
6784 case NEON::BI__builtin_neon_vst1q_x4_v: {
6785 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6786 llvm::Type *Tys[2] = { VTy, PTy };
6787 unsigned Int;
6788 switch (BuiltinID) {
6789 case NEON::BI__builtin_neon_vst1_x2_v:
6790 case NEON::BI__builtin_neon_vst1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006791 Int = Intrinsic::aarch64_neon_st1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006792 break;
6793 case NEON::BI__builtin_neon_vst1_x3_v:
6794 case NEON::BI__builtin_neon_vst1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006795 Int = Intrinsic::aarch64_neon_st1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006796 break;
6797 case NEON::BI__builtin_neon_vst1_x4_v:
6798 case NEON::BI__builtin_neon_vst1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006799 Int = Intrinsic::aarch64_neon_st1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006800 break;
6801 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00006802 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6803 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
Tim Northovera2ee4332014-03-29 15:09:45 +00006804 }
6805 case NEON::BI__builtin_neon_vld1_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00006806 case NEON::BI__builtin_neon_vld1q_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006807 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
Peter Collingbourneb367c562016-11-28 22:30:21 +00006808 auto Alignment = CharUnits::fromQuantity(
6809 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16);
6810 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment);
6811 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006812 case NEON::BI__builtin_neon_vst1_v:
6813 case NEON::BI__builtin_neon_vst1q_v:
6814 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
6815 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
John McCall7f416cc2015-09-08 08:05:57 +00006816 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006817 case NEON::BI__builtin_neon_vld1_lane_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00006818 case NEON::BI__builtin_neon_vld1q_lane_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006819 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6820 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
6821 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00006822 auto Alignment = CharUnits::fromQuantity(
6823 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16);
6824 Ops[0] =
6825 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Tim Northovera2ee4332014-03-29 15:09:45 +00006826 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane");
Peter Collingbourneb367c562016-11-28 22:30:21 +00006827 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006828 case NEON::BI__builtin_neon_vld1_dup_v:
6829 case NEON::BI__builtin_neon_vld1q_dup_v: {
6830 Value *V = UndefValue::get(Ty);
6831 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
6832 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00006833 auto Alignment = CharUnits::fromQuantity(
6834 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16);
6835 Ops[0] =
6836 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Michael J. Spencer5ce26682014-06-02 19:48:59 +00006837 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006838 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI);
6839 return EmitNeonSplat(Ops[0], CI);
6840 }
6841 case NEON::BI__builtin_neon_vst1_lane_v:
6842 case NEON::BI__builtin_neon_vst1q_lane_v:
6843 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6844 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
6845 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00006846 return Builder.CreateDefaultAlignedStore(Ops[1],
6847 Builder.CreateBitCast(Ops[0], Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00006848 case NEON::BI__builtin_neon_vld2_v:
6849 case NEON::BI__builtin_neon_vld2q_v: {
6850 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
6851 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6852 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006853 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006854 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
6855 Ops[0] = Builder.CreateBitCast(Ops[0],
6856 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006857 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006858 }
6859 case NEON::BI__builtin_neon_vld3_v:
6860 case NEON::BI__builtin_neon_vld3q_v: {
6861 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
6862 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6863 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006864 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006865 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
6866 Ops[0] = Builder.CreateBitCast(Ops[0],
6867 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006868 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006869 }
6870 case NEON::BI__builtin_neon_vld4_v:
6871 case NEON::BI__builtin_neon_vld4q_v: {
6872 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
6873 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6874 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006875 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006876 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
6877 Ops[0] = Builder.CreateBitCast(Ops[0],
6878 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006879 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006880 }
Tim Northover74b2def2014-04-01 10:37:47 +00006881 case NEON::BI__builtin_neon_vld2_dup_v:
6882 case NEON::BI__builtin_neon_vld2q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006883 llvm::Type *PTy =
6884 llvm::PointerType::getUnqual(VTy->getElementType());
6885 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6886 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006887 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006888 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
6889 Ops[0] = Builder.CreateBitCast(Ops[0],
6890 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006891 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006892 }
Tim Northover74b2def2014-04-01 10:37:47 +00006893 case NEON::BI__builtin_neon_vld3_dup_v:
6894 case NEON::BI__builtin_neon_vld3q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006895 llvm::Type *PTy =
6896 llvm::PointerType::getUnqual(VTy->getElementType());
6897 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6898 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006899 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006900 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
6901 Ops[0] = Builder.CreateBitCast(Ops[0],
6902 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006903 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006904 }
Tim Northover74b2def2014-04-01 10:37:47 +00006905 case NEON::BI__builtin_neon_vld4_dup_v:
6906 case NEON::BI__builtin_neon_vld4q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006907 llvm::Type *PTy =
6908 llvm::PointerType::getUnqual(VTy->getElementType());
6909 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6910 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006911 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006912 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
6913 Ops[0] = Builder.CreateBitCast(Ops[0],
6914 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00006915 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006916 }
6917 case NEON::BI__builtin_neon_vld2_lane_v:
6918 case NEON::BI__builtin_neon_vld2q_lane_v: {
6919 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006920 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006921 Ops.push_back(Ops[1]);
6922 Ops.erase(Ops.begin()+1);
6923 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6924 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00006925 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00006926 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00006927 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6928 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006929 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006930 }
6931 case NEON::BI__builtin_neon_vld3_lane_v:
6932 case NEON::BI__builtin_neon_vld3q_lane_v: {
6933 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006934 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006935 Ops.push_back(Ops[1]);
6936 Ops.erase(Ops.begin()+1);
6937 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6938 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
6939 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00006940 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00006941 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00006942 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6943 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006944 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006945 }
6946 case NEON::BI__builtin_neon_vld4_lane_v:
6947 case NEON::BI__builtin_neon_vld4q_lane_v: {
6948 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006949 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00006950 Ops.push_back(Ops[1]);
6951 Ops.erase(Ops.begin()+1);
6952 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6953 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
6954 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
6955 Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00006956 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00006957 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00006958 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6959 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006960 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006961 }
6962 case NEON::BI__builtin_neon_vst2_v:
6963 case NEON::BI__builtin_neon_vst2q_v: {
6964 Ops.push_back(Ops[0]);
6965 Ops.erase(Ops.begin());
6966 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006967 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00006968 Ops, "");
6969 }
6970 case NEON::BI__builtin_neon_vst2_lane_v:
6971 case NEON::BI__builtin_neon_vst2q_lane_v: {
6972 Ops.push_back(Ops[0]);
6973 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00006974 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006975 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006976 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00006977 Ops, "");
6978 }
6979 case NEON::BI__builtin_neon_vst3_v:
6980 case NEON::BI__builtin_neon_vst3q_v: {
6981 Ops.push_back(Ops[0]);
6982 Ops.erase(Ops.begin());
6983 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006984 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00006985 Ops, "");
6986 }
6987 case NEON::BI__builtin_neon_vst3_lane_v:
6988 case NEON::BI__builtin_neon_vst3q_lane_v: {
6989 Ops.push_back(Ops[0]);
6990 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00006991 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006992 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00006993 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00006994 Ops, "");
6995 }
6996 case NEON::BI__builtin_neon_vst4_v:
6997 case NEON::BI__builtin_neon_vst4q_v: {
6998 Ops.push_back(Ops[0]);
6999 Ops.erase(Ops.begin());
7000 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007001 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007002 Ops, "");
7003 }
7004 case NEON::BI__builtin_neon_vst4_lane_v:
7005 case NEON::BI__builtin_neon_vst4q_lane_v: {
7006 Ops.push_back(Ops[0]);
7007 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007008 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007009 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007010 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007011 Ops, "");
7012 }
7013 case NEON::BI__builtin_neon_vtrn_v:
7014 case NEON::BI__builtin_neon_vtrnq_v: {
7015 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7016 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7017 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007018 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007019
7020 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007021 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007022 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007023 Indices.push_back(i+vi);
7024 Indices.push_back(i+e+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007025 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007026 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007027 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00007028 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007029 }
7030 return SV;
7031 }
7032 case NEON::BI__builtin_neon_vuzp_v:
7033 case NEON::BI__builtin_neon_vuzpq_v: {
7034 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7035 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7036 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007037 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007038
7039 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007040 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007041 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00007042 Indices.push_back(2*i+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007043
David Blaikiefb901c7a2015-04-04 15:12:29 +00007044 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007045 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00007046 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007047 }
7048 return SV;
7049 }
7050 case NEON::BI__builtin_neon_vzip_v:
7051 case NEON::BI__builtin_neon_vzipq_v: {
7052 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7053 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7054 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007055 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007056
7057 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007058 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007059 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007060 Indices.push_back((i + vi*e) >> 1);
7061 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northovera2ee4332014-03-29 15:09:45 +00007062 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007063 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007064 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00007065 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007066 }
7067 return SV;
7068 }
7069 case NEON::BI__builtin_neon_vqtbl1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007070 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007071 Ops, "vtbl1");
7072 }
7073 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007074 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007075 Ops, "vtbl2");
7076 }
7077 case NEON::BI__builtin_neon_vqtbl3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007078 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007079 Ops, "vtbl3");
7080 }
7081 case NEON::BI__builtin_neon_vqtbl4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007082 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007083 Ops, "vtbl4");
7084 }
7085 case NEON::BI__builtin_neon_vqtbx1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007086 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007087 Ops, "vtbx1");
7088 }
7089 case NEON::BI__builtin_neon_vqtbx2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007090 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007091 Ops, "vtbx2");
7092 }
7093 case NEON::BI__builtin_neon_vqtbx3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007094 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007095 Ops, "vtbx3");
7096 }
7097 case NEON::BI__builtin_neon_vqtbx4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007098 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007099 Ops, "vtbx4");
7100 }
7101 case NEON::BI__builtin_neon_vsqadd_v:
7102 case NEON::BI__builtin_neon_vsqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007103 Int = Intrinsic::aarch64_neon_usqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007104 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd");
7105 }
7106 case NEON::BI__builtin_neon_vuqadd_v:
7107 case NEON::BI__builtin_neon_vuqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007108 Int = Intrinsic::aarch64_neon_suqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007109 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
7110 }
7111 }
7112}
7113
Bill Wendling65b2a962010-10-09 08:47:25 +00007114llvm::Value *CodeGenFunction::
Bill Wendlingf1a3fca2012-02-22 09:30:11 +00007115BuildVector(ArrayRef<llvm::Value*> Ops) {
Bill Wendling65b2a962010-10-09 08:47:25 +00007116 assert((Ops.size() & (Ops.size() - 1)) == 0 &&
7117 "Not a power-of-two sized vector!");
7118 bool AllConstants = true;
7119 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i)
7120 AllConstants &= isa<Constant>(Ops[i]);
7121
7122 // If this is a constant vector, create a ConstantVector.
7123 if (AllConstants) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007124 SmallVector<llvm::Constant*, 16> CstOps;
Bill Wendling65b2a962010-10-09 08:47:25 +00007125 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
7126 CstOps.push_back(cast<Constant>(Ops[i]));
7127 return llvm::ConstantVector::get(CstOps);
7128 }
7129
7130 // Otherwise, insertelement the values to build the vector.
7131 Value *Result =
7132 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size()));
7133
7134 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007135 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i));
Bill Wendling65b2a962010-10-09 08:47:25 +00007136
7137 return Result;
7138}
7139
Igor Bregeraadb8762016-06-08 13:59:20 +00007140// Convert the mask from an integer type to a vector of i1.
7141static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask,
7142 unsigned NumElts) {
7143
7144 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(),
7145 cast<IntegerType>(Mask->getType())->getBitWidth());
7146 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy);
7147
7148 // If we have less than 8 elements, then the starting mask was an i8 and
7149 // we need to extract down to the right number of elements.
7150 if (NumElts < 8) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007151 uint32_t Indices[4];
Igor Bregeraadb8762016-06-08 13:59:20 +00007152 for (unsigned i = 0; i != NumElts; ++i)
7153 Indices[i] = i;
7154 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec,
7155 makeArrayRef(Indices, NumElts),
7156 "extract");
7157 }
7158 return MaskVec;
7159}
7160
Craig Topper6e891fb2016-05-31 01:50:10 +00007161static Value *EmitX86MaskedStore(CodeGenFunction &CGF,
7162 SmallVectorImpl<Value *> &Ops,
7163 unsigned Align) {
7164 // Cast the pointer to right type.
7165 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7166 llvm::PointerType::getUnqual(Ops[1]->getType()));
7167
7168 // If the mask is all ones just emit a regular store.
7169 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7170 if (C->isAllOnesValue())
7171 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align);
7172
Igor Bregeraadb8762016-06-08 13:59:20 +00007173 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7174 Ops[1]->getType()->getVectorNumElements());
Craig Topper6e891fb2016-05-31 01:50:10 +00007175
Igor Bregeraadb8762016-06-08 13:59:20 +00007176 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec);
Craig Topper6e891fb2016-05-31 01:50:10 +00007177}
7178
Craig Topper4b060e32016-05-31 06:58:07 +00007179static Value *EmitX86MaskedLoad(CodeGenFunction &CGF,
7180 SmallVectorImpl<Value *> &Ops, unsigned Align) {
7181 // Cast the pointer to right type.
7182 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7183 llvm::PointerType::getUnqual(Ops[1]->getType()));
7184
7185 // If the mask is all ones just emit a regular store.
7186 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7187 if (C->isAllOnesValue())
7188 return CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7189
Igor Bregeraadb8762016-06-08 13:59:20 +00007190 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7191 Ops[1]->getType()->getVectorNumElements());
Craig Topper4b060e32016-05-31 06:58:07 +00007192
Igor Bregeraadb8762016-06-08 13:59:20 +00007193 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]);
7194}
Craig Topper4b060e32016-05-31 06:58:07 +00007195
Simon Pilgrim2d851732016-07-22 13:58:56 +00007196static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF,
7197 SmallVectorImpl<Value *> &Ops,
7198 llvm::Type *DstTy,
7199 unsigned SrcSizeInBits,
7200 unsigned Align) {
7201 // Load the subvector.
7202 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7203
7204 // Create broadcast mask.
7205 unsigned NumDstElts = DstTy->getVectorNumElements();
7206 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits();
7207
7208 SmallVector<uint32_t, 8> Mask;
7209 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts)
7210 for (unsigned j = 0; j != NumSrcElts; ++j)
7211 Mask.push_back(j);
7212
7213 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst");
7214}
7215
Igor Bregeraadb8762016-06-08 13:59:20 +00007216static Value *EmitX86Select(CodeGenFunction &CGF,
Craig Topperc1442972016-06-09 05:15:00 +00007217 Value *Mask, Value *Op0, Value *Op1) {
Igor Bregeraadb8762016-06-08 13:59:20 +00007218
7219 // If the mask is all ones just return first argument.
Craig Topperc1442972016-06-09 05:15:00 +00007220 if (const auto *C = dyn_cast<Constant>(Mask))
Igor Bregeraadb8762016-06-08 13:59:20 +00007221 if (C->isAllOnesValue())
Craig Topperc1442972016-06-09 05:15:00 +00007222 return Op0;
Igor Bregeraadb8762016-06-08 13:59:20 +00007223
Craig Topperc1442972016-06-09 05:15:00 +00007224 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements());
Igor Bregeraadb8762016-06-08 13:59:20 +00007225
Craig Topperc1442972016-06-09 05:15:00 +00007226 return CGF.Builder.CreateSelect(Mask, Op0, Op1);
Craig Topper4b060e32016-05-31 06:58:07 +00007227}
7228
Craig Topperd1691c72016-06-22 04:47:58 +00007229static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC,
7230 bool Signed, SmallVectorImpl<Value *> &Ops) {
Craig Toppera54c21e2016-06-15 14:06:34 +00007231 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topperd1691c72016-06-22 04:47:58 +00007232 Value *Cmp;
Craig Toppera54c21e2016-06-15 14:06:34 +00007233
Craig Topperd1691c72016-06-22 04:47:58 +00007234 if (CC == 3) {
7235 Cmp = Constant::getNullValue(
7236 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7237 } else if (CC == 7) {
7238 Cmp = Constant::getAllOnesValue(
7239 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7240 } else {
7241 ICmpInst::Predicate Pred;
7242 switch (CC) {
7243 default: llvm_unreachable("Unknown condition code");
7244 case 0: Pred = ICmpInst::ICMP_EQ; break;
7245 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
7246 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
7247 case 4: Pred = ICmpInst::ICMP_NE; break;
7248 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
7249 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
7250 }
7251 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7252 }
7253
7254 const auto *C = dyn_cast<Constant>(Ops.back());
Craig Toppera54c21e2016-06-15 14:06:34 +00007255 if (!C || !C->isAllOnesValue())
Craig Topperd1691c72016-06-22 04:47:58 +00007256 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts));
Craig Toppera54c21e2016-06-15 14:06:34 +00007257
7258 if (NumElts < 8) {
7259 uint32_t Indices[8];
7260 for (unsigned i = 0; i != NumElts; ++i)
7261 Indices[i] = i;
7262 for (unsigned i = NumElts; i != 8; ++i)
Craig Topperac1823f2016-07-04 07:09:46 +00007263 Indices[i] = i % NumElts + NumElts;
Igor Breger2c880cf2016-06-29 08:14:17 +00007264 Cmp = CGF.Builder.CreateShuffleVector(
7265 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices);
Craig Toppera54c21e2016-06-15 14:06:34 +00007266 }
7267 return CGF.Builder.CreateBitCast(Cmp,
7268 IntegerType::get(CGF.getLLVMContext(),
7269 std::max(NumElts, 8U)));
7270}
7271
Craig Topper531ce282016-10-24 04:04:24 +00007272static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred,
7273 ArrayRef<Value *> Ops) {
7274 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7275 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]);
7276
7277 if (Ops.size() == 2)
7278 return Res;
7279
7280 assert(Ops.size() == 4);
7281 return EmitX86Select(CGF, Ops[3], Res, Ops[2]);
7282}
7283
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007284static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op,
7285 llvm::Type *DstTy) {
7286 unsigned NumberOfElements = DstTy->getVectorNumElements();
7287 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements);
7288 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2");
7289}
7290
Erich Keane9937b132017-09-01 19:42:45 +00007291Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007292 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
7293 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
Erich Keane9937b132017-09-01 19:42:45 +00007294 return EmitX86CpuIs(CPUStr);
7295}
7296
7297Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007298
7299 // This enum contains the vendor, type, and subtype enums from the
7300 // runtime library concatenated together. The _START labels mark
7301 // the start and are used to adjust the value into the correct
7302 // encoding space.
7303 enum X86CPUs {
7304 INTEL = 1,
7305 AMD,
7306 CPU_TYPE_START,
7307 INTEL_BONNELL,
7308 INTEL_CORE2,
7309 INTEL_COREI7,
7310 AMDFAM10H,
7311 AMDFAM15H,
7312 INTEL_SILVERMONT,
7313 INTEL_KNL,
7314 AMD_BTVER1,
7315 AMD_BTVER2,
7316 CPU_SUBTYPE_START,
7317 INTEL_COREI7_NEHALEM,
7318 INTEL_COREI7_WESTMERE,
7319 INTEL_COREI7_SANDYBRIDGE,
7320 AMDFAM10H_BARCELONA,
7321 AMDFAM10H_SHANGHAI,
7322 AMDFAM10H_ISTANBUL,
7323 AMDFAM15H_BDVER1,
7324 AMDFAM15H_BDVER2,
7325 AMDFAM15H_BDVER3,
7326 AMDFAM15H_BDVER4,
7327 AMDFAM17H_ZNVER1,
7328 INTEL_COREI7_IVYBRIDGE,
7329 INTEL_COREI7_HASWELL,
7330 INTEL_COREI7_BROADWELL,
7331 INTEL_COREI7_SKYLAKE,
7332 INTEL_COREI7_SKYLAKE_AVX512,
7333 };
7334
7335 X86CPUs CPU =
7336 StringSwitch<X86CPUs>(CPUStr)
7337 .Case("amd", AMD)
7338 .Case("amdfam10h", AMDFAM10H)
Erich Keane9937b132017-09-01 19:42:45 +00007339 .Case("amdfam10", AMDFAM10H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007340 .Case("amdfam15h", AMDFAM15H)
Erich Keane9937b132017-09-01 19:42:45 +00007341 .Case("amdfam15", AMDFAM15H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007342 .Case("atom", INTEL_BONNELL)
7343 .Case("barcelona", AMDFAM10H_BARCELONA)
7344 .Case("bdver1", AMDFAM15H_BDVER1)
7345 .Case("bdver2", AMDFAM15H_BDVER2)
7346 .Case("bdver3", AMDFAM15H_BDVER3)
7347 .Case("bdver4", AMDFAM15H_BDVER4)
7348 .Case("bonnell", INTEL_BONNELL)
7349 .Case("broadwell", INTEL_COREI7_BROADWELL)
7350 .Case("btver1", AMD_BTVER1)
7351 .Case("btver2", AMD_BTVER2)
7352 .Case("core2", INTEL_CORE2)
7353 .Case("corei7", INTEL_COREI7)
7354 .Case("haswell", INTEL_COREI7_HASWELL)
7355 .Case("intel", INTEL)
7356 .Case("istanbul", AMDFAM10H_ISTANBUL)
7357 .Case("ivybridge", INTEL_COREI7_IVYBRIDGE)
7358 .Case("knl", INTEL_KNL)
7359 .Case("nehalem", INTEL_COREI7_NEHALEM)
7360 .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE)
7361 .Case("shanghai", AMDFAM10H_SHANGHAI)
7362 .Case("silvermont", INTEL_SILVERMONT)
7363 .Case("skylake", INTEL_COREI7_SKYLAKE)
7364 .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512)
7365 .Case("slm", INTEL_SILVERMONT)
7366 .Case("westmere", INTEL_COREI7_WESTMERE)
7367 .Case("znver1", AMDFAM17H_ZNVER1);
7368
Erich Keane9937b132017-09-01 19:42:45 +00007369 llvm::Type *Int32Ty = Builder.getInt32Ty();
Craig Topper699ae0c2017-08-10 20:28:30 +00007370
7371 // Matching the struct layout from the compiler-rt/libgcc structure that is
7372 // filled in:
7373 // unsigned int __cpu_vendor;
7374 // unsigned int __cpu_type;
7375 // unsigned int __cpu_subtype;
7376 // unsigned int __cpu_features[1];
7377 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7378 llvm::ArrayType::get(Int32Ty, 1));
7379
7380 // Grab the global __cpu_model.
Erich Keane9937b132017-09-01 19:42:45 +00007381 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
Craig Topper699ae0c2017-08-10 20:28:30 +00007382
7383 // Calculate the index needed to access the correct field based on the
7384 // range. Also adjust the expected value.
7385 unsigned Index;
7386 unsigned Value;
7387 if (CPU > CPU_SUBTYPE_START) {
7388 Index = 2;
7389 Value = CPU - CPU_SUBTYPE_START;
7390 } else if (CPU > CPU_TYPE_START) {
7391 Index = 1;
7392 Value = CPU - CPU_TYPE_START;
7393 } else {
7394 Index = 0;
7395 Value = CPU;
7396 }
7397
7398 // Grab the appropriate field from __cpu_model.
7399 llvm::Value *Idxs[] = {
7400 ConstantInt::get(Int32Ty, 0),
7401 ConstantInt::get(Int32Ty, Index)
7402 };
Erich Keane9937b132017-09-01 19:42:45 +00007403 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs);
7404 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4));
Craig Topper699ae0c2017-08-10 20:28:30 +00007405
7406 // Check the value of the field against the requested value.
Erich Keane9937b132017-09-01 19:42:45 +00007407 return Builder.CreateICmpEQ(CpuValue,
Craig Topper699ae0c2017-08-10 20:28:30 +00007408 llvm::ConstantInt::get(Int32Ty, Value));
7409}
7410
Erich Keane9937b132017-09-01 19:42:45 +00007411Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) {
7412 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts();
7413 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString();
7414 return EmitX86CpuSupports(FeatureStr);
7415}
7416
7417Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) {
7418 // TODO: When/if this becomes more than x86 specific then use a TargetInfo
7419 // based mapping.
7420 // Processor features and mapping to processor feature value.
7421 enum X86Features {
7422 CMOV = 0,
7423 MMX,
7424 POPCNT,
7425 SSE,
7426 SSE2,
7427 SSE3,
7428 SSSE3,
7429 SSE4_1,
7430 SSE4_2,
7431 AVX,
7432 AVX2,
7433 SSE4_A,
7434 FMA4,
7435 XOP,
7436 FMA,
7437 AVX512F,
7438 BMI,
7439 BMI2,
7440 AES,
7441 PCLMUL,
7442 AVX512VL,
7443 AVX512BW,
7444 AVX512DQ,
7445 AVX512CD,
7446 AVX512ER,
7447 AVX512PF,
7448 AVX512VBMI,
7449 AVX512IFMA,
7450 AVX5124VNNIW,
7451 AVX5124FMAPS,
7452 AVX512VPOPCNTDQ,
7453 MAX
7454 };
7455
7456 uint32_t FeaturesMask = 0;
7457
7458 for (const StringRef &FeatureStr : FeatureStrs) {
7459 X86Features Feature =
7460 StringSwitch<X86Features>(FeatureStr)
7461 .Case("cmov", X86Features::CMOV)
7462 .Case("mmx", X86Features::MMX)
7463 .Case("popcnt", X86Features::POPCNT)
7464 .Case("sse", X86Features::SSE)
7465 .Case("sse2", X86Features::SSE2)
7466 .Case("sse3", X86Features::SSE3)
7467 .Case("ssse3", X86Features::SSSE3)
7468 .Case("sse4.1", X86Features::SSE4_1)
7469 .Case("sse4.2", X86Features::SSE4_2)
7470 .Case("avx", X86Features::AVX)
7471 .Case("avx2", X86Features::AVX2)
7472 .Case("sse4a", X86Features::SSE4_A)
7473 .Case("fma4", X86Features::FMA4)
7474 .Case("xop", X86Features::XOP)
7475 .Case("fma", X86Features::FMA)
7476 .Case("avx512f", X86Features::AVX512F)
7477 .Case("bmi", X86Features::BMI)
7478 .Case("bmi2", X86Features::BMI2)
7479 .Case("aes", X86Features::AES)
7480 .Case("pclmul", X86Features::PCLMUL)
7481 .Case("avx512vl", X86Features::AVX512VL)
7482 .Case("avx512bw", X86Features::AVX512BW)
7483 .Case("avx512dq", X86Features::AVX512DQ)
7484 .Case("avx512cd", X86Features::AVX512CD)
7485 .Case("avx512er", X86Features::AVX512ER)
7486 .Case("avx512pf", X86Features::AVX512PF)
7487 .Case("avx512vbmi", X86Features::AVX512VBMI)
7488 .Case("avx512ifma", X86Features::AVX512IFMA)
7489 .Case("avx5124vnniw", X86Features::AVX5124VNNIW)
7490 .Case("avx5124fmaps", X86Features::AVX5124FMAPS)
7491 .Case("avx512vpopcntdq", X86Features::AVX512VPOPCNTDQ)
7492 .Default(X86Features::MAX);
7493 assert(Feature != X86Features::MAX && "Invalid feature!");
7494 FeaturesMask |= (1U << Feature);
7495 }
7496
7497 // Matching the struct layout from the compiler-rt/libgcc structure that is
7498 // filled in:
7499 // unsigned int __cpu_vendor;
7500 // unsigned int __cpu_type;
7501 // unsigned int __cpu_subtype;
7502 // unsigned int __cpu_features[1];
7503 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7504 llvm::ArrayType::get(Int32Ty, 1));
7505
7506 // Grab the global __cpu_model.
7507 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
7508
7509 // Grab the first (0th) element from the field __cpu_features off of the
7510 // global in the struct STy.
7511 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3),
7512 ConstantInt::get(Int32Ty, 0)};
7513 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs);
7514 Value *Features =
7515 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4));
7516
7517 // Check the value of the bit corresponding to the feature requested.
7518 Value *Bitset = Builder.CreateAnd(
7519 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask));
7520 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0));
7521}
7522
Mike Stump11289f42009-09-09 15:08:12 +00007523Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00007524 const CallExpr *E) {
Erich Keane9937b132017-09-01 19:42:45 +00007525 if (BuiltinID == X86::BI__builtin_cpu_is)
7526 return EmitX86CpuIs(E);
7527 if (BuiltinID == X86::BI__builtin_cpu_supports)
7528 return EmitX86CpuSupports(E);
7529
Chris Lattner0e62c1c2011-07-23 10:55:15 +00007530 SmallVector<Value*, 4> Ops;
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007531
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007532 // Find out if any arguments are required to be integer constant expressions.
7533 unsigned ICEArguments = 0;
7534 ASTContext::GetBuiltinTypeError Error;
7535 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
7536 assert(Error == ASTContext::GE_None && "Should not codegen an error");
7537
7538 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
7539 // If this is a normal argument, just emit it as a scalar.
7540 if ((ICEArguments & (1 << i)) == 0) {
7541 Ops.push_back(EmitScalarExpr(E->getArg(i)));
7542 continue;
7543 }
7544
7545 // If this is required to be a constant, constant fold it so that we know
7546 // that the generated intrinsic gets a ConstantInt.
7547 llvm::APSInt Result;
7548 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
7549 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00007550 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007551 }
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007552
Sanjay Patel280cfd12016-06-15 21:20:04 +00007553 // These exist so that the builtin that takes an immediate can be bounds
7554 // checked by clang to avoid passing bad immediates to the backend. Since
7555 // AVX has a larger immediate than SSE we would need separate builtins to
7556 // do the different bounds checking. Rather than create a clang specific
7557 // SSE only builtin, this implements eight separate builtins to match gcc
7558 // implementation.
7559 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) {
7560 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm));
7561 llvm::Function *F = CGM.getIntrinsic(ID);
7562 return Builder.CreateCall(F, Ops);
7563 };
7564
7565 // For the vector forms of FP comparisons, translate the builtins directly to
7566 // IR.
7567 // TODO: The builtins could be removed if the SSE header files used vector
7568 // extension comparisons directly (vector ordered/unordered may need
7569 // additional support via __builtin_isnan()).
Craig Topper01600632016-07-08 01:57:24 +00007570 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) {
Sanjay Patel280cfd12016-06-15 21:20:04 +00007571 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]);
Craig Topper01600632016-07-08 01:57:24 +00007572 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType());
Sanjay Patel280cfd12016-06-15 21:20:04 +00007573 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy);
7574 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy);
7575 return Builder.CreateBitCast(Sext, FPVecTy);
7576 };
7577
Anders Carlsson895af082007-12-09 23:17:02 +00007578 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00007579 default: return nullptr;
Craig Topper2c03e532017-08-28 05:43:23 +00007580 case X86::BI__builtin_cpu_init: {
7581 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
7582 /*Variadic*/false);
7583 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy,
7584 "__cpu_indicator_init");
7585 return Builder.CreateCall(Func);
7586 }
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007587 case X86::BI_mm_prefetch: {
John McCall7f416cc2015-09-08 08:05:57 +00007588 Value *Address = Ops[0];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007589 Value *RW = ConstantInt::get(Int32Ty, 0);
John McCall7f416cc2015-09-08 08:05:57 +00007590 Value *Locality = Ops[1];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007591 Value *Data = ConstantInt::get(Int32Ty, 1);
7592 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00007593 return Builder.CreateCall(F, {Address, RW, Locality, Data});
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007594 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007595 case X86::BI_mm_clflush: {
7596 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush),
7597 Ops[0]);
7598 }
7599 case X86::BI_mm_lfence: {
7600 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence));
7601 }
7602 case X86::BI_mm_mfence: {
7603 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence));
7604 }
7605 case X86::BI_mm_sfence: {
7606 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence));
7607 }
7608 case X86::BI_mm_pause: {
7609 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause));
7610 }
7611 case X86::BI__rdtsc: {
7612 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc));
7613 }
Simon Pilgrim5aba9922015-08-26 21:17:12 +00007614 case X86::BI__builtin_ia32_undef128:
7615 case X86::BI__builtin_ia32_undef256:
7616 case X86::BI__builtin_ia32_undef512:
Sanjay Patele795daa2017-03-12 19:15:10 +00007617 // The x86 definition of "undef" is not the same as the LLVM definition
7618 // (PR32176). We leave optimizing away an unnecessary zero constant to the
7619 // IR optimizer and backend.
7620 // TODO: If we had a "freeze" IR instruction to generate a fixed undef
7621 // value, we should use that here instead of a zero.
7622 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Bill Wendling65b2a962010-10-09 08:47:25 +00007623 case X86::BI__builtin_ia32_vec_init_v8qi:
7624 case X86::BI__builtin_ia32_vec_init_v4hi:
7625 case X86::BI__builtin_ia32_vec_init_v2si:
7626 return Builder.CreateBitCast(BuildVector(Ops),
John McCallad7c5c12011-02-08 08:22:06 +00007627 llvm::Type::getX86_MMXTy(getLLVMContext()));
Argyrios Kyrtzidis073c9cb2010-10-10 03:19:11 +00007628 case X86::BI__builtin_ia32_vec_ext_v2si:
7629 return Builder.CreateExtractElement(Ops[0],
7630 llvm::ConstantInt::get(Ops[1]->getType(), 0));
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007631 case X86::BI_mm_setcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007632 case X86::BI__builtin_ia32_ldmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007633 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Nate Begeman91f40e32008-04-14 04:49:57 +00007634 Builder.CreateStore(Ops[0], Tmp);
7635 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007636 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007637 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007638 case X86::BI_mm_getcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007639 case X86::BI__builtin_ia32_stmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007640 Address Tmp = CreateMemTemp(E->getType());
Ted Kremenekc14efa72011-08-17 21:04:19 +00007641 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007642 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007643 return Builder.CreateLoad(Tmp, "stmxcsr");
7644 }
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007645 case X86::BI__builtin_ia32_xsave:
7646 case X86::BI__builtin_ia32_xsave64:
7647 case X86::BI__builtin_ia32_xrstor:
7648 case X86::BI__builtin_ia32_xrstor64:
7649 case X86::BI__builtin_ia32_xsaveopt:
7650 case X86::BI__builtin_ia32_xsaveopt64:
7651 case X86::BI__builtin_ia32_xrstors:
7652 case X86::BI__builtin_ia32_xrstors64:
7653 case X86::BI__builtin_ia32_xsavec:
7654 case X86::BI__builtin_ia32_xsavec64:
7655 case X86::BI__builtin_ia32_xsaves:
Reid Kleckner66e77172016-08-16 16:04:14 +00007656 case X86::BI__builtin_ia32_xsaves64: {
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007657 Intrinsic::ID ID;
7658#define INTRINSIC_X86_XSAVE_ID(NAME) \
7659 case X86::BI__builtin_ia32_##NAME: \
7660 ID = Intrinsic::x86_##NAME; \
7661 break
7662 switch (BuiltinID) {
7663 default: llvm_unreachable("Unsupported intrinsic!");
7664 INTRINSIC_X86_XSAVE_ID(xsave);
7665 INTRINSIC_X86_XSAVE_ID(xsave64);
7666 INTRINSIC_X86_XSAVE_ID(xrstor);
7667 INTRINSIC_X86_XSAVE_ID(xrstor64);
7668 INTRINSIC_X86_XSAVE_ID(xsaveopt);
7669 INTRINSIC_X86_XSAVE_ID(xsaveopt64);
7670 INTRINSIC_X86_XSAVE_ID(xrstors);
7671 INTRINSIC_X86_XSAVE_ID(xrstors64);
7672 INTRINSIC_X86_XSAVE_ID(xsavec);
7673 INTRINSIC_X86_XSAVE_ID(xsavec64);
7674 INTRINSIC_X86_XSAVE_ID(xsaves);
7675 INTRINSIC_X86_XSAVE_ID(xsaves64);
7676 }
7677#undef INTRINSIC_X86_XSAVE_ID
7678 Value *Mhi = Builder.CreateTrunc(
7679 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty);
7680 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty);
7681 Ops[1] = Mhi;
7682 Ops.push_back(Mlo);
7683 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
7684 }
Craig Topper6e891fb2016-05-31 01:50:10 +00007685 case X86::BI__builtin_ia32_storedqudi128_mask:
7686 case X86::BI__builtin_ia32_storedqusi128_mask:
7687 case X86::BI__builtin_ia32_storedquhi128_mask:
7688 case X86::BI__builtin_ia32_storedquqi128_mask:
7689 case X86::BI__builtin_ia32_storeupd128_mask:
7690 case X86::BI__builtin_ia32_storeups128_mask:
7691 case X86::BI__builtin_ia32_storedqudi256_mask:
7692 case X86::BI__builtin_ia32_storedqusi256_mask:
7693 case X86::BI__builtin_ia32_storedquhi256_mask:
7694 case X86::BI__builtin_ia32_storedquqi256_mask:
7695 case X86::BI__builtin_ia32_storeupd256_mask:
7696 case X86::BI__builtin_ia32_storeups256_mask:
7697 case X86::BI__builtin_ia32_storedqudi512_mask:
7698 case X86::BI__builtin_ia32_storedqusi512_mask:
7699 case X86::BI__builtin_ia32_storedquhi512_mask:
7700 case X86::BI__builtin_ia32_storedquqi512_mask:
7701 case X86::BI__builtin_ia32_storeupd512_mask:
7702 case X86::BI__builtin_ia32_storeups512_mask:
7703 return EmitX86MaskedStore(*this, Ops, 1);
7704
Ayman Musae60a41c2016-11-08 12:00:30 +00007705 case X86::BI__builtin_ia32_storess128_mask:
7706 case X86::BI__builtin_ia32_storesd128_mask: {
7707 return EmitX86MaskedStore(*this, Ops, 16);
7708 }
Oren Ben Simhon140c1fb2017-05-25 13:44:11 +00007709 case X86::BI__builtin_ia32_vpopcntd_512:
7710 case X86::BI__builtin_ia32_vpopcntq_512: {
7711 llvm::Type *ResultType = ConvertType(E->getType());
7712 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
7713 return Builder.CreateCall(F, Ops);
7714 }
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007715 case X86::BI__builtin_ia32_cvtmask2b128:
7716 case X86::BI__builtin_ia32_cvtmask2b256:
7717 case X86::BI__builtin_ia32_cvtmask2b512:
7718 case X86::BI__builtin_ia32_cvtmask2w128:
7719 case X86::BI__builtin_ia32_cvtmask2w256:
7720 case X86::BI__builtin_ia32_cvtmask2w512:
7721 case X86::BI__builtin_ia32_cvtmask2d128:
7722 case X86::BI__builtin_ia32_cvtmask2d256:
7723 case X86::BI__builtin_ia32_cvtmask2d512:
7724 case X86::BI__builtin_ia32_cvtmask2q128:
7725 case X86::BI__builtin_ia32_cvtmask2q256:
7726 case X86::BI__builtin_ia32_cvtmask2q512:
7727 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType()));
7728
Craig Topper6e891fb2016-05-31 01:50:10 +00007729 case X86::BI__builtin_ia32_movdqa32store128_mask:
7730 case X86::BI__builtin_ia32_movdqa64store128_mask:
7731 case X86::BI__builtin_ia32_storeaps128_mask:
7732 case X86::BI__builtin_ia32_storeapd128_mask:
7733 case X86::BI__builtin_ia32_movdqa32store256_mask:
7734 case X86::BI__builtin_ia32_movdqa64store256_mask:
7735 case X86::BI__builtin_ia32_storeaps256_mask:
7736 case X86::BI__builtin_ia32_storeapd256_mask:
7737 case X86::BI__builtin_ia32_movdqa32store512_mask:
7738 case X86::BI__builtin_ia32_movdqa64store512_mask:
7739 case X86::BI__builtin_ia32_storeaps512_mask:
7740 case X86::BI__builtin_ia32_storeapd512_mask: {
7741 unsigned Align =
7742 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7743 return EmitX86MaskedStore(*this, Ops, Align);
7744 }
Craig Topper4b060e32016-05-31 06:58:07 +00007745 case X86::BI__builtin_ia32_loadups128_mask:
7746 case X86::BI__builtin_ia32_loadups256_mask:
7747 case X86::BI__builtin_ia32_loadups512_mask:
7748 case X86::BI__builtin_ia32_loadupd128_mask:
7749 case X86::BI__builtin_ia32_loadupd256_mask:
7750 case X86::BI__builtin_ia32_loadupd512_mask:
7751 case X86::BI__builtin_ia32_loaddquqi128_mask:
7752 case X86::BI__builtin_ia32_loaddquqi256_mask:
7753 case X86::BI__builtin_ia32_loaddquqi512_mask:
7754 case X86::BI__builtin_ia32_loaddquhi128_mask:
7755 case X86::BI__builtin_ia32_loaddquhi256_mask:
7756 case X86::BI__builtin_ia32_loaddquhi512_mask:
7757 case X86::BI__builtin_ia32_loaddqusi128_mask:
7758 case X86::BI__builtin_ia32_loaddqusi256_mask:
7759 case X86::BI__builtin_ia32_loaddqusi512_mask:
7760 case X86::BI__builtin_ia32_loaddqudi128_mask:
7761 case X86::BI__builtin_ia32_loaddqudi256_mask:
7762 case X86::BI__builtin_ia32_loaddqudi512_mask:
7763 return EmitX86MaskedLoad(*this, Ops, 1);
7764
Ayman Musae60a41c2016-11-08 12:00:30 +00007765 case X86::BI__builtin_ia32_loadss128_mask:
7766 case X86::BI__builtin_ia32_loadsd128_mask:
7767 return EmitX86MaskedLoad(*this, Ops, 16);
7768
Craig Topper4b060e32016-05-31 06:58:07 +00007769 case X86::BI__builtin_ia32_loadaps128_mask:
7770 case X86::BI__builtin_ia32_loadaps256_mask:
7771 case X86::BI__builtin_ia32_loadaps512_mask:
7772 case X86::BI__builtin_ia32_loadapd128_mask:
7773 case X86::BI__builtin_ia32_loadapd256_mask:
7774 case X86::BI__builtin_ia32_loadapd512_mask:
7775 case X86::BI__builtin_ia32_movdqa32load128_mask:
7776 case X86::BI__builtin_ia32_movdqa32load256_mask:
7777 case X86::BI__builtin_ia32_movdqa32load512_mask:
7778 case X86::BI__builtin_ia32_movdqa64load128_mask:
7779 case X86::BI__builtin_ia32_movdqa64load256_mask:
7780 case X86::BI__builtin_ia32_movdqa64load512_mask: {
7781 unsigned Align =
7782 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7783 return EmitX86MaskedLoad(*this, Ops, Align);
7784 }
Simon Pilgrim2d851732016-07-22 13:58:56 +00007785
7786 case X86::BI__builtin_ia32_vbroadcastf128_pd256:
7787 case X86::BI__builtin_ia32_vbroadcastf128_ps256: {
7788 llvm::Type *DstTy = ConvertType(E->getType());
Chandler Carruth4c5e8cc2016-08-10 07:32:47 +00007789 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1);
Simon Pilgrim2d851732016-07-22 13:58:56 +00007790 }
7791
Nate Begeman91f40e32008-04-14 04:49:57 +00007792 case X86::BI__builtin_ia32_storehps:
7793 case X86::BI__builtin_ia32_storelps: {
Chris Lattner5e016ae2010-06-27 07:15:29 +00007794 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty);
7795 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2);
Mike Stump11289f42009-09-09 15:08:12 +00007796
Nate Begeman91f40e32008-04-14 04:49:57 +00007797 // cast val v2i64
7798 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
Mike Stump11289f42009-09-09 15:08:12 +00007799
Nate Begeman91f40e32008-04-14 04:49:57 +00007800 // extract (0, 1)
7801 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
Michael J. Spencerdd597752014-05-31 00:22:12 +00007802 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index);
Nate Begeman91f40e32008-04-14 04:49:57 +00007803 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
7804
7805 // cast pointer to i64 & store
7806 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00007807 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begeman91f40e32008-04-14 04:49:57 +00007808 }
Craig Topper480e2b62015-02-17 06:37:58 +00007809 case X86::BI__builtin_ia32_palignr128:
Craig Topperf51cc072016-06-06 06:13:01 +00007810 case X86::BI__builtin_ia32_palignr256:
Craig Topperf51cc072016-06-06 06:13:01 +00007811 case X86::BI__builtin_ia32_palignr512_mask: {
Craig Topper480e2b62015-02-17 06:37:58 +00007812 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
Craig Topper94aba2c2011-12-19 07:03:25 +00007813
Craig Topperf2f1a092016-07-08 02:17:35 +00007814 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topper480e2b62015-02-17 06:37:58 +00007815 assert(NumElts % 16 == 0);
Craig Topper480e2b62015-02-17 06:37:58 +00007816
Craig Topper480e2b62015-02-17 06:37:58 +00007817 // If palignr is shifting the pair of vectors more than the size of two
7818 // lanes, emit zero.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007819 if (ShiftVal >= 32)
Craig Topper480e2b62015-02-17 06:37:58 +00007820 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Craig Topper94aba2c2011-12-19 07:03:25 +00007821
Craig Topper480e2b62015-02-17 06:37:58 +00007822 // If palignr is shifting the pair of input vectors more than one lane,
Craig Topper96f9a572015-02-17 07:18:01 +00007823 // but less than two lanes, convert to shifting in zeroes.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007824 if (ShiftVal > 16) {
7825 ShiftVal -= 16;
Benjamin Kramerb5960562015-07-20 15:31:17 +00007826 Ops[1] = Ops[0];
Craig Topper96f9a572015-02-17 07:18:01 +00007827 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType());
Craig Topper94aba2c2011-12-19 07:03:25 +00007828 }
7829
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007830 uint32_t Indices[64];
Craig Topper96f9a572015-02-17 07:18:01 +00007831 // 256-bit palignr operates on 128-bit lanes so we need to handle that
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007832 for (unsigned l = 0; l != NumElts; l += 16) {
7833 for (unsigned i = 0; i != 16; ++i) {
Craig Topper96f9a572015-02-17 07:18:01 +00007834 unsigned Idx = ShiftVal + i;
Craig Topperb8b4b7e2016-05-29 07:06:02 +00007835 if (Idx >= 16)
7836 Idx += NumElts - 16; // End of lane, switch operand.
Benjamin Kramerc385a802015-07-28 15:40:11 +00007837 Indices[l + i] = Idx + l;
Craig Topper96f9a572015-02-17 07:18:01 +00007838 }
7839 }
7840
Craig Topperf51cc072016-06-06 06:13:01 +00007841 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0],
7842 makeArrayRef(Indices, NumElts),
7843 "palignr");
7844
7845 // If this isn't a masked builtin, just return the align operation.
7846 if (Ops.size() == 3)
7847 return Align;
7848
Simon Pilgrim532de1c2016-06-13 10:05:19 +00007849 return EmitX86Select(*this, Ops[4], Align, Ops[3]);
7850 }
7851
7852 case X86::BI__builtin_ia32_movnti:
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007853 case X86::BI__builtin_ia32_movnti64:
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007854 case X86::BI__builtin_ia32_movntsd:
7855 case X86::BI__builtin_ia32_movntss: {
7856 llvm::MDNode *Node = llvm::MDNode::get(
7857 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
7858
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007859 Value *Ptr = Ops[0];
7860 Value *Src = Ops[1];
7861
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007862 // Extract the 0'th element of the source vector.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007863 if (BuiltinID == X86::BI__builtin_ia32_movntsd ||
7864 BuiltinID == X86::BI__builtin_ia32_movntss)
7865 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007866
7867 // Convert the type of the pointer to a pointer to the stored type.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007868 Value *BC = Builder.CreateBitCast(
7869 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007870
7871 // Unaligned nontemporal store of the scalar value.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00007872 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC);
Simon Pilgrimd39d0262016-06-17 14:28:16 +00007873 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
7874 SI->setAlignment(1);
7875 return SI;
7876 }
7877
Simon Pilgrim532de1c2016-06-13 10:05:19 +00007878 case X86::BI__builtin_ia32_selectb_128:
Igor Bregeraadb8762016-06-08 13:59:20 +00007879 case X86::BI__builtin_ia32_selectb_256:
7880 case X86::BI__builtin_ia32_selectb_512:
7881 case X86::BI__builtin_ia32_selectw_128:
7882 case X86::BI__builtin_ia32_selectw_256:
7883 case X86::BI__builtin_ia32_selectw_512:
7884 case X86::BI__builtin_ia32_selectd_128:
7885 case X86::BI__builtin_ia32_selectd_256:
7886 case X86::BI__builtin_ia32_selectd_512:
7887 case X86::BI__builtin_ia32_selectq_128:
7888 case X86::BI__builtin_ia32_selectq_256:
7889 case X86::BI__builtin_ia32_selectq_512:
7890 case X86::BI__builtin_ia32_selectps_128:
7891 case X86::BI__builtin_ia32_selectps_256:
7892 case X86::BI__builtin_ia32_selectps_512:
7893 case X86::BI__builtin_ia32_selectpd_128:
7894 case X86::BI__builtin_ia32_selectpd_256:
7895 case X86::BI__builtin_ia32_selectpd_512:
Craig Topperc1442972016-06-09 05:15:00 +00007896 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]);
Craig Toppera54c21e2016-06-15 14:06:34 +00007897 case X86::BI__builtin_ia32_pcmpeqb128_mask:
7898 case X86::BI__builtin_ia32_pcmpeqb256_mask:
7899 case X86::BI__builtin_ia32_pcmpeqb512_mask:
7900 case X86::BI__builtin_ia32_pcmpeqw128_mask:
7901 case X86::BI__builtin_ia32_pcmpeqw256_mask:
7902 case X86::BI__builtin_ia32_pcmpeqw512_mask:
7903 case X86::BI__builtin_ia32_pcmpeqd128_mask:
7904 case X86::BI__builtin_ia32_pcmpeqd256_mask:
7905 case X86::BI__builtin_ia32_pcmpeqd512_mask:
7906 case X86::BI__builtin_ia32_pcmpeqq128_mask:
7907 case X86::BI__builtin_ia32_pcmpeqq256_mask:
7908 case X86::BI__builtin_ia32_pcmpeqq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00007909 return EmitX86MaskedCompare(*this, 0, false, Ops);
Craig Toppera54c21e2016-06-15 14:06:34 +00007910 case X86::BI__builtin_ia32_pcmpgtb128_mask:
7911 case X86::BI__builtin_ia32_pcmpgtb256_mask:
7912 case X86::BI__builtin_ia32_pcmpgtb512_mask:
7913 case X86::BI__builtin_ia32_pcmpgtw128_mask:
7914 case X86::BI__builtin_ia32_pcmpgtw256_mask:
7915 case X86::BI__builtin_ia32_pcmpgtw512_mask:
7916 case X86::BI__builtin_ia32_pcmpgtd128_mask:
7917 case X86::BI__builtin_ia32_pcmpgtd256_mask:
7918 case X86::BI__builtin_ia32_pcmpgtd512_mask:
7919 case X86::BI__builtin_ia32_pcmpgtq128_mask:
7920 case X86::BI__builtin_ia32_pcmpgtq256_mask:
7921 case X86::BI__builtin_ia32_pcmpgtq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00007922 return EmitX86MaskedCompare(*this, 6, true, Ops);
7923 case X86::BI__builtin_ia32_cmpb128_mask:
7924 case X86::BI__builtin_ia32_cmpb256_mask:
7925 case X86::BI__builtin_ia32_cmpb512_mask:
7926 case X86::BI__builtin_ia32_cmpw128_mask:
7927 case X86::BI__builtin_ia32_cmpw256_mask:
7928 case X86::BI__builtin_ia32_cmpw512_mask:
7929 case X86::BI__builtin_ia32_cmpd128_mask:
7930 case X86::BI__builtin_ia32_cmpd256_mask:
7931 case X86::BI__builtin_ia32_cmpd512_mask:
7932 case X86::BI__builtin_ia32_cmpq128_mask:
7933 case X86::BI__builtin_ia32_cmpq256_mask:
7934 case X86::BI__builtin_ia32_cmpq512_mask: {
7935 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
7936 return EmitX86MaskedCompare(*this, CC, true, Ops);
7937 }
7938 case X86::BI__builtin_ia32_ucmpb128_mask:
7939 case X86::BI__builtin_ia32_ucmpb256_mask:
7940 case X86::BI__builtin_ia32_ucmpb512_mask:
7941 case X86::BI__builtin_ia32_ucmpw128_mask:
7942 case X86::BI__builtin_ia32_ucmpw256_mask:
7943 case X86::BI__builtin_ia32_ucmpw512_mask:
7944 case X86::BI__builtin_ia32_ucmpd128_mask:
7945 case X86::BI__builtin_ia32_ucmpd256_mask:
7946 case X86::BI__builtin_ia32_ucmpd512_mask:
7947 case X86::BI__builtin_ia32_ucmpq128_mask:
7948 case X86::BI__builtin_ia32_ucmpq256_mask:
7949 case X86::BI__builtin_ia32_ucmpq512_mask: {
7950 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
7951 return EmitX86MaskedCompare(*this, CC, false, Ops);
7952 }
Sanjay Patel7495ec02016-06-15 17:18:50 +00007953
Craig Topper46e75552016-07-06 04:24:29 +00007954 case X86::BI__builtin_ia32_vplzcntd_128_mask:
7955 case X86::BI__builtin_ia32_vplzcntd_256_mask:
7956 case X86::BI__builtin_ia32_vplzcntd_512_mask:
7957 case X86::BI__builtin_ia32_vplzcntq_128_mask:
7958 case X86::BI__builtin_ia32_vplzcntq_256_mask:
7959 case X86::BI__builtin_ia32_vplzcntq_512_mask: {
7960 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType());
7961 return EmitX86Select(*this, Ops[2],
7962 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}),
7963 Ops[1]);
7964 }
7965
Sanjay Patel7495ec02016-06-15 17:18:50 +00007966 case X86::BI__builtin_ia32_pmaxsb128:
7967 case X86::BI__builtin_ia32_pmaxsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00007968 case X86::BI__builtin_ia32_pmaxsd128:
Craig Topper531ce282016-10-24 04:04:24 +00007969 case X86::BI__builtin_ia32_pmaxsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00007970 case X86::BI__builtin_ia32_pmaxsb256:
7971 case X86::BI__builtin_ia32_pmaxsw256:
Craig Topper531ce282016-10-24 04:04:24 +00007972 case X86::BI__builtin_ia32_pmaxsd256:
7973 case X86::BI__builtin_ia32_pmaxsq256_mask:
7974 case X86::BI__builtin_ia32_pmaxsb512_mask:
7975 case X86::BI__builtin_ia32_pmaxsw512_mask:
7976 case X86::BI__builtin_ia32_pmaxsd512_mask:
7977 case X86::BI__builtin_ia32_pmaxsq512_mask:
7978 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00007979 case X86::BI__builtin_ia32_pmaxub128:
7980 case X86::BI__builtin_ia32_pmaxuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00007981 case X86::BI__builtin_ia32_pmaxud128:
Craig Topper531ce282016-10-24 04:04:24 +00007982 case X86::BI__builtin_ia32_pmaxuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00007983 case X86::BI__builtin_ia32_pmaxub256:
7984 case X86::BI__builtin_ia32_pmaxuw256:
Craig Topper531ce282016-10-24 04:04:24 +00007985 case X86::BI__builtin_ia32_pmaxud256:
7986 case X86::BI__builtin_ia32_pmaxuq256_mask:
7987 case X86::BI__builtin_ia32_pmaxub512_mask:
7988 case X86::BI__builtin_ia32_pmaxuw512_mask:
7989 case X86::BI__builtin_ia32_pmaxud512_mask:
7990 case X86::BI__builtin_ia32_pmaxuq512_mask:
7991 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00007992 case X86::BI__builtin_ia32_pminsb128:
7993 case X86::BI__builtin_ia32_pminsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00007994 case X86::BI__builtin_ia32_pminsd128:
Craig Topper531ce282016-10-24 04:04:24 +00007995 case X86::BI__builtin_ia32_pminsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00007996 case X86::BI__builtin_ia32_pminsb256:
7997 case X86::BI__builtin_ia32_pminsw256:
Craig Topper531ce282016-10-24 04:04:24 +00007998 case X86::BI__builtin_ia32_pminsd256:
7999 case X86::BI__builtin_ia32_pminsq256_mask:
8000 case X86::BI__builtin_ia32_pminsb512_mask:
8001 case X86::BI__builtin_ia32_pminsw512_mask:
8002 case X86::BI__builtin_ia32_pminsd512_mask:
8003 case X86::BI__builtin_ia32_pminsq512_mask:
8004 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008005 case X86::BI__builtin_ia32_pminub128:
8006 case X86::BI__builtin_ia32_pminuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008007 case X86::BI__builtin_ia32_pminud128:
Craig Topper531ce282016-10-24 04:04:24 +00008008 case X86::BI__builtin_ia32_pminuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008009 case X86::BI__builtin_ia32_pminub256:
8010 case X86::BI__builtin_ia32_pminuw256:
Craig Topper531ce282016-10-24 04:04:24 +00008011 case X86::BI__builtin_ia32_pminud256:
8012 case X86::BI__builtin_ia32_pminuq256_mask:
8013 case X86::BI__builtin_ia32_pminub512_mask:
8014 case X86::BI__builtin_ia32_pminuw512_mask:
8015 case X86::BI__builtin_ia32_pminud512_mask:
8016 case X86::BI__builtin_ia32_pminuq512_mask:
8017 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008018
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008019 // 3DNow!
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008020 case X86::BI__builtin_ia32_pswapdsf:
8021 case X86::BI__builtin_ia32_pswapdsi: {
Chandler Carrutha2a54102012-02-20 07:35:45 +00008022 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext());
8023 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast");
Craig Topperd2f814d2015-02-16 21:30:08 +00008024 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd);
8025 return Builder.CreateCall(F, Ops, "pswapd");
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008026 }
Benjamin Kramera43b6992012-07-12 09:33:03 +00008027 case X86::BI__builtin_ia32_rdrand16_step:
8028 case X86::BI__builtin_ia32_rdrand32_step:
Michael Liaoffaae352013-03-29 05:17:55 +00008029 case X86::BI__builtin_ia32_rdrand64_step:
8030 case X86::BI__builtin_ia32_rdseed16_step:
8031 case X86::BI__builtin_ia32_rdseed32_step:
8032 case X86::BI__builtin_ia32_rdseed64_step: {
Benjamin Kramera43b6992012-07-12 09:33:03 +00008033 Intrinsic::ID ID;
8034 switch (BuiltinID) {
8035 default: llvm_unreachable("Unsupported intrinsic!");
8036 case X86::BI__builtin_ia32_rdrand16_step:
8037 ID = Intrinsic::x86_rdrand_16;
8038 break;
8039 case X86::BI__builtin_ia32_rdrand32_step:
8040 ID = Intrinsic::x86_rdrand_32;
8041 break;
8042 case X86::BI__builtin_ia32_rdrand64_step:
8043 ID = Intrinsic::x86_rdrand_64;
8044 break;
Michael Liaoffaae352013-03-29 05:17:55 +00008045 case X86::BI__builtin_ia32_rdseed16_step:
8046 ID = Intrinsic::x86_rdseed_16;
8047 break;
8048 case X86::BI__builtin_ia32_rdseed32_step:
8049 ID = Intrinsic::x86_rdseed_32;
8050 break;
8051 case X86::BI__builtin_ia32_rdseed64_step:
8052 ID = Intrinsic::x86_rdseed_64;
8053 break;
Benjamin Kramera43b6992012-07-12 09:33:03 +00008054 }
8055
David Blaikie4ba525b2015-07-14 17:27:39 +00008056 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID));
John McCall7f416cc2015-09-08 08:05:57 +00008057 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0),
8058 Ops[0]);
Benjamin Kramera43b6992012-07-12 09:33:03 +00008059 return Builder.CreateExtractValue(Call, 1);
8060 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008061
8062 // SSE packed comparison intrinsics
Craig Topper2094d8f2014-12-27 06:59:57 +00008063 case X86::BI__builtin_ia32_cmpeqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008064 case X86::BI__builtin_ia32_cmpeqpd:
Craig Topper01600632016-07-08 01:57:24 +00008065 return getVectorFCmpIR(CmpInst::FCMP_OEQ);
Craig Topper925ef0a2016-07-08 01:48:44 +00008066 case X86::BI__builtin_ia32_cmpltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008067 case X86::BI__builtin_ia32_cmpltpd:
Craig Topper01600632016-07-08 01:57:24 +00008068 return getVectorFCmpIR(CmpInst::FCMP_OLT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008069 case X86::BI__builtin_ia32_cmpleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008070 case X86::BI__builtin_ia32_cmplepd:
Craig Topper01600632016-07-08 01:57:24 +00008071 return getVectorFCmpIR(CmpInst::FCMP_OLE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008072 case X86::BI__builtin_ia32_cmpunordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008073 case X86::BI__builtin_ia32_cmpunordpd:
Craig Topper01600632016-07-08 01:57:24 +00008074 return getVectorFCmpIR(CmpInst::FCMP_UNO);
Craig Topper925ef0a2016-07-08 01:48:44 +00008075 case X86::BI__builtin_ia32_cmpneqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008076 case X86::BI__builtin_ia32_cmpneqpd:
Craig Topper01600632016-07-08 01:57:24 +00008077 return getVectorFCmpIR(CmpInst::FCMP_UNE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008078 case X86::BI__builtin_ia32_cmpnltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008079 case X86::BI__builtin_ia32_cmpnltpd:
Craig Topper01600632016-07-08 01:57:24 +00008080 return getVectorFCmpIR(CmpInst::FCMP_UGE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008081 case X86::BI__builtin_ia32_cmpnleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008082 case X86::BI__builtin_ia32_cmpnlepd:
Craig Topper01600632016-07-08 01:57:24 +00008083 return getVectorFCmpIR(CmpInst::FCMP_UGT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008084 case X86::BI__builtin_ia32_cmpordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008085 case X86::BI__builtin_ia32_cmpordpd:
Craig Topper01600632016-07-08 01:57:24 +00008086 return getVectorFCmpIR(CmpInst::FCMP_ORD);
Craig Topper425d02d2016-07-06 06:27:31 +00008087 case X86::BI__builtin_ia32_cmpps:
8088 case X86::BI__builtin_ia32_cmpps256:
8089 case X86::BI__builtin_ia32_cmppd:
8090 case X86::BI__builtin_ia32_cmppd256: {
8091 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
8092 // If this one of the SSE immediates, we can use native IR.
8093 if (CC < 8) {
8094 FCmpInst::Predicate Pred;
8095 switch (CC) {
8096 case 0: Pred = FCmpInst::FCMP_OEQ; break;
8097 case 1: Pred = FCmpInst::FCMP_OLT; break;
8098 case 2: Pred = FCmpInst::FCMP_OLE; break;
8099 case 3: Pred = FCmpInst::FCMP_UNO; break;
8100 case 4: Pred = FCmpInst::FCMP_UNE; break;
8101 case 5: Pred = FCmpInst::FCMP_UGE; break;
8102 case 6: Pred = FCmpInst::FCMP_UGT; break;
8103 case 7: Pred = FCmpInst::FCMP_ORD; break;
8104 }
Craig Topper01600632016-07-08 01:57:24 +00008105 return getVectorFCmpIR(Pred);
Craig Topper425d02d2016-07-06 06:27:31 +00008106 }
8107
8108 // We can't handle 8-31 immediates with native IR, use the intrinsic.
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008109 // Except for predicates that create constants.
Craig Topper425d02d2016-07-06 06:27:31 +00008110 Intrinsic::ID ID;
8111 switch (BuiltinID) {
8112 default: llvm_unreachable("Unsupported intrinsic!");
8113 case X86::BI__builtin_ia32_cmpps:
8114 ID = Intrinsic::x86_sse_cmp_ps;
8115 break;
8116 case X86::BI__builtin_ia32_cmpps256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008117 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8118 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8119 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8120 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8121 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) :
8122 llvm::Constant::getNullValue(Builder.getInt32Ty());
8123 Value *Vec = Builder.CreateVectorSplat(
8124 Ops[0]->getType()->getVectorNumElements(), Constant);
8125 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8126 }
Craig Topper425d02d2016-07-06 06:27:31 +00008127 ID = Intrinsic::x86_avx_cmp_ps_256;
8128 break;
8129 case X86::BI__builtin_ia32_cmppd:
8130 ID = Intrinsic::x86_sse2_cmp_pd;
8131 break;
8132 case X86::BI__builtin_ia32_cmppd256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008133 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8134 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8135 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8136 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8137 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) :
8138 llvm::Constant::getNullValue(Builder.getInt64Ty());
8139 Value *Vec = Builder.CreateVectorSplat(
8140 Ops[0]->getType()->getVectorNumElements(), Constant);
8141 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8142 }
Craig Topper425d02d2016-07-06 06:27:31 +00008143 ID = Intrinsic::x86_avx_cmp_pd_256;
8144 break;
8145 }
8146
8147 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
8148 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008149
8150 // SSE scalar comparison intrinsics
8151 case X86::BI__builtin_ia32_cmpeqss:
8152 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0);
8153 case X86::BI__builtin_ia32_cmpltss:
8154 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1);
8155 case X86::BI__builtin_ia32_cmpless:
8156 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2);
8157 case X86::BI__builtin_ia32_cmpunordss:
8158 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3);
8159 case X86::BI__builtin_ia32_cmpneqss:
8160 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4);
8161 case X86::BI__builtin_ia32_cmpnltss:
8162 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5);
8163 case X86::BI__builtin_ia32_cmpnless:
8164 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6);
8165 case X86::BI__builtin_ia32_cmpordss:
8166 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7);
Craig Topper2094d8f2014-12-27 06:59:57 +00008167 case X86::BI__builtin_ia32_cmpeqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008168 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0);
Craig Topper2094d8f2014-12-27 06:59:57 +00008169 case X86::BI__builtin_ia32_cmpltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008170 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1);
Craig Topper2094d8f2014-12-27 06:59:57 +00008171 case X86::BI__builtin_ia32_cmplesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008172 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2);
Craig Topper2094d8f2014-12-27 06:59:57 +00008173 case X86::BI__builtin_ia32_cmpunordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008174 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3);
Craig Topper2094d8f2014-12-27 06:59:57 +00008175 case X86::BI__builtin_ia32_cmpneqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008176 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4);
Craig Topper2094d8f2014-12-27 06:59:57 +00008177 case X86::BI__builtin_ia32_cmpnltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008178 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5);
Craig Topper2094d8f2014-12-27 06:59:57 +00008179 case X86::BI__builtin_ia32_cmpnlesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008180 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6);
Craig Topper2094d8f2014-12-27 06:59:57 +00008181 case X86::BI__builtin_ia32_cmpordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008182 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008183
Albert Gutowski7216f172016-10-10 18:09:27 +00008184 case X86::BI__emul:
8185 case X86::BI__emulu: {
8186 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64);
8187 bool isSigned = (BuiltinID == X86::BI__emul);
8188 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned);
8189 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned);
8190 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned);
8191 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008192 case X86::BI__mulh:
Albert Gutowski7216f172016-10-10 18:09:27 +00008193 case X86::BI__umulh:
8194 case X86::BI_mul128:
8195 case X86::BI_umul128: {
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008196 llvm::Type *ResType = ConvertType(E->getType());
8197 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
8198
Albert Gutowski7216f172016-10-10 18:09:27 +00008199 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128);
8200 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned);
8201 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008202
8203 Value *MulResult, *HigherBits;
8204 if (IsSigned) {
8205 MulResult = Builder.CreateNSWMul(LHS, RHS);
8206 HigherBits = Builder.CreateAShr(MulResult, 64);
8207 } else {
8208 MulResult = Builder.CreateNUWMul(LHS, RHS);
8209 HigherBits = Builder.CreateLShr(MulResult, 64);
8210 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008211 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned);
Albert Gutowski7216f172016-10-10 18:09:27 +00008212
8213 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh)
8214 return HigherBits;
8215
8216 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2));
8217 Builder.CreateStore(HigherBits, HighBitsAddress);
8218 return Builder.CreateIntCast(MulResult, ResType, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008219 }
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008220
8221 case X86::BI__faststorefence: {
8222 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008223 llvm::SyncScope::System);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008224 }
8225 case X86::BI_ReadWriteBarrier:
8226 case X86::BI_ReadBarrier:
8227 case X86::BI_WriteBarrier: {
8228 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008229 llvm::SyncScope::SingleThread);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008230 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00008231 case X86::BI_BitScanForward:
8232 case X86::BI_BitScanForward64:
8233 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
8234 case X86::BI_BitScanReverse:
8235 case X86::BI_BitScanReverse64:
8236 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00008237
8238 case X86::BI_InterlockedAnd64:
8239 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
8240 case X86::BI_InterlockedExchange64:
8241 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
8242 case X86::BI_InterlockedExchangeAdd64:
8243 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
8244 case X86::BI_InterlockedExchangeSub64:
8245 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
8246 case X86::BI_InterlockedOr64:
8247 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
8248 case X86::BI_InterlockedXor64:
8249 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
8250 case X86::BI_InterlockedDecrement64:
8251 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
8252 case X86::BI_InterlockedIncrement64:
8253 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
8254
Albert Gutowski397d81b2016-10-13 16:03:42 +00008255 case X86::BI_AddressOfReturnAddress: {
8256 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
8257 return Builder.CreateCall(F);
8258 }
Albert Gutowski1deab382016-10-14 17:33:05 +00008259 case X86::BI__stosb: {
8260 // We treat __stosb as a volatile memset - it may not generate "rep stosb"
8261 // instruction, but it will create a memset that won't be optimized away.
8262 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true);
8263 }
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008264 case X86::BI__ud2:
8265 // llvm.trap makes a ud2a instruction on x86.
8266 return EmitTrapCall(Intrinsic::trap);
8267 case X86::BI__int2c: {
8268 // This syscall signals a driver assertion failure in x86 NT kernels.
8269 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
8270 llvm::InlineAsm *IA =
8271 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true);
Reid Klecknerde864822017-03-21 16:57:30 +00008272 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
8273 getLLVMContext(), llvm::AttributeList::FunctionIndex,
8274 llvm::Attribute::NoReturn);
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008275 CallSite CS = Builder.CreateCall(IA);
8276 CS.setAttributes(NoReturnAttr);
8277 return CS.getInstruction();
8278 }
Hans Wennborg043f4022017-03-22 19:13:13 +00008279 case X86::BI__readfsbyte:
8280 case X86::BI__readfsword:
8281 case X86::BI__readfsdword:
8282 case X86::BI__readfsqword: {
8283 llvm::Type *IntTy = ConvertType(E->getType());
8284 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8285 llvm::PointerType::get(IntTy, 257));
8286 LoadInst *Load = Builder.CreateAlignedLoad(
8287 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8288 Load->setVolatile(true);
8289 return Load;
8290 }
8291 case X86::BI__readgsbyte:
8292 case X86::BI__readgsword:
8293 case X86::BI__readgsdword:
8294 case X86::BI__readgsqword: {
8295 llvm::Type *IntTy = ConvertType(E->getType());
8296 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8297 llvm::PointerType::get(IntTy, 256));
8298 LoadInst *Load = Builder.CreateAlignedLoad(
8299 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8300 Load->setVolatile(true);
8301 return Load;
8302 }
Anders Carlsson895af082007-12-09 23:17:02 +00008303 }
8304}
8305
Tony Linthicum76329bf2011-12-12 21:14:55 +00008306
Mike Stump11289f42009-09-09 15:08:12 +00008307Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00008308 const CallExpr *E) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00008309 SmallVector<Value*, 4> Ops;
Chris Lattnerdad40622010-04-14 03:54:58 +00008310
8311 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
8312 Ops.push_back(EmitScalarExpr(E->getArg(i)));
8313
8314 Intrinsic::ID ID = Intrinsic::not_intrinsic;
8315
8316 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00008317 default: return nullptr;
Chris Lattnerdad40622010-04-14 03:54:58 +00008318
Hal Finkel65e1e4d2015-08-31 23:55:19 +00008319 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we
8320 // call __builtin_readcyclecounter.
8321 case PPC::BI__builtin_ppc_get_timebase:
8322 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter));
8323
Tony Jiang6a49aad2016-11-15 14:30:56 +00008324 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008325 case PPC::BI__builtin_altivec_lvx:
8326 case PPC::BI__builtin_altivec_lvxl:
8327 case PPC::BI__builtin_altivec_lvebx:
8328 case PPC::BI__builtin_altivec_lvehx:
8329 case PPC::BI__builtin_altivec_lvewx:
8330 case PPC::BI__builtin_altivec_lvsl:
8331 case PPC::BI__builtin_altivec_lvsr:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008332 case PPC::BI__builtin_vsx_lxvd2x:
8333 case PPC::BI__builtin_vsx_lxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008334 case PPC::BI__builtin_vsx_lxvd2x_be:
8335 case PPC::BI__builtin_vsx_lxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008336 case PPC::BI__builtin_vsx_lxvl:
8337 case PPC::BI__builtin_vsx_lxvll:
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008338 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008339 if(BuiltinID == PPC::BI__builtin_vsx_lxvl ||
8340 BuiltinID == PPC::BI__builtin_vsx_lxvll){
8341 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
8342 }else {
8343 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8344 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]);
8345 Ops.pop_back();
8346 }
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008347
8348 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008349 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008350 case PPC::BI__builtin_altivec_lvx:
8351 ID = Intrinsic::ppc_altivec_lvx;
8352 break;
8353 case PPC::BI__builtin_altivec_lvxl:
8354 ID = Intrinsic::ppc_altivec_lvxl;
8355 break;
8356 case PPC::BI__builtin_altivec_lvebx:
8357 ID = Intrinsic::ppc_altivec_lvebx;
8358 break;
8359 case PPC::BI__builtin_altivec_lvehx:
8360 ID = Intrinsic::ppc_altivec_lvehx;
8361 break;
8362 case PPC::BI__builtin_altivec_lvewx:
8363 ID = Intrinsic::ppc_altivec_lvewx;
8364 break;
8365 case PPC::BI__builtin_altivec_lvsl:
8366 ID = Intrinsic::ppc_altivec_lvsl;
8367 break;
8368 case PPC::BI__builtin_altivec_lvsr:
8369 ID = Intrinsic::ppc_altivec_lvsr;
8370 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008371 case PPC::BI__builtin_vsx_lxvd2x:
8372 ID = Intrinsic::ppc_vsx_lxvd2x;
8373 break;
8374 case PPC::BI__builtin_vsx_lxvw4x:
8375 ID = Intrinsic::ppc_vsx_lxvw4x;
8376 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008377 case PPC::BI__builtin_vsx_lxvd2x_be:
8378 ID = Intrinsic::ppc_vsx_lxvd2x_be;
8379 break;
8380 case PPC::BI__builtin_vsx_lxvw4x_be:
8381 ID = Intrinsic::ppc_vsx_lxvw4x_be;
8382 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008383 case PPC::BI__builtin_vsx_lxvl:
8384 ID = Intrinsic::ppc_vsx_lxvl;
8385 break;
8386 case PPC::BI__builtin_vsx_lxvll:
8387 ID = Intrinsic::ppc_vsx_lxvll;
8388 break;
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008389 }
8390 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008391 return Builder.CreateCall(F, Ops, "");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008392 }
8393
Tony Jiang6a49aad2016-11-15 14:30:56 +00008394 // vec_st, vec_xst_be
Chris Lattnerdad40622010-04-14 03:54:58 +00008395 case PPC::BI__builtin_altivec_stvx:
8396 case PPC::BI__builtin_altivec_stvxl:
8397 case PPC::BI__builtin_altivec_stvebx:
8398 case PPC::BI__builtin_altivec_stvehx:
8399 case PPC::BI__builtin_altivec_stvewx:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008400 case PPC::BI__builtin_vsx_stxvd2x:
8401 case PPC::BI__builtin_vsx_stxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008402 case PPC::BI__builtin_vsx_stxvd2x_be:
8403 case PPC::BI__builtin_vsx_stxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008404 case PPC::BI__builtin_vsx_stxvl:
8405 case PPC::BI__builtin_vsx_stxvll:
Chris Lattnerdad40622010-04-14 03:54:58 +00008406 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008407 if(BuiltinID == PPC::BI__builtin_vsx_stxvl ||
8408 BuiltinID == PPC::BI__builtin_vsx_stxvll ){
8409 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8410 }else {
8411 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy);
8412 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]);
8413 Ops.pop_back();
8414 }
Chris Lattnerdad40622010-04-14 03:54:58 +00008415
8416 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008417 default: llvm_unreachable("Unsupported st intrinsic!");
Chris Lattnerdad40622010-04-14 03:54:58 +00008418 case PPC::BI__builtin_altivec_stvx:
8419 ID = Intrinsic::ppc_altivec_stvx;
8420 break;
8421 case PPC::BI__builtin_altivec_stvxl:
8422 ID = Intrinsic::ppc_altivec_stvxl;
8423 break;
8424 case PPC::BI__builtin_altivec_stvebx:
8425 ID = Intrinsic::ppc_altivec_stvebx;
8426 break;
8427 case PPC::BI__builtin_altivec_stvehx:
8428 ID = Intrinsic::ppc_altivec_stvehx;
8429 break;
8430 case PPC::BI__builtin_altivec_stvewx:
8431 ID = Intrinsic::ppc_altivec_stvewx;
8432 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008433 case PPC::BI__builtin_vsx_stxvd2x:
8434 ID = Intrinsic::ppc_vsx_stxvd2x;
8435 break;
8436 case PPC::BI__builtin_vsx_stxvw4x:
8437 ID = Intrinsic::ppc_vsx_stxvw4x;
8438 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008439 case PPC::BI__builtin_vsx_stxvd2x_be:
8440 ID = Intrinsic::ppc_vsx_stxvd2x_be;
8441 break;
8442 case PPC::BI__builtin_vsx_stxvw4x_be:
8443 ID = Intrinsic::ppc_vsx_stxvw4x_be;
8444 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008445 case PPC::BI__builtin_vsx_stxvl:
8446 ID = Intrinsic::ppc_vsx_stxvl;
8447 break;
8448 case PPC::BI__builtin_vsx_stxvll:
8449 ID = Intrinsic::ppc_vsx_stxvll;
8450 break;
Chris Lattnerdad40622010-04-14 03:54:58 +00008451 }
8452 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008453 return Builder.CreateCall(F, Ops, "");
Chris Lattnerdad40622010-04-14 03:54:58 +00008454 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008455 // Square root
8456 case PPC::BI__builtin_vsx_xvsqrtsp:
8457 case PPC::BI__builtin_vsx_xvsqrtdp: {
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008458 llvm::Type *ResultType = ConvertType(E->getType());
8459 Value *X = EmitScalarExpr(E->getArg(0));
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008460 ID = Intrinsic::sqrt;
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008461 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8462 return Builder.CreateCall(F, X);
Chris Lattnerdad40622010-04-14 03:54:58 +00008463 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008464 // Count leading zeros
8465 case PPC::BI__builtin_altivec_vclzb:
8466 case PPC::BI__builtin_altivec_vclzh:
8467 case PPC::BI__builtin_altivec_vclzw:
8468 case PPC::BI__builtin_altivec_vclzd: {
8469 llvm::Type *ResultType = ConvertType(E->getType());
8470 Value *X = EmitScalarExpr(E->getArg(0));
8471 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8472 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
8473 return Builder.CreateCall(F, {X, Undef});
8474 }
Nemanja Ivanovic10e2b5d2016-09-27 10:45:22 +00008475 case PPC::BI__builtin_altivec_vctzb:
8476 case PPC::BI__builtin_altivec_vctzh:
8477 case PPC::BI__builtin_altivec_vctzw:
8478 case PPC::BI__builtin_altivec_vctzd: {
8479 llvm::Type *ResultType = ConvertType(E->getType());
8480 Value *X = EmitScalarExpr(E->getArg(0));
8481 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8482 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
8483 return Builder.CreateCall(F, {X, Undef});
8484 }
8485 case PPC::BI__builtin_altivec_vpopcntb:
8486 case PPC::BI__builtin_altivec_vpopcnth:
8487 case PPC::BI__builtin_altivec_vpopcntw:
8488 case PPC::BI__builtin_altivec_vpopcntd: {
8489 llvm::Type *ResultType = ConvertType(E->getType());
8490 Value *X = EmitScalarExpr(E->getArg(0));
8491 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
8492 return Builder.CreateCall(F, X);
8493 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008494 // Copy sign
8495 case PPC::BI__builtin_vsx_xvcpsgnsp:
8496 case PPC::BI__builtin_vsx_xvcpsgndp: {
8497 llvm::Type *ResultType = ConvertType(E->getType());
8498 Value *X = EmitScalarExpr(E->getArg(0));
8499 Value *Y = EmitScalarExpr(E->getArg(1));
8500 ID = Intrinsic::copysign;
8501 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8502 return Builder.CreateCall(F, {X, Y});
8503 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008504 // Rounding/truncation
8505 case PPC::BI__builtin_vsx_xvrspip:
8506 case PPC::BI__builtin_vsx_xvrdpip:
8507 case PPC::BI__builtin_vsx_xvrdpim:
8508 case PPC::BI__builtin_vsx_xvrspim:
8509 case PPC::BI__builtin_vsx_xvrdpi:
8510 case PPC::BI__builtin_vsx_xvrspi:
8511 case PPC::BI__builtin_vsx_xvrdpic:
8512 case PPC::BI__builtin_vsx_xvrspic:
8513 case PPC::BI__builtin_vsx_xvrdpiz:
8514 case PPC::BI__builtin_vsx_xvrspiz: {
8515 llvm::Type *ResultType = ConvertType(E->getType());
8516 Value *X = EmitScalarExpr(E->getArg(0));
8517 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
8518 BuiltinID == PPC::BI__builtin_vsx_xvrspim)
8519 ID = Intrinsic::floor;
8520 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
8521 BuiltinID == PPC::BI__builtin_vsx_xvrspi)
8522 ID = Intrinsic::round;
8523 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
8524 BuiltinID == PPC::BI__builtin_vsx_xvrspic)
8525 ID = Intrinsic::nearbyint;
8526 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
8527 BuiltinID == PPC::BI__builtin_vsx_xvrspip)
8528 ID = Intrinsic::ceil;
8529 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
8530 BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
8531 ID = Intrinsic::trunc;
8532 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8533 return Builder.CreateCall(F, X);
8534 }
Kit Bartonfbab1582016-03-09 19:28:31 +00008535
8536 // Absolute value
8537 case PPC::BI__builtin_vsx_xvabsdp:
8538 case PPC::BI__builtin_vsx_xvabssp: {
8539 llvm::Type *ResultType = ConvertType(E->getType());
8540 Value *X = EmitScalarExpr(E->getArg(0));
8541 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
8542 return Builder.CreateCall(F, X);
8543 }
8544
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008545 // FMA variations
8546 case PPC::BI__builtin_vsx_xvmaddadp:
8547 case PPC::BI__builtin_vsx_xvmaddasp:
8548 case PPC::BI__builtin_vsx_xvnmaddadp:
8549 case PPC::BI__builtin_vsx_xvnmaddasp:
8550 case PPC::BI__builtin_vsx_xvmsubadp:
8551 case PPC::BI__builtin_vsx_xvmsubasp:
8552 case PPC::BI__builtin_vsx_xvnmsubadp:
8553 case PPC::BI__builtin_vsx_xvnmsubasp: {
8554 llvm::Type *ResultType = ConvertType(E->getType());
8555 Value *X = EmitScalarExpr(E->getArg(0));
8556 Value *Y = EmitScalarExpr(E->getArg(1));
8557 Value *Z = EmitScalarExpr(E->getArg(2));
8558 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
8559 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
8560 switch (BuiltinID) {
8561 case PPC::BI__builtin_vsx_xvmaddadp:
8562 case PPC::BI__builtin_vsx_xvmaddasp:
8563 return Builder.CreateCall(F, {X, Y, Z});
8564 case PPC::BI__builtin_vsx_xvnmaddadp:
8565 case PPC::BI__builtin_vsx_xvnmaddasp:
8566 return Builder.CreateFSub(Zero,
8567 Builder.CreateCall(F, {X, Y, Z}), "sub");
8568 case PPC::BI__builtin_vsx_xvmsubadp:
8569 case PPC::BI__builtin_vsx_xvmsubasp:
8570 return Builder.CreateCall(F,
8571 {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8572 case PPC::BI__builtin_vsx_xvnmsubadp:
8573 case PPC::BI__builtin_vsx_xvnmsubasp:
8574 Value *FsubRes =
8575 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8576 return Builder.CreateFSub(Zero, FsubRes, "sub");
8577 }
8578 llvm_unreachable("Unknown FMA operation");
8579 return nullptr; // Suppress no-return warning
8580 }
Sean Fertile96d9e0e2017-01-05 21:43:30 +00008581
8582 case PPC::BI__builtin_vsx_insertword: {
8583 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
8584
8585 // Third argument is a compile time constant int. It must be clamped to
8586 // to the range [0, 12].
8587 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8588 assert(ArgCI &&
8589 "Third arg to xxinsertw intrinsic must be constant integer");
8590 const int64_t MaxIndex = 12;
8591 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8592
8593 // The builtin semantics don't exactly match the xxinsertw instructions
8594 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the
8595 // word from the first argument, and inserts it in the second argument. The
8596 // instruction extracts the word from its second input register and inserts
8597 // it into its first input register, so swap the first and second arguments.
8598 std::swap(Ops[0], Ops[1]);
8599
8600 // Need to cast the second argument from a vector of unsigned int to a
8601 // vector of long long.
8602 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8603
8604 if (getTarget().isLittleEndian()) {
8605 // Create a shuffle mask of (1, 0)
8606 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8607 ConstantInt::get(Int32Ty, 0)
8608 };
8609 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8610
8611 // Reverse the double words in the vector we will extract from.
8612 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8613 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask);
8614
8615 // Reverse the index.
8616 Index = MaxIndex - Index;
8617 }
8618
8619 // Intrinsic expects the first arg to be a vector of int.
8620 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8621 Ops[2] = ConstantInt::getSigned(Int32Ty, Index);
8622 return Builder.CreateCall(F, Ops);
8623 }
8624
8625 case PPC::BI__builtin_vsx_extractuword: {
8626 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
8627
8628 // Intrinsic expects the first argument to be a vector of doublewords.
8629 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8630
8631 // The second argument is a compile time constant int that needs to
8632 // be clamped to the range [0, 12].
8633 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]);
8634 assert(ArgCI &&
8635 "Second Arg to xxextractuw intrinsic must be a constant integer!");
8636 const int64_t MaxIndex = 12;
8637 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8638
8639 if (getTarget().isLittleEndian()) {
8640 // Reverse the index.
8641 Index = MaxIndex - Index;
8642 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8643
8644 // Emit the call, then reverse the double words of the results vector.
8645 Value *Call = Builder.CreateCall(F, Ops);
8646
8647 // Create a shuffle mask of (1, 0)
8648 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8649 ConstantInt::get(Int32Ty, 0)
8650 };
8651 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8652
8653 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask);
8654 return ShuffleCall;
8655 } else {
8656 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8657 return Builder.CreateCall(F, Ops);
8658 }
8659 }
Tony Jiangbbc48e92017-05-24 15:13:32 +00008660
8661 case PPC::BI__builtin_vsx_xxpermdi: {
8662 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8663 assert(ArgCI && "Third arg must be constant integer!");
8664
8665 unsigned Index = ArgCI->getZExtValue();
8666 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8667 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8668
8669 // Element zero comes from the first input vector and element one comes from
8670 // the second. The element indices within each vector are numbered in big
8671 // endian order so the shuffle mask must be adjusted for this on little
8672 // endian platforms (i.e. index is complemented and source vector reversed).
8673 unsigned ElemIdx0;
8674 unsigned ElemIdx1;
8675 if (getTarget().isLittleEndian()) {
8676 ElemIdx0 = (~Index & 1) + 2;
8677 ElemIdx1 = (~Index & 2) >> 1;
8678 } else { // BigEndian
8679 ElemIdx0 = (Index & 2) >> 1;
8680 ElemIdx1 = 2 + (Index & 1);
8681 }
8682
8683 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0),
8684 ConstantInt::get(Int32Ty, ElemIdx1)};
8685 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8686
8687 Value *ShuffleCall =
8688 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8689 QualType BIRetType = E->getType();
8690 auto RetTy = ConvertType(BIRetType);
8691 return Builder.CreateBitCast(ShuffleCall, RetTy);
8692 }
Tony Jiang9aa2c032017-05-24 15:54:13 +00008693
8694 case PPC::BI__builtin_vsx_xxsldwi: {
8695 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8696 assert(ArgCI && "Third argument must be a compile time constant");
8697 unsigned Index = ArgCI->getZExtValue() & 0x3;
8698 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8699 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4));
8700
8701 // Create a shuffle mask
8702 unsigned ElemIdx0;
8703 unsigned ElemIdx1;
8704 unsigned ElemIdx2;
8705 unsigned ElemIdx3;
8706 if (getTarget().isLittleEndian()) {
8707 // Little endian element N comes from element 8+N-Index of the
8708 // concatenated wide vector (of course, using modulo arithmetic on
8709 // the total number of elements).
8710 ElemIdx0 = (8 - Index) % 8;
8711 ElemIdx1 = (9 - Index) % 8;
8712 ElemIdx2 = (10 - Index) % 8;
8713 ElemIdx3 = (11 - Index) % 8;
8714 } else {
8715 // Big endian ElemIdx<N> = Index + N
8716 ElemIdx0 = Index;
8717 ElemIdx1 = Index + 1;
8718 ElemIdx2 = Index + 2;
8719 ElemIdx3 = Index + 3;
8720 }
8721
8722 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0),
8723 ConstantInt::get(Int32Ty, ElemIdx1),
8724 ConstantInt::get(Int32Ty, ElemIdx2),
8725 ConstantInt::get(Int32Ty, ElemIdx3)};
8726
8727 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8728 Value *ShuffleCall =
8729 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8730 QualType BIRetType = E->getType();
8731 auto RetTy = ConvertType(BIRetType);
8732 return Builder.CreateBitCast(ShuffleCall, RetTy);
8733 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008734 }
Mike Stump11289f42009-09-09 15:08:12 +00008735}
Matt Arsenault56f008d2014-06-24 20:45:01 +00008736
Matt Arsenault3ea39f92015-06-19 17:54:10 +00008737Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
8738 const CallExpr *E) {
Matt Arsenault56f008d2014-06-24 20:45:01 +00008739 switch (BuiltinID) {
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008740 case AMDGPU::BI__builtin_amdgcn_div_scale:
8741 case AMDGPU::BI__builtin_amdgcn_div_scalef: {
Matt Arsenault56f008d2014-06-24 20:45:01 +00008742 // Translate from the intrinsics's struct return to the builtin's out
8743 // argument.
8744
John McCall7f416cc2015-09-08 08:05:57 +00008745 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3));
Matt Arsenault56f008d2014-06-24 20:45:01 +00008746
8747 llvm::Value *X = EmitScalarExpr(E->getArg(0));
8748 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
8749 llvm::Value *Z = EmitScalarExpr(E->getArg(2));
8750
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008751 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale,
Matt Arsenault56f008d2014-06-24 20:45:01 +00008752 X->getType());
8753
David Blaikie43f9bb72015-05-18 22:14:03 +00008754 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z});
Matt Arsenault56f008d2014-06-24 20:45:01 +00008755
8756 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0);
8757 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1);
8758
8759 llvm::Type *RealFlagType
John McCall7f416cc2015-09-08 08:05:57 +00008760 = FlagOutPtr.getPointer()->getType()->getPointerElementType();
Matt Arsenault56f008d2014-06-24 20:45:01 +00008761
8762 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType);
John McCall7f416cc2015-09-08 08:05:57 +00008763 Builder.CreateStore(FlagExt, FlagOutPtr);
Matt Arsenault56f008d2014-06-24 20:45:01 +00008764 return Result;
Matt Arsenault85877112014-07-15 17:23:46 +00008765 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008766 case AMDGPU::BI__builtin_amdgcn_div_fmas:
8767 case AMDGPU::BI__builtin_amdgcn_div_fmasf: {
Matt Arsenault2174a9d2014-10-21 22:21:41 +00008768 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0));
8769 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1));
8770 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2));
8771 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3));
8772
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008773 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas,
Matt Arsenault2174a9d2014-10-21 22:21:41 +00008774 Src0->getType());
8775 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3);
David Blaikie43f9bb72015-05-18 22:14:03 +00008776 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool});
Matt Arsenault2174a9d2014-10-21 22:21:41 +00008777 }
Changpeng Fang03bdd8f2016-08-18 22:04:54 +00008778
8779 case AMDGPU::BI__builtin_amdgcn_ds_swizzle:
8780 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle);
Yaxun Liu4d867992017-03-10 01:30:46 +00008781 case AMDGPU::BI__builtin_amdgcn_mov_dpp: {
8782 llvm::SmallVector<llvm::Value *, 5> Args;
8783 for (unsigned I = 0; I != 5; ++I)
8784 Args.push_back(EmitScalarExpr(E->getArg(I)));
8785 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp,
8786 Args[0]->getType());
8787 return Builder.CreateCall(F, Args);
8788 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008789 case AMDGPU::BI__builtin_amdgcn_div_fixup:
8790 case AMDGPU::BI__builtin_amdgcn_div_fixupf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008791 case AMDGPU::BI__builtin_amdgcn_div_fixuph:
Matt Arsenaultf652cae2016-07-01 17:38:14 +00008792 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008793 case AMDGPU::BI__builtin_amdgcn_trig_preop:
8794 case AMDGPU::BI__builtin_amdgcn_trig_preopf:
8795 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop);
8796 case AMDGPU::BI__builtin_amdgcn_rcp:
8797 case AMDGPU::BI__builtin_amdgcn_rcpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008798 case AMDGPU::BI__builtin_amdgcn_rcph:
Matt Arsenault105e8922016-02-03 17:49:38 +00008799 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008800 case AMDGPU::BI__builtin_amdgcn_rsq:
8801 case AMDGPU::BI__builtin_amdgcn_rsqf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008802 case AMDGPU::BI__builtin_amdgcn_rsqh:
Matt Arsenault105e8922016-02-03 17:49:38 +00008803 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq);
Matt Arsenaultf5c1f472016-02-13 01:03:09 +00008804 case AMDGPU::BI__builtin_amdgcn_rsq_clamp:
8805 case AMDGPU::BI__builtin_amdgcn_rsq_clampf:
8806 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp);
Matt Arsenault9b277b42016-02-13 01:21:09 +00008807 case AMDGPU::BI__builtin_amdgcn_sinf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008808 case AMDGPU::BI__builtin_amdgcn_sinh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00008809 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin);
8810 case AMDGPU::BI__builtin_amdgcn_cosf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008811 case AMDGPU::BI__builtin_amdgcn_cosh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00008812 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos);
8813 case AMDGPU::BI__builtin_amdgcn_log_clampf:
8814 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008815 case AMDGPU::BI__builtin_amdgcn_ldexp:
8816 case AMDGPU::BI__builtin_amdgcn_ldexpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008817 case AMDGPU::BI__builtin_amdgcn_ldexph:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008818 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp);
Matt Arsenault3fb96332016-03-30 22:57:40 +00008819 case AMDGPU::BI__builtin_amdgcn_frexp_mant:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008820 case AMDGPU::BI__builtin_amdgcn_frexp_mantf:
8821 case AMDGPU::BI__builtin_amdgcn_frexp_manth:
Matt Arsenault3fb96332016-03-30 22:57:40 +00008822 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant);
Matt Arsenault3fb96332016-03-30 22:57:40 +00008823 case AMDGPU::BI__builtin_amdgcn_frexp_exp:
Konstantin Zhuravlyov62ae8f62016-11-18 22:31:51 +00008824 case AMDGPU::BI__builtin_amdgcn_frexp_expf: {
8825 Value *Src0 = EmitScalarExpr(E->getArg(0));
8826 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
8827 { Builder.getInt32Ty(), Src0->getType() });
8828 return Builder.CreateCall(F, Src0);
8829 }
8830 case AMDGPU::BI__builtin_amdgcn_frexp_exph: {
8831 Value *Src0 = EmitScalarExpr(E->getArg(0));
8832 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
8833 { Builder.getInt16Ty(), Src0->getType() });
8834 return Builder.CreateCall(F, Src0);
8835 }
Matt Arsenault2d510592016-05-28 00:43:27 +00008836 case AMDGPU::BI__builtin_amdgcn_fract:
8837 case AMDGPU::BI__builtin_amdgcn_fractf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008838 case AMDGPU::BI__builtin_amdgcn_fracth:
Matt Arsenault2d510592016-05-28 00:43:27 +00008839 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract);
Wei Dingea41f352016-07-15 16:43:03 +00008840 case AMDGPU::BI__builtin_amdgcn_lerp:
8841 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp);
Wei Ding91c84502016-08-05 15:38:46 +00008842 case AMDGPU::BI__builtin_amdgcn_uicmp:
8843 case AMDGPU::BI__builtin_amdgcn_uicmpl:
8844 case AMDGPU::BI__builtin_amdgcn_sicmp:
8845 case AMDGPU::BI__builtin_amdgcn_sicmpl:
8846 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp);
8847 case AMDGPU::BI__builtin_amdgcn_fcmp:
8848 case AMDGPU::BI__builtin_amdgcn_fcmpf:
8849 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008850 case AMDGPU::BI__builtin_amdgcn_class:
8851 case AMDGPU::BI__builtin_amdgcn_classf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00008852 case AMDGPU::BI__builtin_amdgcn_classh:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008853 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class);
Matt Arsenaulta274b202017-01-31 03:42:07 +00008854 case AMDGPU::BI__builtin_amdgcn_fmed3f:
Matt Arsenaulta0c6dca2017-02-22 20:55:59 +00008855 case AMDGPU::BI__builtin_amdgcn_fmed3h:
Matt Arsenaulta274b202017-01-31 03:42:07 +00008856 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3);
Matt Arsenault64665bc2016-06-28 00:13:17 +00008857 case AMDGPU::BI__builtin_amdgcn_read_exec: {
8858 CallInst *CI = cast<CallInst>(
8859 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec"));
8860 CI->setConvergent();
8861 return CI;
8862 }
Jan Veselyd7e03a52016-07-10 22:38:04 +00008863
8864 // amdgcn workitem
8865 case AMDGPU::BI__builtin_amdgcn_workitem_id_x:
8866 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024);
8867 case AMDGPU::BI__builtin_amdgcn_workitem_id_y:
8868 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024);
8869 case AMDGPU::BI__builtin_amdgcn_workitem_id_z:
8870 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024);
8871
Matt Arsenaultc86671d2016-07-15 21:33:02 +00008872 // r600 intrinsics
8873 case AMDGPU::BI__builtin_r600_recipsqrt_ieee:
8874 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef:
8875 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee);
Jan Veselyd7e03a52016-07-10 22:38:04 +00008876 case AMDGPU::BI__builtin_r600_read_tidig_x:
8877 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024);
8878 case AMDGPU::BI__builtin_r600_read_tidig_y:
8879 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024);
8880 case AMDGPU::BI__builtin_r600_read_tidig_z:
8881 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00008882 default:
Matt Arsenault56f008d2014-06-24 20:45:01 +00008883 return nullptr;
8884 }
8885}
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008886
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008887/// Handle a SystemZ function in which the final argument is a pointer
8888/// to an int that receives the post-instruction CC value. At the LLVM level
8889/// this is represented as a function that returns a {result, cc} pair.
8890static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF,
8891 unsigned IntrinsicID,
8892 const CallExpr *E) {
8893 unsigned NumArgs = E->getNumArgs() - 1;
8894 SmallVector<Value *, 8> Args(NumArgs);
8895 for (unsigned I = 0; I < NumArgs; ++I)
8896 Args[I] = CGF.EmitScalarExpr(E->getArg(I));
John McCall7f416cc2015-09-08 08:05:57 +00008897 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs));
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008898 Value *F = CGF.CGM.getIntrinsic(IntrinsicID);
8899 Value *Call = CGF.Builder.CreateCall(F, Args);
8900 Value *CC = CGF.Builder.CreateExtractValue(Call, 1);
8901 CGF.Builder.CreateStore(CC, CCPtr);
8902 return CGF.Builder.CreateExtractValue(Call, 0);
8903}
8904
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008905Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
8906 const CallExpr *E) {
8907 switch (BuiltinID) {
8908 case SystemZ::BI__builtin_tbegin: {
8909 Value *TDB = EmitScalarExpr(E->getArg(0));
8910 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
8911 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin);
David Blaikie43f9bb72015-05-18 22:14:03 +00008912 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008913 }
8914 case SystemZ::BI__builtin_tbegin_nofloat: {
8915 Value *TDB = EmitScalarExpr(E->getArg(0));
8916 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
8917 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat);
David Blaikie43f9bb72015-05-18 22:14:03 +00008918 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008919 }
8920 case SystemZ::BI__builtin_tbeginc: {
8921 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy);
8922 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08);
8923 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc);
David Blaikie43f9bb72015-05-18 22:14:03 +00008924 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008925 }
8926 case SystemZ::BI__builtin_tabort: {
8927 Value *Data = EmitScalarExpr(E->getArg(0));
8928 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort);
8929 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort"));
8930 }
8931 case SystemZ::BI__builtin_non_tx_store: {
8932 Value *Address = EmitScalarExpr(E->getArg(0));
8933 Value *Data = EmitScalarExpr(E->getArg(1));
8934 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg);
David Blaikie43f9bb72015-05-18 22:14:03 +00008935 return Builder.CreateCall(F, {Data, Address});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00008936 }
8937
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008938 // Vector builtins. Note that most vector builtins are mapped automatically
8939 // to target-specific LLVM intrinsics. The ones handled specially here can
8940 // be represented via standard LLVM IR, which is preferable to enable common
8941 // LLVM optimizations.
8942
8943 case SystemZ::BI__builtin_s390_vpopctb:
8944 case SystemZ::BI__builtin_s390_vpopcth:
8945 case SystemZ::BI__builtin_s390_vpopctf:
8946 case SystemZ::BI__builtin_s390_vpopctg: {
8947 llvm::Type *ResultType = ConvertType(E->getType());
8948 Value *X = EmitScalarExpr(E->getArg(0));
8949 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
8950 return Builder.CreateCall(F, X);
8951 }
8952
8953 case SystemZ::BI__builtin_s390_vclzb:
8954 case SystemZ::BI__builtin_s390_vclzh:
8955 case SystemZ::BI__builtin_s390_vclzf:
8956 case SystemZ::BI__builtin_s390_vclzg: {
8957 llvm::Type *ResultType = ConvertType(E->getType());
8958 Value *X = EmitScalarExpr(E->getArg(0));
8959 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8960 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00008961 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008962 }
8963
8964 case SystemZ::BI__builtin_s390_vctzb:
8965 case SystemZ::BI__builtin_s390_vctzh:
8966 case SystemZ::BI__builtin_s390_vctzf:
8967 case SystemZ::BI__builtin_s390_vctzg: {
8968 llvm::Type *ResultType = ConvertType(E->getType());
8969 Value *X = EmitScalarExpr(E->getArg(0));
8970 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8971 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00008972 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008973 }
8974
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00008975 case SystemZ::BI__builtin_s390_vfsqsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008976 case SystemZ::BI__builtin_s390_vfsqdb: {
8977 llvm::Type *ResultType = ConvertType(E->getType());
8978 Value *X = EmitScalarExpr(E->getArg(0));
8979 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
8980 return Builder.CreateCall(F, X);
8981 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00008982 case SystemZ::BI__builtin_s390_vfmasb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008983 case SystemZ::BI__builtin_s390_vfmadb: {
8984 llvm::Type *ResultType = ConvertType(E->getType());
8985 Value *X = EmitScalarExpr(E->getArg(0));
8986 Value *Y = EmitScalarExpr(E->getArg(1));
8987 Value *Z = EmitScalarExpr(E->getArg(2));
8988 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00008989 return Builder.CreateCall(F, {X, Y, Z});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008990 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00008991 case SystemZ::BI__builtin_s390_vfmssb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00008992 case SystemZ::BI__builtin_s390_vfmsdb: {
8993 llvm::Type *ResultType = ConvertType(E->getType());
8994 Value *X = EmitScalarExpr(E->getArg(0));
8995 Value *Y = EmitScalarExpr(E->getArg(1));
8996 Value *Z = EmitScalarExpr(E->getArg(2));
8997 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
8998 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00008999 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009000 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009001 case SystemZ::BI__builtin_s390_vfnmasb:
9002 case SystemZ::BI__builtin_s390_vfnmadb: {
9003 llvm::Type *ResultType = ConvertType(E->getType());
9004 Value *X = EmitScalarExpr(E->getArg(0));
9005 Value *Y = EmitScalarExpr(E->getArg(1));
9006 Value *Z = EmitScalarExpr(E->getArg(2));
9007 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9008 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9009 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub");
9010 }
9011 case SystemZ::BI__builtin_s390_vfnmssb:
9012 case SystemZ::BI__builtin_s390_vfnmsdb: {
9013 llvm::Type *ResultType = ConvertType(E->getType());
9014 Value *X = EmitScalarExpr(E->getArg(0));
9015 Value *Y = EmitScalarExpr(E->getArg(1));
9016 Value *Z = EmitScalarExpr(E->getArg(2));
9017 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9018 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9019 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub");
9020 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ}));
9021 }
9022 case SystemZ::BI__builtin_s390_vflpsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009023 case SystemZ::BI__builtin_s390_vflpdb: {
9024 llvm::Type *ResultType = ConvertType(E->getType());
9025 Value *X = EmitScalarExpr(E->getArg(0));
9026 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9027 return Builder.CreateCall(F, X);
9028 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009029 case SystemZ::BI__builtin_s390_vflnsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009030 case SystemZ::BI__builtin_s390_vflndb: {
9031 llvm::Type *ResultType = ConvertType(E->getType());
9032 Value *X = EmitScalarExpr(E->getArg(0));
9033 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9034 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9035 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub");
9036 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009037 case SystemZ::BI__builtin_s390_vfisb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009038 case SystemZ::BI__builtin_s390_vfidb: {
9039 llvm::Type *ResultType = ConvertType(E->getType());
9040 Value *X = EmitScalarExpr(E->getArg(0));
9041 // Constant-fold the M4 and M5 mask arguments.
9042 llvm::APSInt M4, M5;
9043 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext());
9044 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext());
9045 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?");
9046 (void)IsConstM4; (void)IsConstM5;
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009047 // Check whether this instance can be represented via a LLVM standard
9048 // intrinsic. We only support some combinations of M4 and M5.
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009049 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9050 switch (M4.getZExtValue()) {
9051 default: break;
9052 case 0: // IEEE-inexact exception allowed
9053 switch (M5.getZExtValue()) {
9054 default: break;
9055 case 0: ID = Intrinsic::rint; break;
9056 }
9057 break;
9058 case 4: // IEEE-inexact exception suppressed
9059 switch (M5.getZExtValue()) {
9060 default: break;
9061 case 0: ID = Intrinsic::nearbyint; break;
9062 case 1: ID = Intrinsic::round; break;
9063 case 5: ID = Intrinsic::trunc; break;
9064 case 6: ID = Intrinsic::ceil; break;
9065 case 7: ID = Intrinsic::floor; break;
9066 }
9067 break;
9068 }
9069 if (ID != Intrinsic::not_intrinsic) {
9070 Function *F = CGM.getIntrinsic(ID, ResultType);
9071 return Builder.CreateCall(F, X);
9072 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009073 switch (BuiltinID) {
9074 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break;
9075 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break;
9076 default: llvm_unreachable("Unknown BuiltinID");
9077 }
9078 Function *F = CGM.getIntrinsic(ID);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009079 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9080 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5);
David Blaikie43f9bb72015-05-18 22:14:03 +00009081 return Builder.CreateCall(F, {X, M4Value, M5Value});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009082 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009083 case SystemZ::BI__builtin_s390_vfmaxsb:
9084 case SystemZ::BI__builtin_s390_vfmaxdb: {
9085 llvm::Type *ResultType = ConvertType(E->getType());
9086 Value *X = EmitScalarExpr(E->getArg(0));
9087 Value *Y = EmitScalarExpr(E->getArg(1));
9088 // Constant-fold the M4 mask argument.
9089 llvm::APSInt M4;
9090 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9091 assert(IsConstM4 && "Constant arg isn't actually constant?");
9092 (void)IsConstM4;
9093 // Check whether this instance can be represented via a LLVM standard
9094 // intrinsic. We only support some values of M4.
9095 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9096 switch (M4.getZExtValue()) {
9097 default: break;
9098 case 4: ID = Intrinsic::maxnum; break;
9099 }
9100 if (ID != Intrinsic::not_intrinsic) {
9101 Function *F = CGM.getIntrinsic(ID, ResultType);
9102 return Builder.CreateCall(F, {X, Y});
9103 }
9104 switch (BuiltinID) {
9105 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break;
9106 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break;
9107 default: llvm_unreachable("Unknown BuiltinID");
9108 }
9109 Function *F = CGM.getIntrinsic(ID);
9110 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9111 return Builder.CreateCall(F, {X, Y, M4Value});
9112 }
9113 case SystemZ::BI__builtin_s390_vfminsb:
9114 case SystemZ::BI__builtin_s390_vfmindb: {
9115 llvm::Type *ResultType = ConvertType(E->getType());
9116 Value *X = EmitScalarExpr(E->getArg(0));
9117 Value *Y = EmitScalarExpr(E->getArg(1));
9118 // Constant-fold the M4 mask argument.
9119 llvm::APSInt M4;
9120 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9121 assert(IsConstM4 && "Constant arg isn't actually constant?");
9122 (void)IsConstM4;
9123 // Check whether this instance can be represented via a LLVM standard
9124 // intrinsic. We only support some values of M4.
9125 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9126 switch (M4.getZExtValue()) {
9127 default: break;
9128 case 4: ID = Intrinsic::minnum; break;
9129 }
9130 if (ID != Intrinsic::not_intrinsic) {
9131 Function *F = CGM.getIntrinsic(ID, ResultType);
9132 return Builder.CreateCall(F, {X, Y});
9133 }
9134 switch (BuiltinID) {
9135 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break;
9136 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break;
9137 default: llvm_unreachable("Unknown BuiltinID");
9138 }
9139 Function *F = CGM.getIntrinsic(ID);
9140 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9141 return Builder.CreateCall(F, {X, Y, M4Value});
9142 }
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009143
9144 // Vector intrisincs that output the post-instruction CC value.
9145
9146#define INTRINSIC_WITH_CC(NAME) \
9147 case SystemZ::BI__builtin_##NAME: \
9148 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E)
9149
9150 INTRINSIC_WITH_CC(s390_vpkshs);
9151 INTRINSIC_WITH_CC(s390_vpksfs);
9152 INTRINSIC_WITH_CC(s390_vpksgs);
9153
9154 INTRINSIC_WITH_CC(s390_vpklshs);
9155 INTRINSIC_WITH_CC(s390_vpklsfs);
9156 INTRINSIC_WITH_CC(s390_vpklsgs);
9157
9158 INTRINSIC_WITH_CC(s390_vceqbs);
9159 INTRINSIC_WITH_CC(s390_vceqhs);
9160 INTRINSIC_WITH_CC(s390_vceqfs);
9161 INTRINSIC_WITH_CC(s390_vceqgs);
9162
9163 INTRINSIC_WITH_CC(s390_vchbs);
9164 INTRINSIC_WITH_CC(s390_vchhs);
9165 INTRINSIC_WITH_CC(s390_vchfs);
9166 INTRINSIC_WITH_CC(s390_vchgs);
9167
9168 INTRINSIC_WITH_CC(s390_vchlbs);
9169 INTRINSIC_WITH_CC(s390_vchlhs);
9170 INTRINSIC_WITH_CC(s390_vchlfs);
9171 INTRINSIC_WITH_CC(s390_vchlgs);
9172
9173 INTRINSIC_WITH_CC(s390_vfaebs);
9174 INTRINSIC_WITH_CC(s390_vfaehs);
9175 INTRINSIC_WITH_CC(s390_vfaefs);
9176
9177 INTRINSIC_WITH_CC(s390_vfaezbs);
9178 INTRINSIC_WITH_CC(s390_vfaezhs);
9179 INTRINSIC_WITH_CC(s390_vfaezfs);
9180
9181 INTRINSIC_WITH_CC(s390_vfeebs);
9182 INTRINSIC_WITH_CC(s390_vfeehs);
9183 INTRINSIC_WITH_CC(s390_vfeefs);
9184
9185 INTRINSIC_WITH_CC(s390_vfeezbs);
9186 INTRINSIC_WITH_CC(s390_vfeezhs);
9187 INTRINSIC_WITH_CC(s390_vfeezfs);
9188
9189 INTRINSIC_WITH_CC(s390_vfenebs);
9190 INTRINSIC_WITH_CC(s390_vfenehs);
9191 INTRINSIC_WITH_CC(s390_vfenefs);
9192
9193 INTRINSIC_WITH_CC(s390_vfenezbs);
9194 INTRINSIC_WITH_CC(s390_vfenezhs);
9195 INTRINSIC_WITH_CC(s390_vfenezfs);
9196
9197 INTRINSIC_WITH_CC(s390_vistrbs);
9198 INTRINSIC_WITH_CC(s390_vistrhs);
9199 INTRINSIC_WITH_CC(s390_vistrfs);
9200
9201 INTRINSIC_WITH_CC(s390_vstrcbs);
9202 INTRINSIC_WITH_CC(s390_vstrchs);
9203 INTRINSIC_WITH_CC(s390_vstrcfs);
9204
9205 INTRINSIC_WITH_CC(s390_vstrczbs);
9206 INTRINSIC_WITH_CC(s390_vstrczhs);
9207 INTRINSIC_WITH_CC(s390_vstrczfs);
9208
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009209 INTRINSIC_WITH_CC(s390_vfcesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009210 INTRINSIC_WITH_CC(s390_vfcedbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009211 INTRINSIC_WITH_CC(s390_vfchsbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009212 INTRINSIC_WITH_CC(s390_vfchdbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009213 INTRINSIC_WITH_CC(s390_vfchesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009214 INTRINSIC_WITH_CC(s390_vfchedbs);
9215
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009216 INTRINSIC_WITH_CC(s390_vftcisb);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009217 INTRINSIC_WITH_CC(s390_vftcidb);
9218
9219#undef INTRINSIC_WITH_CC
9220
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009221 default:
9222 return nullptr;
9223 }
9224}
Artem Belevichd21e5c62015-06-25 18:29:42 +00009225
9226Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
9227 const CallExpr *E) {
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009228 auto MakeLdg = [&](unsigned IntrinsicID) {
9229 Value *Ptr = EmitScalarExpr(E->getArg(0));
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009230 clang::CharUnits Align =
Krzysztof Parzyszek8f248232017-05-18 17:07:11 +00009231 getNaturalPointeeTypeAlignment(E->getArg(0)->getType());
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009232 return Builder.CreateCall(
9233 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9234 Ptr->getType()}),
9235 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())});
9236 };
Artem Belevichfda99052016-09-28 17:47:35 +00009237 auto MakeScopedAtomic = [&](unsigned IntrinsicID) {
9238 Value *Ptr = EmitScalarExpr(E->getArg(0));
9239 return Builder.CreateCall(
9240 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9241 Ptr->getType()}),
9242 {Ptr, EmitScalarExpr(E->getArg(1))});
9243 };
Artem Belevichd21e5c62015-06-25 18:29:42 +00009244 switch (BuiltinID) {
9245 case NVPTX::BI__nvvm_atom_add_gen_i:
9246 case NVPTX::BI__nvvm_atom_add_gen_l:
9247 case NVPTX::BI__nvvm_atom_add_gen_ll:
9248 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E);
9249
9250 case NVPTX::BI__nvvm_atom_sub_gen_i:
9251 case NVPTX::BI__nvvm_atom_sub_gen_l:
9252 case NVPTX::BI__nvvm_atom_sub_gen_ll:
9253 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E);
9254
9255 case NVPTX::BI__nvvm_atom_and_gen_i:
9256 case NVPTX::BI__nvvm_atom_and_gen_l:
9257 case NVPTX::BI__nvvm_atom_and_gen_ll:
9258 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E);
9259
9260 case NVPTX::BI__nvvm_atom_or_gen_i:
9261 case NVPTX::BI__nvvm_atom_or_gen_l:
9262 case NVPTX::BI__nvvm_atom_or_gen_ll:
9263 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E);
9264
9265 case NVPTX::BI__nvvm_atom_xor_gen_i:
9266 case NVPTX::BI__nvvm_atom_xor_gen_l:
9267 case NVPTX::BI__nvvm_atom_xor_gen_ll:
9268 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E);
9269
9270 case NVPTX::BI__nvvm_atom_xchg_gen_i:
9271 case NVPTX::BI__nvvm_atom_xchg_gen_l:
9272 case NVPTX::BI__nvvm_atom_xchg_gen_ll:
9273 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E);
9274
9275 case NVPTX::BI__nvvm_atom_max_gen_i:
9276 case NVPTX::BI__nvvm_atom_max_gen_l:
9277 case NVPTX::BI__nvvm_atom_max_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009278 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E);
9279
Artem Belevichd21e5c62015-06-25 18:29:42 +00009280 case NVPTX::BI__nvvm_atom_max_gen_ui:
9281 case NVPTX::BI__nvvm_atom_max_gen_ul:
9282 case NVPTX::BI__nvvm_atom_max_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009283 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009284
9285 case NVPTX::BI__nvvm_atom_min_gen_i:
9286 case NVPTX::BI__nvvm_atom_min_gen_l:
9287 case NVPTX::BI__nvvm_atom_min_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009288 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E);
9289
Artem Belevichd21e5c62015-06-25 18:29:42 +00009290 case NVPTX::BI__nvvm_atom_min_gen_ui:
9291 case NVPTX::BI__nvvm_atom_min_gen_ul:
9292 case NVPTX::BI__nvvm_atom_min_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009293 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009294
9295 case NVPTX::BI__nvvm_atom_cas_gen_i:
9296 case NVPTX::BI__nvvm_atom_cas_gen_l:
9297 case NVPTX::BI__nvvm_atom_cas_gen_ll:
Jingyue Wuf1eca252015-09-30 21:49:32 +00009298 // __nvvm_atom_cas_gen_* should return the old value rather than the
9299 // success flag.
9300 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009301
9302 case NVPTX::BI__nvvm_atom_add_gen_f: {
9303 Value *Ptr = EmitScalarExpr(E->getArg(0));
9304 Value *Val = EmitScalarExpr(E->getArg(1));
9305 // atomicrmw only deals with integer arguments so we need to use
9306 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that.
9307 Value *FnALAF32 =
9308 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType());
9309 return Builder.CreateCall(FnALAF32, {Ptr, Val});
9310 }
9311
Justin Lebar717d2b02016-03-22 00:09:28 +00009312 case NVPTX::BI__nvvm_atom_inc_gen_ui: {
9313 Value *Ptr = EmitScalarExpr(E->getArg(0));
9314 Value *Val = EmitScalarExpr(E->getArg(1));
9315 Value *FnALI32 =
9316 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType());
9317 return Builder.CreateCall(FnALI32, {Ptr, Val});
9318 }
9319
9320 case NVPTX::BI__nvvm_atom_dec_gen_ui: {
9321 Value *Ptr = EmitScalarExpr(E->getArg(0));
9322 Value *Val = EmitScalarExpr(E->getArg(1));
9323 Value *FnALD32 =
9324 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType());
9325 return Builder.CreateCall(FnALD32, {Ptr, Val});
9326 }
9327
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009328 case NVPTX::BI__nvvm_ldg_c:
9329 case NVPTX::BI__nvvm_ldg_c2:
9330 case NVPTX::BI__nvvm_ldg_c4:
9331 case NVPTX::BI__nvvm_ldg_s:
9332 case NVPTX::BI__nvvm_ldg_s2:
9333 case NVPTX::BI__nvvm_ldg_s4:
9334 case NVPTX::BI__nvvm_ldg_i:
9335 case NVPTX::BI__nvvm_ldg_i2:
9336 case NVPTX::BI__nvvm_ldg_i4:
9337 case NVPTX::BI__nvvm_ldg_l:
9338 case NVPTX::BI__nvvm_ldg_ll:
9339 case NVPTX::BI__nvvm_ldg_ll2:
9340 case NVPTX::BI__nvvm_ldg_uc:
9341 case NVPTX::BI__nvvm_ldg_uc2:
9342 case NVPTX::BI__nvvm_ldg_uc4:
9343 case NVPTX::BI__nvvm_ldg_us:
9344 case NVPTX::BI__nvvm_ldg_us2:
9345 case NVPTX::BI__nvvm_ldg_us4:
9346 case NVPTX::BI__nvvm_ldg_ui:
9347 case NVPTX::BI__nvvm_ldg_ui2:
9348 case NVPTX::BI__nvvm_ldg_ui4:
9349 case NVPTX::BI__nvvm_ldg_ul:
9350 case NVPTX::BI__nvvm_ldg_ull:
9351 case NVPTX::BI__nvvm_ldg_ull2:
9352 // PTX Interoperability section 2.2: "For a vector with an even number of
9353 // elements, its alignment is set to number of elements times the alignment
9354 // of its member: n*alignof(t)."
9355 return MakeLdg(Intrinsic::nvvm_ldg_global_i);
9356 case NVPTX::BI__nvvm_ldg_f:
9357 case NVPTX::BI__nvvm_ldg_f2:
9358 case NVPTX::BI__nvvm_ldg_f4:
9359 case NVPTX::BI__nvvm_ldg_d:
9360 case NVPTX::BI__nvvm_ldg_d2:
9361 return MakeLdg(Intrinsic::nvvm_ldg_global_f);
Artem Belevichfda99052016-09-28 17:47:35 +00009362
9363 case NVPTX::BI__nvvm_atom_cta_add_gen_i:
9364 case NVPTX::BI__nvvm_atom_cta_add_gen_l:
9365 case NVPTX::BI__nvvm_atom_cta_add_gen_ll:
9366 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta);
9367 case NVPTX::BI__nvvm_atom_sys_add_gen_i:
9368 case NVPTX::BI__nvvm_atom_sys_add_gen_l:
9369 case NVPTX::BI__nvvm_atom_sys_add_gen_ll:
9370 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys);
9371 case NVPTX::BI__nvvm_atom_cta_add_gen_f:
9372 case NVPTX::BI__nvvm_atom_cta_add_gen_d:
9373 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta);
9374 case NVPTX::BI__nvvm_atom_sys_add_gen_f:
9375 case NVPTX::BI__nvvm_atom_sys_add_gen_d:
9376 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys);
9377 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i:
9378 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l:
9379 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll:
9380 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta);
9381 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i:
9382 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l:
9383 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll:
9384 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys);
9385 case NVPTX::BI__nvvm_atom_cta_max_gen_i:
9386 case NVPTX::BI__nvvm_atom_cta_max_gen_ui:
9387 case NVPTX::BI__nvvm_atom_cta_max_gen_l:
9388 case NVPTX::BI__nvvm_atom_cta_max_gen_ul:
9389 case NVPTX::BI__nvvm_atom_cta_max_gen_ll:
9390 case NVPTX::BI__nvvm_atom_cta_max_gen_ull:
9391 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta);
9392 case NVPTX::BI__nvvm_atom_sys_max_gen_i:
9393 case NVPTX::BI__nvvm_atom_sys_max_gen_ui:
9394 case NVPTX::BI__nvvm_atom_sys_max_gen_l:
9395 case NVPTX::BI__nvvm_atom_sys_max_gen_ul:
9396 case NVPTX::BI__nvvm_atom_sys_max_gen_ll:
9397 case NVPTX::BI__nvvm_atom_sys_max_gen_ull:
9398 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys);
9399 case NVPTX::BI__nvvm_atom_cta_min_gen_i:
9400 case NVPTX::BI__nvvm_atom_cta_min_gen_ui:
9401 case NVPTX::BI__nvvm_atom_cta_min_gen_l:
9402 case NVPTX::BI__nvvm_atom_cta_min_gen_ul:
9403 case NVPTX::BI__nvvm_atom_cta_min_gen_ll:
9404 case NVPTX::BI__nvvm_atom_cta_min_gen_ull:
9405 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta);
9406 case NVPTX::BI__nvvm_atom_sys_min_gen_i:
9407 case NVPTX::BI__nvvm_atom_sys_min_gen_ui:
9408 case NVPTX::BI__nvvm_atom_sys_min_gen_l:
9409 case NVPTX::BI__nvvm_atom_sys_min_gen_ul:
9410 case NVPTX::BI__nvvm_atom_sys_min_gen_ll:
9411 case NVPTX::BI__nvvm_atom_sys_min_gen_ull:
9412 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys);
9413 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui:
9414 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta);
9415 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui:
9416 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta);
9417 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui:
9418 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys);
9419 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui:
9420 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys);
9421 case NVPTX::BI__nvvm_atom_cta_and_gen_i:
9422 case NVPTX::BI__nvvm_atom_cta_and_gen_l:
9423 case NVPTX::BI__nvvm_atom_cta_and_gen_ll:
9424 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta);
9425 case NVPTX::BI__nvvm_atom_sys_and_gen_i:
9426 case NVPTX::BI__nvvm_atom_sys_and_gen_l:
9427 case NVPTX::BI__nvvm_atom_sys_and_gen_ll:
9428 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys);
9429 case NVPTX::BI__nvvm_atom_cta_or_gen_i:
9430 case NVPTX::BI__nvvm_atom_cta_or_gen_l:
9431 case NVPTX::BI__nvvm_atom_cta_or_gen_ll:
9432 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta);
9433 case NVPTX::BI__nvvm_atom_sys_or_gen_i:
9434 case NVPTX::BI__nvvm_atom_sys_or_gen_l:
9435 case NVPTX::BI__nvvm_atom_sys_or_gen_ll:
9436 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys);
9437 case NVPTX::BI__nvvm_atom_cta_xor_gen_i:
9438 case NVPTX::BI__nvvm_atom_cta_xor_gen_l:
9439 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll:
9440 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta);
9441 case NVPTX::BI__nvvm_atom_sys_xor_gen_i:
9442 case NVPTX::BI__nvvm_atom_sys_xor_gen_l:
9443 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll:
9444 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys);
9445 case NVPTX::BI__nvvm_atom_cta_cas_gen_i:
9446 case NVPTX::BI__nvvm_atom_cta_cas_gen_l:
9447 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: {
9448 Value *Ptr = EmitScalarExpr(E->getArg(0));
9449 return Builder.CreateCall(
9450 CGM.getIntrinsic(
9451 Intrinsic::nvvm_atomic_cas_gen_i_cta,
9452 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9453 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9454 }
9455 case NVPTX::BI__nvvm_atom_sys_cas_gen_i:
9456 case NVPTX::BI__nvvm_atom_sys_cas_gen_l:
9457 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: {
9458 Value *Ptr = EmitScalarExpr(E->getArg(0));
9459 return Builder.CreateCall(
9460 CGM.getIntrinsic(
9461 Intrinsic::nvvm_atomic_cas_gen_i_sys,
9462 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9463 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9464 }
Artem Belevichd21e5c62015-06-25 18:29:42 +00009465 default:
9466 return nullptr;
9467 }
9468}
Dan Gohmanc2853072015-09-03 22:51:53 +00009469
9470Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
9471 const CallExpr *E) {
9472 switch (BuiltinID) {
Derek Schuffdbd24b42016-05-02 17:26:19 +00009473 case WebAssembly::BI__builtin_wasm_current_memory: {
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009474 llvm::Type *ResultType = ConvertType(E->getType());
Derek Schuffdbd24b42016-05-02 17:26:19 +00009475 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType);
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009476 return Builder.CreateCall(Callee);
9477 }
Dan Gohman24f0a082015-11-05 20:16:37 +00009478 case WebAssembly::BI__builtin_wasm_grow_memory: {
Dan Gohman266b38a2015-10-02 20:20:01 +00009479 Value *X = EmitScalarExpr(E->getArg(0));
Dan Gohman24f0a082015-11-05 20:16:37 +00009480 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType());
Dan Gohman266b38a2015-10-02 20:20:01 +00009481 return Builder.CreateCall(Callee, X);
9482 }
Heejin Ahnb92440e2017-06-30 00:44:01 +00009483 case WebAssembly::BI__builtin_wasm_throw: {
9484 Value *Tag = EmitScalarExpr(E->getArg(0));
9485 Value *Obj = EmitScalarExpr(E->getArg(1));
9486 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
9487 return Builder.CreateCall(Callee, {Tag, Obj});
9488 }
9489 case WebAssembly::BI__builtin_wasm_rethrow: {
9490 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow);
9491 return Builder.CreateCall(Callee);
9492 }
Dan Gohmanc2853072015-09-03 22:51:53 +00009493
9494 default:
9495 return nullptr;
9496 }
9497}