blob: 1de7c6e17d11e6a55ddcd2bfadabe13d136b1681 [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"
Akira Hatanakaa4638122017-10-06 07:47:47 +000033#include "llvm/Support/ScopedPrinter.h"
Reid Kleckner30701ed2017-09-05 20:27:35 +000034#include "llvm/Support/ConvertUTF.h"
Kit Barton8246f282015-03-25 19:41:41 +000035#include <sstream>
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +000036
Anders Carlsson1d8e5212007-08-20 18:05:56 +000037using namespace clang;
38using namespace CodeGen;
Anders Carlssona020c432007-12-09 21:20:04 +000039using namespace llvm;
40
Sean Fertile96d9e0e2017-01-05 21:43:30 +000041static
42int64_t clamp(int64_t Value, int64_t Low, int64_t High) {
43 return std::min(High, std::max(Low, Value));
44}
45
John McCall30e4efd2011-09-13 23:05:03 +000046/// getBuiltinLibFunction - Given a builtin id for a function like
47/// "__builtin_fabsf", return a Function* for "fabsf".
John McCallb92ab1a2016-10-26 23:46:34 +000048llvm::Constant *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD,
49 unsigned BuiltinID) {
John McCall30e4efd2011-09-13 23:05:03 +000050 assert(Context.BuiltinInfo.isLibFunction(BuiltinID));
51
52 // Get the name, skip over the __builtin_ prefix (if necessary).
53 StringRef Name;
54 GlobalDecl D(FD);
55
56 // If the builtin has been declared explicitly with an assembler label,
57 // use the mangled name. This differs from the plain label on platforms
58 // that prefix labels.
59 if (FD->hasAttr<AsmLabelAttr>())
60 Name = getMangledName(D);
61 else
Mehdi Amini7186a432016-10-11 19:04:24 +000062 Name = Context.BuiltinInfo.getName(BuiltinID) + 10;
John McCall30e4efd2011-09-13 23:05:03 +000063
64 llvm::FunctionType *Ty =
65 cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType()));
66
67 return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false);
68}
69
John McCall3a7f6922010-10-27 20:58:56 +000070/// Emit the conversions required to turn the given value into an
71/// integer of the given size.
72static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V,
Chris Lattner2192fe52011-07-18 04:24:23 +000073 QualType T, llvm::IntegerType *IntType) {
John McCall3a7f6922010-10-27 20:58:56 +000074 V = CGF.EmitToMemory(V, T);
Chris Lattner07e96862010-10-01 23:43:16 +000075
John McCall3a7f6922010-10-27 20:58:56 +000076 if (V->getType()->isPointerTy())
77 return CGF.Builder.CreatePtrToInt(V, IntType);
78
79 assert(V->getType() == IntType);
80 return V;
Chandler Carruthbc8cab12010-07-18 07:23:17 +000081}
82
John McCall3a7f6922010-10-27 20:58:56 +000083static Value *EmitFromInt(CodeGenFunction &CGF, llvm::Value *V,
Chris Lattner2192fe52011-07-18 04:24:23 +000084 QualType T, llvm::Type *ResultType) {
John McCall3a7f6922010-10-27 20:58:56 +000085 V = CGF.EmitFromMemory(V, T);
86
87 if (ResultType->isPointerTy())
88 return CGF.Builder.CreateIntToPtr(V, ResultType);
89
90 assert(V->getType() == ResultType);
91 return V;
Chandler Carruthbc8cab12010-07-18 07:23:17 +000092}
93
Daniel Dunbar4fab57d2009-04-07 00:55:51 +000094/// Utility to insert an atomic instruction based on Instrinsic::ID
95/// and the expression node.
Artem Belevichd21e5c62015-06-25 18:29:42 +000096static Value *MakeBinaryAtomicValue(CodeGenFunction &CGF,
97 llvm::AtomicRMWInst::BinOp Kind,
98 const CallExpr *E) {
John McCall3a7f6922010-10-27 20:58:56 +000099 QualType T = E->getType();
100 assert(E->getArg(0)->getType()->isPointerType());
101 assert(CGF.getContext().hasSameUnqualifiedType(T,
102 E->getArg(0)->getType()->getPointeeType()));
103 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
104
Chris Lattnerb2f659b2010-09-21 23:40:48 +0000105 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +0000106 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
John McCall6bde9542010-10-26 22:09:15 +0000107
Chris Lattnera5f58b02011-07-09 17:41:47 +0000108 llvm::IntegerType *IntType =
John McCall3a7f6922010-10-27 20:58:56 +0000109 llvm::IntegerType::get(CGF.getLLVMContext(),
110 CGF.getContext().getTypeSize(T));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000111 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
John McCall3a7f6922010-10-27 20:58:56 +0000112
John McCall3a7f6922010-10-27 20:58:56 +0000113 llvm::Value *Args[2];
114 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
115 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
Chris Lattner2192fe52011-07-18 04:24:23 +0000116 llvm::Type *ValueType = Args[1]->getType();
John McCall3a7f6922010-10-27 20:58:56 +0000117 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
118
JF Bastien92f4ef12016-04-06 17:26:42 +0000119 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
120 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
Artem Belevichd21e5c62015-06-25 18:29:42 +0000121 return EmitFromInt(CGF, Result, T, ValueType);
122}
123
Michael Zolotukhin84df1232015-09-08 23:52:33 +0000124static Value *EmitNontemporalStore(CodeGenFunction &CGF, const CallExpr *E) {
125 Value *Val = CGF.EmitScalarExpr(E->getArg(0));
126 Value *Address = CGF.EmitScalarExpr(E->getArg(1));
127
128 // Convert the type of the pointer to a pointer to the stored type.
129 Val = CGF.EmitToMemory(Val, E->getArg(0)->getType());
130 Value *BC = CGF.Builder.CreateBitCast(
131 Address, llvm::PointerType::getUnqual(Val->getType()), "cast");
132 LValue LV = CGF.MakeNaturalAlignAddrLValue(BC, E->getArg(0)->getType());
133 LV.setNontemporal(true);
134 CGF.EmitStoreOfScalar(Val, LV, false);
135 return nullptr;
136}
137
138static Value *EmitNontemporalLoad(CodeGenFunction &CGF, const CallExpr *E) {
139 Value *Address = CGF.EmitScalarExpr(E->getArg(0));
140
141 LValue LV = CGF.MakeNaturalAlignAddrLValue(Address, E->getType());
142 LV.setNontemporal(true);
143 return CGF.EmitLoadOfScalar(LV, E->getExprLoc());
144}
145
Artem Belevichd21e5c62015-06-25 18:29:42 +0000146static RValue EmitBinaryAtomic(CodeGenFunction &CGF,
147 llvm::AtomicRMWInst::BinOp Kind,
148 const CallExpr *E) {
149 return RValue::get(MakeBinaryAtomicValue(CGF, Kind, E));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +0000150}
151
152/// Utility to insert an atomic instruction based Instrinsic::ID and
John McCall3a7f6922010-10-27 20:58:56 +0000153/// the expression node, where the return value is the result of the
154/// operation.
Chris Lattner43660c52010-05-06 05:35:16 +0000155static RValue EmitBinaryAtomicPost(CodeGenFunction &CGF,
Eli Friedmane9f81132011-09-07 01:41:24 +0000156 llvm::AtomicRMWInst::BinOp Kind,
157 const CallExpr *E,
Hal Finkeld2208b52014-10-02 20:53:50 +0000158 Instruction::BinaryOps Op,
159 bool Invert = false) {
John McCall3a7f6922010-10-27 20:58:56 +0000160 QualType T = E->getType();
161 assert(E->getArg(0)->getType()->isPointerType());
162 assert(CGF.getContext().hasSameUnqualifiedType(T,
163 E->getArg(0)->getType()->getPointeeType()));
164 assert(CGF.getContext().hasSameUnqualifiedType(T, E->getArg(1)->getType()));
165
Chris Lattnerb2f659b2010-09-21 23:40:48 +0000166 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +0000167 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
John McCall6bde9542010-10-26 22:09:15 +0000168
Chris Lattnera5f58b02011-07-09 17:41:47 +0000169 llvm::IntegerType *IntType =
John McCall3a7f6922010-10-27 20:58:56 +0000170 llvm::IntegerType::get(CGF.getLLVMContext(),
171 CGF.getContext().getTypeSize(T));
Chris Lattnera5f58b02011-07-09 17:41:47 +0000172 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
John McCall3a7f6922010-10-27 20:58:56 +0000173
John McCall3a7f6922010-10-27 20:58:56 +0000174 llvm::Value *Args[2];
175 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
Chris Lattner2192fe52011-07-18 04:24:23 +0000176 llvm::Type *ValueType = Args[1]->getType();
John McCall3a7f6922010-10-27 20:58:56 +0000177 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
178 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
179
JF Bastien92f4ef12016-04-06 17:26:42 +0000180 llvm::Value *Result = CGF.Builder.CreateAtomicRMW(
181 Kind, Args[0], Args[1], llvm::AtomicOrdering::SequentiallyConsistent);
John McCall3a7f6922010-10-27 20:58:56 +0000182 Result = CGF.Builder.CreateBinOp(Op, Result, Args[1]);
Hal Finkeld2208b52014-10-02 20:53:50 +0000183 if (Invert)
184 Result = CGF.Builder.CreateBinOp(llvm::Instruction::Xor, Result,
185 llvm::ConstantInt::get(IntType, -1));
John McCall3a7f6922010-10-27 20:58:56 +0000186 Result = EmitFromInt(CGF, Result, T, ValueType);
187 return RValue::get(Result);
Mon P Wangb84407d2008-05-09 22:40:52 +0000188}
189
Artem Belevichd21e5c62015-06-25 18:29:42 +0000190/// @brief Utility to insert an atomic cmpxchg instruction.
191///
192/// @param CGF The current codegen function.
193/// @param E Builtin call expression to convert to cmpxchg.
194/// arg0 - address to operate on
195/// arg1 - value to compare with
196/// arg2 - new value
197/// @param ReturnBool Specifies whether to return success flag of
198/// cmpxchg result or the old value.
199///
200/// @returns result of cmpxchg, according to ReturnBool
201static Value *MakeAtomicCmpXchgValue(CodeGenFunction &CGF, const CallExpr *E,
202 bool ReturnBool) {
203 QualType T = ReturnBool ? E->getArg(1)->getType() : E->getType();
204 llvm::Value *DestPtr = CGF.EmitScalarExpr(E->getArg(0));
205 unsigned AddrSpace = DestPtr->getType()->getPointerAddressSpace();
206
207 llvm::IntegerType *IntType = llvm::IntegerType::get(
208 CGF.getLLVMContext(), CGF.getContext().getTypeSize(T));
209 llvm::Type *IntPtrType = IntType->getPointerTo(AddrSpace);
210
211 Value *Args[3];
212 Args[0] = CGF.Builder.CreateBitCast(DestPtr, IntPtrType);
213 Args[1] = CGF.EmitScalarExpr(E->getArg(1));
214 llvm::Type *ValueType = Args[1]->getType();
215 Args[1] = EmitToInt(CGF, Args[1], T, IntType);
216 Args[2] = EmitToInt(CGF, CGF.EmitScalarExpr(E->getArg(2)), T, IntType);
217
JF Bastien92f4ef12016-04-06 17:26:42 +0000218 Value *Pair = CGF.Builder.CreateAtomicCmpXchg(
219 Args[0], Args[1], Args[2], llvm::AtomicOrdering::SequentiallyConsistent,
220 llvm::AtomicOrdering::SequentiallyConsistent);
Artem Belevichd21e5c62015-06-25 18:29:42 +0000221 if (ReturnBool)
222 // Extract boolean success flag and zext it to int.
223 return CGF.Builder.CreateZExt(CGF.Builder.CreateExtractValue(Pair, 1),
224 CGF.ConvertType(E->getType()));
225 else
226 // Extract old value and emit it using the same type as compare value.
227 return EmitFromInt(CGF, CGF.Builder.CreateExtractValue(Pair, 0), T,
228 ValueType);
229}
230
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000231// Emit a simple mangled intrinsic that has 1 argument and a return type
232// matching the argument type.
233static Value *emitUnaryBuiltin(CodeGenFunction &CGF,
234 const CallExpr *E,
235 unsigned IntrinsicID) {
236 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
237
238 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
239 return CGF.Builder.CreateCall(F, Src0);
240}
241
242// Emit an intrinsic that has 2 operands of the same type as its result.
243static Value *emitBinaryBuiltin(CodeGenFunction &CGF,
244 const CallExpr *E,
245 unsigned IntrinsicID) {
246 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
247 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
248
249 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
250 return CGF.Builder.CreateCall(F, { Src0, Src1 });
251}
252
253// Emit an intrinsic that has 3 operands of the same type as its result.
254static Value *emitTernaryBuiltin(CodeGenFunction &CGF,
255 const CallExpr *E,
256 unsigned IntrinsicID) {
257 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
258 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
259 llvm::Value *Src2 = CGF.EmitScalarExpr(E->getArg(2));
260
261 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
262 return CGF.Builder.CreateCall(F, { Src0, Src1, Src2 });
263}
264
265// Emit an intrinsic that has 1 float or double operand, and 1 integer.
266static Value *emitFPIntBuiltin(CodeGenFunction &CGF,
267 const CallExpr *E,
268 unsigned IntrinsicID) {
269 llvm::Value *Src0 = CGF.EmitScalarExpr(E->getArg(0));
270 llvm::Value *Src1 = CGF.EmitScalarExpr(E->getArg(1));
271
272 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, Src0->getType());
273 return CGF.Builder.CreateCall(F, {Src0, Src1});
274}
275
Tom Stellardc4e0c102014-09-03 15:24:29 +0000276/// EmitFAbs - Emit a call to @llvm.fabs().
Reid Kleckner4cad00a2014-11-03 23:51:40 +0000277static Value *EmitFAbs(CodeGenFunction &CGF, Value *V) {
Tom Stellardc4e0c102014-09-03 15:24:29 +0000278 Value *F = CGF.CGM.getIntrinsic(Intrinsic::fabs, V->getType());
279 llvm::CallInst *Call = CGF.Builder.CreateCall(F, V);
280 Call->setDoesNotAccessMemory();
281 return Call;
Chris Lattner43660c52010-05-06 05:35:16 +0000282}
283
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000284/// Emit the computation of the sign bit for a floating point value. Returns
285/// the i1 sign bit value.
286static Value *EmitSignBit(CodeGenFunction &CGF, Value *V) {
287 LLVMContext &C = CGF.CGM.getLLVMContext();
288
289 llvm::Type *Ty = V->getType();
290 int Width = Ty->getPrimitiveSizeInBits();
291 llvm::Type *IntTy = llvm::IntegerType::get(C, Width);
292 V = CGF.Builder.CreateBitCast(V, IntTy);
293 if (Ty->isPPC_FP128Ty()) {
Petar Jovanovic73d10442015-11-06 14:52:46 +0000294 // We want the sign bit of the higher-order double. The bitcast we just
295 // did works as if the double-double was stored to memory and then
296 // read as an i128. The "store" will put the higher-order double in the
297 // lower address in both little- and big-Endian modes, but the "load"
298 // will treat those bits as a different part of the i128: the low bits in
299 // little-Endian, the high bits in big-Endian. Therefore, on big-Endian
300 // we need to shift the high bits down to the low before truncating.
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000301 Width >>= 1;
Simon Pilgrim532de1c2016-06-13 10:05:19 +0000302 if (CGF.getTarget().isBigEndian()) {
303 Value *ShiftCst = llvm::ConstantInt::get(IntTy, Width);
304 V = CGF.Builder.CreateLShr(V, ShiftCst);
305 }
306 // We are truncating value in order to extract the higher-order
307 // double, which we will be using to extract the sign from.
308 IntTy = llvm::IntegerType::get(C, Width);
309 V = CGF.Builder.CreateTrunc(V, IntTy);
Chandler Carruthc66deaf2015-03-19 22:39:51 +0000310 }
311 Value *Zero = llvm::Constant::getNullValue(IntTy);
312 return CGF.Builder.CreateICmpSLT(V, Zero);
313}
314
John McCallb92ab1a2016-10-26 23:46:34 +0000315static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *FD,
316 const CallExpr *E, llvm::Constant *calleeValue) {
317 CGCallee callee = CGCallee::forDirect(calleeValue, FD);
318 return CGF.EmitCall(E->getCallee()->getType(), callee, E, ReturnValueSlot());
John McCall30e4efd2011-09-13 23:05:03 +0000319}
320
Michael Gottesman54398012013-01-13 02:22:39 +0000321/// \brief Emit a call to llvm.{sadd,uadd,ssub,usub,smul,umul}.with.overflow.*
322/// depending on IntrinsicID.
323///
324/// \arg CGF The current codegen function.
325/// \arg IntrinsicID The ID for the Intrinsic we wish to generate.
326/// \arg X The first argument to the llvm.*.with.overflow.*.
327/// \arg Y The second argument to the llvm.*.with.overflow.*.
328/// \arg Carry The carry returned by the llvm.*.with.overflow.*.
329/// \returns The result (i.e. sum/product) returned by the intrinsic.
330static llvm::Value *EmitOverflowIntrinsic(CodeGenFunction &CGF,
331 const llvm::Intrinsic::ID IntrinsicID,
332 llvm::Value *X, llvm::Value *Y,
333 llvm::Value *&Carry) {
334 // Make sure we have integers of the same width.
335 assert(X->getType() == Y->getType() &&
336 "Arguments must be the same type. (Did you forget to make sure both "
337 "arguments have the same integer width?)");
338
NAKAMURA Takumi7ab4fbf2013-01-13 11:26:44 +0000339 llvm::Value *Callee = CGF.CGM.getIntrinsic(IntrinsicID, X->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +0000340 llvm::Value *Tmp = CGF.Builder.CreateCall(Callee, {X, Y});
Michael Gottesman54398012013-01-13 02:22:39 +0000341 Carry = CGF.Builder.CreateExtractValue(Tmp, 1);
342 return CGF.Builder.CreateExtractValue(Tmp, 0);
343}
344
Jan Veselyd7e03a52016-07-10 22:38:04 +0000345static Value *emitRangedBuiltin(CodeGenFunction &CGF,
346 unsigned IntrinsicID,
347 int low, int high) {
348 llvm::MDBuilder MDHelper(CGF.getLLVMContext());
349 llvm::MDNode *RNode = MDHelper.createRange(APInt(32, low), APInt(32, high));
350 Value *F = CGF.CGM.getIntrinsic(IntrinsicID, {});
351 llvm::Instruction *Call = CGF.Builder.CreateCall(F);
352 Call->setMetadata(llvm::LLVMContext::MD_range, RNode);
353 return Call;
354}
355
John McCall03107a42015-10-29 20:48:01 +0000356namespace {
357 struct WidthAndSignedness {
358 unsigned Width;
359 bool Signed;
360 };
361}
362
363static WidthAndSignedness
364getIntegerWidthAndSignedness(const clang::ASTContext &context,
365 const clang::QualType Type) {
366 assert(Type->isIntegerType() && "Given type is not an integer.");
367 unsigned Width = Type->isBooleanType() ? 1 : context.getTypeInfo(Type).Width;
368 bool Signed = Type->isSignedIntegerType();
369 return {Width, Signed};
370}
371
372// Given one or more integer types, this function produces an integer type that
373// encompasses them: any value in one of the given types could be expressed in
374// the encompassing type.
375static struct WidthAndSignedness
376EncompassingIntegerType(ArrayRef<struct WidthAndSignedness> Types) {
377 assert(Types.size() > 0 && "Empty list of types.");
378
379 // If any of the given types is signed, we must return a signed type.
380 bool Signed = false;
381 for (const auto &Type : Types) {
382 Signed |= Type.Signed;
383 }
384
385 // The encompassing type must have a width greater than or equal to the width
386 // of the specified types. Aditionally, if the encompassing type is signed,
387 // its width must be strictly greater than the width of any unsigned types
388 // given.
389 unsigned Width = 0;
390 for (const auto &Type : Types) {
391 unsigned MinWidth = Type.Width + (Signed && !Type.Signed);
392 if (Width < MinWidth) {
393 Width = MinWidth;
394 }
395 }
396
397 return {Width, Signed};
398}
399
Charles Davisc7d5c942015-09-17 20:55:33 +0000400Value *CodeGenFunction::EmitVAStartEnd(Value *ArgValue, bool IsStart) {
401 llvm::Type *DestType = Int8PtrTy;
402 if (ArgValue->getType() != DestType)
403 ArgValue =
404 Builder.CreateBitCast(ArgValue, DestType, ArgValue->getName().data());
405
406 Intrinsic::ID inst = IsStart ? Intrinsic::vastart : Intrinsic::vaend;
407 return Builder.CreateCall(CGM.getIntrinsic(inst), ArgValue);
408}
409
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000410/// Checks if using the result of __builtin_object_size(p, @p From) in place of
411/// __builtin_object_size(p, @p To) is correct
412static bool areBOSTypesCompatible(int From, int To) {
413 // Note: Our __builtin_object_size implementation currently treats Type=0 and
414 // Type=2 identically. Encoding this implementation detail here may make
415 // improving __builtin_object_size difficult in the future, so it's omitted.
416 return From == To || (From == 0 && To == 1) || (From == 3 && To == 2);
417}
418
419static llvm::Value *
420getDefaultBuiltinObjectSizeResult(unsigned Type, llvm::IntegerType *ResType) {
421 return ConstantInt::get(ResType, (Type & 2) ? 0 : -1, /*isSigned=*/true);
422}
423
424llvm::Value *
425CodeGenFunction::evaluateOrEmitBuiltinObjectSize(const Expr *E, unsigned Type,
George Burgess IV0d6592a2017-02-23 05:59:56 +0000426 llvm::IntegerType *ResType,
427 llvm::Value *EmittedE) {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000428 uint64_t ObjectSize;
429 if (!E->tryEvaluateObjectSize(ObjectSize, getContext(), Type))
George Burgess IV0d6592a2017-02-23 05:59:56 +0000430 return emitBuiltinObjectSize(E, Type, ResType, EmittedE);
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000431 return ConstantInt::get(ResType, ObjectSize, /*isSigned=*/true);
432}
433
434/// Returns a Value corresponding to the size of the given expression.
435/// This Value may be either of the following:
436/// - A llvm::Argument (if E is a param with the pass_object_size attribute on
437/// it)
438/// - A call to the @llvm.objectsize intrinsic
George Burgess IV0d6592a2017-02-23 05:59:56 +0000439///
440/// EmittedE is the result of emitting `E` as a scalar expr. If it's non-null
441/// and we wouldn't otherwise try to reference a pass_object_size parameter,
442/// we'll call @llvm.objectsize on EmittedE, rather than emitting E.
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000443llvm::Value *
444CodeGenFunction::emitBuiltinObjectSize(const Expr *E, unsigned Type,
George Burgess IV0d6592a2017-02-23 05:59:56 +0000445 llvm::IntegerType *ResType,
446 llvm::Value *EmittedE) {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000447 // We need to reference an argument if the pointer is a parameter with the
448 // pass_object_size attribute.
449 if (auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
450 auto *Param = dyn_cast<ParmVarDecl>(D->getDecl());
451 auto *PS = D->getDecl()->getAttr<PassObjectSizeAttr>();
452 if (Param != nullptr && PS != nullptr &&
453 areBOSTypesCompatible(PS->getType(), Type)) {
454 auto Iter = SizeArguments.find(Param);
455 assert(Iter != SizeArguments.end());
456
457 const ImplicitParamDecl *D = Iter->second;
458 auto DIter = LocalDeclMap.find(D);
459 assert(DIter != LocalDeclMap.end());
460
461 return EmitLoadOfScalar(DIter->second, /*volatile=*/false,
462 getContext().getSizeType(), E->getLocStart());
463 }
464 }
465
466 // LLVM can't handle Type=3 appropriately, and __builtin_object_size shouldn't
467 // evaluate E for side-effects. In either case, we shouldn't lower to
468 // @llvm.objectsize.
George Burgess IV0d6592a2017-02-23 05:59:56 +0000469 if (Type == 3 || (!EmittedE && E->HasSideEffects(getContext())))
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000470 return getDefaultBuiltinObjectSizeResult(Type, ResType);
471
George Burgess IV0d6592a2017-02-23 05:59:56 +0000472 Value *Ptr = EmittedE ? EmittedE : EmitScalarExpr(E);
George Burgess IV8856aa92017-02-22 02:35:51 +0000473 assert(Ptr->getType()->isPointerTy() &&
474 "Non-pointer passed to __builtin_object_size?");
475
George Burgess IV8856aa92017-02-22 02:35:51 +0000476 Value *F = CGM.getIntrinsic(Intrinsic::objectsize, {ResType, Ptr->getType()});
George Burgess IVa63f9152017-03-21 20:09:35 +0000477
478 // LLVM only supports 0 and 2, make sure that we pass along that as a boolean.
479 Value *Min = Builder.getInt1((Type & 2) != 0);
480 // For GCC compatability, __builtin_object_size treat NULL as unknown size.
481 Value *NullIsUnknown = Builder.getTrue();
482 return Builder.CreateCall(F, {Ptr, Min, NullIsUnknown});
George Burgess IV3e3bb95b2015-12-02 21:58:08 +0000483}
484
Albert Gutowski5e08df02016-10-13 22:35:07 +0000485// Many of MSVC builtins are on both x64 and ARM; to avoid repeating code, we
486// handle them here.
487enum class CodeGenFunction::MSVCIntrin {
488 _BitScanForward,
489 _BitScanReverse,
490 _InterlockedAnd,
491 _InterlockedDecrement,
492 _InterlockedExchange,
493 _InterlockedExchangeAdd,
494 _InterlockedExchangeSub,
495 _InterlockedIncrement,
496 _InterlockedOr,
497 _InterlockedXor,
Hans Wennborg5c3c51f2017-04-07 16:41:47 +0000498 _interlockedbittestandset,
Reid Kleckner04f9f912017-02-09 18:31:06 +0000499 __fastfail,
Albert Gutowski5e08df02016-10-13 22:35:07 +0000500};
501
502Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
Reid Kleckner04f9f912017-02-09 18:31:06 +0000503 const CallExpr *E) {
Albert Gutowski5e08df02016-10-13 22:35:07 +0000504 switch (BuiltinID) {
505 case MSVCIntrin::_BitScanForward:
506 case MSVCIntrin::_BitScanReverse: {
507 Value *ArgValue = EmitScalarExpr(E->getArg(1));
508
509 llvm::Type *ArgType = ArgValue->getType();
510 llvm::Type *IndexType =
511 EmitScalarExpr(E->getArg(0))->getType()->getPointerElementType();
512 llvm::Type *ResultType = ConvertType(E->getType());
513
514 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
515 Value *ResZero = llvm::Constant::getNullValue(ResultType);
516 Value *ResOne = llvm::ConstantInt::get(ResultType, 1);
517
518 BasicBlock *Begin = Builder.GetInsertBlock();
519 BasicBlock *End = createBasicBlock("bitscan_end", this->CurFn);
520 Builder.SetInsertPoint(End);
521 PHINode *Result = Builder.CreatePHI(ResultType, 2, "bitscan_result");
522
523 Builder.SetInsertPoint(Begin);
524 Value *IsZero = Builder.CreateICmpEQ(ArgValue, ArgZero);
525 BasicBlock *NotZero = createBasicBlock("bitscan_not_zero", this->CurFn);
526 Builder.CreateCondBr(IsZero, End, NotZero);
527 Result->addIncoming(ResZero, Begin);
528
529 Builder.SetInsertPoint(NotZero);
530 Address IndexAddress = EmitPointerWithAlignment(E->getArg(0));
531
532 if (BuiltinID == MSVCIntrin::_BitScanForward) {
533 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
534 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
535 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
536 Builder.CreateStore(ZeroCount, IndexAddress, false);
537 } else {
538 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
539 Value *ArgTypeLastIndex = llvm::ConstantInt::get(IndexType, ArgWidth - 1);
540
541 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
542 Value *ZeroCount = Builder.CreateCall(F, {ArgValue, Builder.getTrue()});
543 ZeroCount = Builder.CreateIntCast(ZeroCount, IndexType, false);
544 Value *Index = Builder.CreateNSWSub(ArgTypeLastIndex, ZeroCount);
545 Builder.CreateStore(Index, IndexAddress, false);
546 }
547 Builder.CreateBr(End);
548 Result->addIncoming(ResOne, NotZero);
549
550 Builder.SetInsertPoint(End);
551 return Result;
552 }
553 case MSVCIntrin::_InterlockedAnd:
554 return MakeBinaryAtomicValue(*this, AtomicRMWInst::And, E);
555 case MSVCIntrin::_InterlockedExchange:
556 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E);
557 case MSVCIntrin::_InterlockedExchangeAdd:
558 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Add, E);
559 case MSVCIntrin::_InterlockedExchangeSub:
560 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Sub, E);
561 case MSVCIntrin::_InterlockedOr:
562 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Or, E);
563 case MSVCIntrin::_InterlockedXor:
564 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xor, E);
565
Hans Wennborg5c3c51f2017-04-07 16:41:47 +0000566 case MSVCIntrin::_interlockedbittestandset: {
567 llvm::Value *Addr = EmitScalarExpr(E->getArg(0));
568 llvm::Value *Bit = EmitScalarExpr(E->getArg(1));
569 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
570 AtomicRMWInst::Or, Addr,
571 Builder.CreateShl(ConstantInt::get(Bit->getType(), 1), Bit),
572 llvm::AtomicOrdering::SequentiallyConsistent);
573 // Shift the relevant bit to the least significant position, truncate to
574 // the result type, and test the low bit.
575 llvm::Value *Shifted = Builder.CreateLShr(RMWI, Bit);
576 llvm::Value *Truncated =
577 Builder.CreateTrunc(Shifted, ConvertType(E->getType()));
578 return Builder.CreateAnd(Truncated,
579 ConstantInt::get(Truncated->getType(), 1));
580 }
581
Albert Gutowski5e08df02016-10-13 22:35:07 +0000582 case MSVCIntrin::_InterlockedDecrement: {
583 llvm::Type *IntTy = ConvertType(E->getType());
584 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
585 AtomicRMWInst::Sub,
586 EmitScalarExpr(E->getArg(0)),
587 ConstantInt::get(IntTy, 1),
588 llvm::AtomicOrdering::SequentiallyConsistent);
589 return Builder.CreateSub(RMWI, ConstantInt::get(IntTy, 1));
590 }
591 case MSVCIntrin::_InterlockedIncrement: {
592 llvm::Type *IntTy = ConvertType(E->getType());
593 AtomicRMWInst *RMWI = Builder.CreateAtomicRMW(
594 AtomicRMWInst::Add,
595 EmitScalarExpr(E->getArg(0)),
596 ConstantInt::get(IntTy, 1),
597 llvm::AtomicOrdering::SequentiallyConsistent);
598 return Builder.CreateAdd(RMWI, ConstantInt::get(IntTy, 1));
599 }
Reid Kleckner04f9f912017-02-09 18:31:06 +0000600
601 case MSVCIntrin::__fastfail: {
602 // Request immediate process termination from the kernel. The instruction
603 // sequences to do this are documented on MSDN:
604 // https://msdn.microsoft.com/en-us/library/dn774154.aspx
605 llvm::Triple::ArchType ISA = getTarget().getTriple().getArch();
606 StringRef Asm, Constraints;
607 switch (ISA) {
608 default:
609 ErrorUnsupported(E, "__fastfail call for this architecture");
610 break;
611 case llvm::Triple::x86:
612 case llvm::Triple::x86_64:
613 Asm = "int $$0x29";
614 Constraints = "{cx}";
615 break;
616 case llvm::Triple::thumb:
617 Asm = "udf #251";
618 Constraints = "{r0}";
619 break;
620 }
621 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, {Int32Ty}, false);
622 llvm::InlineAsm *IA =
623 llvm::InlineAsm::get(FTy, Asm, Constraints, /*SideEffects=*/true);
Reid Klecknerde864822017-03-21 16:57:30 +0000624 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
625 getLLVMContext(), llvm::AttributeList::FunctionIndex,
626 llvm::Attribute::NoReturn);
Reid Kleckner04f9f912017-02-09 18:31:06 +0000627 CallSite CS = Builder.CreateCall(IA, EmitScalarExpr(E->getArg(0)));
628 CS.setAttributes(NoReturnAttr);
629 return CS.getInstruction();
630 }
Albert Gutowski5e08df02016-10-13 22:35:07 +0000631 }
632 llvm_unreachable("Incorrect MSVC intrinsic!");
633}
634
Mehdi Amini06d367c2016-10-24 20:39:34 +0000635namespace {
636// ARC cleanup for __builtin_os_log_format
637struct CallObjCArcUse final : EHScopeStack::Cleanup {
638 CallObjCArcUse(llvm::Value *object) : object(object) {}
639 llvm::Value *object;
640
641 void Emit(CodeGenFunction &CGF, Flags flags) override {
642 CGF.EmitARCIntrinsicUse(object);
643 }
644};
645}
646
Vedant Kumar10c31022017-07-29 00:19:51 +0000647Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
648 BuiltinCheckKind Kind) {
Victor Leschuk198357b2017-07-29 08:18:38 +0000649 assert((Kind == BCK_CLZPassedZero || Kind == BCK_CTZPassedZero)
650 && "Unsupported builtin check kind");
Vedant Kumar10c31022017-07-29 00:19:51 +0000651
652 Value *ArgValue = EmitScalarExpr(E);
653 if (!SanOpts.has(SanitizerKind::Builtin) || !getTarget().isCLZForZeroUndef())
654 return ArgValue;
655
656 SanitizerScope SanScope(this);
657 Value *Cond = Builder.CreateICmpNE(
658 ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
659 EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin),
660 SanitizerHandler::InvalidBuiltin,
661 {EmitCheckSourceLocation(E->getExprLoc()),
662 llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)},
663 None);
664 return ArgValue;
665}
666
Akira Hatanaka6b103bc2017-10-06 07:12:46 +0000667/// Get the argument type for arguments to os_log_helper.
668static CanQualType getOSLogArgType(ASTContext &C, int Size) {
669 QualType UnsignedTy = C.getIntTypeForBitwidth(Size * 8, /*Signed=*/false);
670 return C.getCanonicalType(UnsignedTy);
671}
672
673llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
674 const analyze_os_log::OSLogBufferLayout &Layout,
675 CharUnits BufferAlignment) {
676 ASTContext &Ctx = getContext();
677
678 llvm::SmallString<64> Name;
679 {
680 raw_svector_ostream OS(Name);
681 OS << "__os_log_helper";
682 OS << "_" << BufferAlignment.getQuantity();
683 OS << "_" << int(Layout.getSummaryByte());
684 OS << "_" << int(Layout.getNumArgsByte());
685 for (const auto &Item : Layout.Items)
686 OS << "_" << int(Item.getSizeByte()) << "_"
687 << int(Item.getDescriptorByte());
688 }
689
690 if (llvm::Function *F = CGM.getModule().getFunction(Name))
691 return F;
692
693 llvm::SmallVector<ImplicitParamDecl, 4> Params;
694 Params.emplace_back(Ctx, nullptr, SourceLocation(), &Ctx.Idents.get("buffer"),
695 Ctx.VoidPtrTy, ImplicitParamDecl::Other);
696
697 for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) {
698 char Size = Layout.Items[I].getSizeByte();
699 if (!Size)
700 continue;
701
Akira Hatanakaa4638122017-10-06 07:47:47 +0000702 Params.emplace_back(
703 Ctx, nullptr, SourceLocation(),
704 &Ctx.Idents.get(std::string("arg") + llvm::to_string(I)),
705 getOSLogArgType(Ctx, Size), ImplicitParamDecl::Other);
Akira Hatanaka6b103bc2017-10-06 07:12:46 +0000706 }
707
708 FunctionArgList Args;
709 for (auto &P : Params)
710 Args.push_back(&P);
711
712 // The helper function has linkonce_odr linkage to enable the linker to merge
713 // identical functions. To ensure the merging always happens, 'noinline' is
714 // attached to the function when compiling with -Oz.
715 const CGFunctionInfo &FI =
716 CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
717 llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
718 llvm::Function *Fn = llvm::Function::Create(
719 FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule());
720 Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
721 CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn);
722 CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
723
724 // Attach 'noinline' at -Oz.
725 if (CGM.getCodeGenOpts().OptimizeSize == 2)
726 Fn->addFnAttr(llvm::Attribute::NoInline);
727
728 auto NL = ApplyDebugLocation::CreateEmpty(*this);
729 IdentifierInfo *II = &Ctx.Idents.get(Name);
730 FunctionDecl *FD = FunctionDecl::Create(
731 Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
732 Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false);
733
734 StartFunction(FD, Ctx.VoidTy, Fn, FI, Args);
735
736 // Create a scope with an artificial location for the body of this function.
737 auto AL = ApplyDebugLocation::CreateArtificial(*this);
738
739 CharUnits Offset;
740 Address BufAddr(Builder.CreateLoad(GetAddrOfLocalVar(&Params[0]), "buf"),
741 BufferAlignment);
742 Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()),
743 Builder.CreateConstByteGEP(BufAddr, Offset++, "summary"));
744 Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()),
745 Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs"));
746
747 unsigned I = 1;
748 for (const auto &Item : Layout.Items) {
749 Builder.CreateStore(
750 Builder.getInt8(Item.getDescriptorByte()),
751 Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor"));
752 Builder.CreateStore(
753 Builder.getInt8(Item.getSizeByte()),
754 Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize"));
755
756 CharUnits Size = Item.size();
757 if (!Size.getQuantity())
758 continue;
759
760 Address Arg = GetAddrOfLocalVar(&Params[I]);
761 Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset, "argData");
762 Addr = Builder.CreateBitCast(Addr, Arg.getPointer()->getType(),
763 "argDataCast");
764 Builder.CreateStore(Builder.CreateLoad(Arg), Addr);
765 Offset += Size;
766 ++I;
767 }
768
769 FinishFunction();
770
771 return Fn;
772}
773
774RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
775 assert(E.getNumArgs() >= 2 &&
776 "__builtin_os_log_format takes at least 2 arguments");
777 ASTContext &Ctx = getContext();
778 analyze_os_log::OSLogBufferLayout Layout;
779 analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout);
780 Address BufAddr = EmitPointerWithAlignment(E.getArg(0));
781 llvm::SmallVector<llvm::Value *, 4> RetainableOperands;
782
783 // Ignore argument 1, the format string. It is not currently used.
784 CallArgList Args;
785 Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy);
786
787 for (const auto &Item : Layout.Items) {
788 int Size = Item.getSizeByte();
789 if (!Size)
790 continue;
791
792 llvm::Value *ArgVal;
793
794 if (const Expr *TheExpr = Item.getExpr()) {
795 ArgVal = EmitScalarExpr(TheExpr, /*Ignore*/ false);
796
797 // Check if this is a retainable type.
798 if (TheExpr->getType()->isObjCRetainableType()) {
799 assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar &&
800 "Only scalar can be a ObjC retainable type");
801 // Check if the object is constant, if not, save it in
802 // RetainableOperands.
803 if (!isa<Constant>(ArgVal))
804 RetainableOperands.push_back(ArgVal);
805 }
806 } else {
807 ArgVal = Builder.getInt32(Item.getConstValue().getQuantity());
808 }
809
810 unsigned ArgValSize =
811 CGM.getDataLayout().getTypeSizeInBits(ArgVal->getType());
812 llvm::IntegerType *IntTy = llvm::Type::getIntNTy(getLLVMContext(),
813 ArgValSize);
814 ArgVal = Builder.CreateBitOrPointerCast(ArgVal, IntTy);
815 CanQualType ArgTy = getOSLogArgType(Ctx, Size);
816 // If ArgVal has type x86_fp80, zero-extend ArgVal.
817 ArgVal = Builder.CreateZExtOrBitCast(ArgVal, ConvertType(ArgTy));
818 Args.add(RValue::get(ArgVal), ArgTy);
819 }
820
821 const CGFunctionInfo &FI =
822 CGM.getTypes().arrangeBuiltinFunctionCall(Ctx.VoidTy, Args);
823 llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction(
824 Layout, BufAddr.getAlignment());
825 EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args);
826
827 // Push a clang.arc.use cleanup for each object in RetainableOperands. The
828 // cleanup will cause the use to appear after the final log call, keeping
829 // the object valid while it’s held in the log buffer. Note that if there’s
830 // a release cleanup on the object, it will already be active; since
831 // cleanups are emitted in reverse order, the use will occur before the
832 // object is released.
833 if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount &&
834 CGM.getCodeGenOpts().OptimizationLevel != 0)
835 for (llvm::Value *Object : RetainableOperands)
836 pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), Object);
837
838 return RValue::get(BufAddr.getPointer());
839}
840
Mike Stump11289f42009-09-09 15:08:12 +0000841RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Peter Collingbournef7706832014-12-12 23:41:25 +0000842 unsigned BuiltinID, const CallExpr *E,
843 ReturnValueSlot ReturnValue) {
Chris Lattner24355b52008-10-06 06:56:41 +0000844 // See if we can constant fold this builtin. If so, don't emit it at all.
Anders Carlssonc9687902008-12-01 02:31:41 +0000845 Expr::EvalResult Result;
Eli Friedmandf88c542012-01-06 20:03:09 +0000846 if (E->EvaluateAsRValue(Result, CGM.getContext()) &&
Fariborz Jahanian24ac1592011-04-25 23:10:07 +0000847 !Result.hasSideEffects()) {
Anders Carlssonc9687902008-12-01 02:31:41 +0000848 if (Result.Val.isInt())
John McCallad7c5c12011-02-08 08:22:06 +0000849 return RValue::get(llvm::ConstantInt::get(getLLVMContext(),
Owen Andersonb7a2fe62009-07-24 23:12:58 +0000850 Result.Val.getInt()));
Chris Lattner07e96862010-10-01 23:43:16 +0000851 if (Result.Val.isFloat())
John McCallad7c5c12011-02-08 08:22:06 +0000852 return RValue::get(llvm::ConstantFP::get(getLLVMContext(),
853 Result.Val.getFloat()));
Chris Lattnera1518b12008-10-06 06:09:18 +0000854 }
Mike Stump11289f42009-09-09 15:08:12 +0000855
Chris Lattner24355b52008-10-06 06:56:41 +0000856 switch (BuiltinID) {
857 default: break; // Handle intrinsics and libm functions below.
Chris Lattnera97132a2008-10-06 07:26:43 +0000858 case Builtin::BI__builtin___CFStringMakeConstantString:
David Chisnall481e3a82010-01-23 02:40:42 +0000859 case Builtin::BI__builtin___NSStringMakeConstantString:
John McCallde0fe072017-08-15 21:42:52 +0000860 return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType()));
Chris Lattner0bf67912008-07-09 17:28:44 +0000861 case Builtin::BI__builtin_stdarg_start:
Anders Carlsson24ebce62007-10-12 23:56:29 +0000862 case Builtin::BI__builtin_va_start:
Reid Kleckner597e81d2014-03-26 15:38:33 +0000863 case Builtin::BI__va_start:
Charles Davisc7d5c942015-09-17 20:55:33 +0000864 case Builtin::BI__builtin_va_end:
865 return RValue::get(
866 EmitVAStartEnd(BuiltinID == Builtin::BI__va_start
867 ? EmitScalarExpr(E->getArg(0))
868 : EmitVAListRef(E->getArg(0)).getPointer(),
869 BuiltinID != Builtin::BI__builtin_va_end));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000870 case Builtin::BI__builtin_va_copy: {
John McCall7f416cc2015-09-08 08:05:57 +0000871 Value *DstPtr = EmitVAListRef(E->getArg(0)).getPointer();
872 Value *SrcPtr = EmitVAListRef(E->getArg(1)).getPointer();
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000873
Chris Lattner2192fe52011-07-18 04:24:23 +0000874 llvm::Type *Type = Int8PtrTy;
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000875
876 DstPtr = Builder.CreateBitCast(DstPtr, Type);
877 SrcPtr = Builder.CreateBitCast(SrcPtr, Type);
David Blaikie43f9bb72015-05-18 22:14:03 +0000878 return RValue::get(Builder.CreateCall(CGM.getIntrinsic(Intrinsic::vacopy),
879 {DstPtr, SrcPtr}));
Anders Carlssonc0b0e592008-02-09 20:26:43 +0000880 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000881 case Builtin::BI__builtin_abs:
Eli Friedman65499b42012-01-17 22:11:30 +0000882 case Builtin::BI__builtin_labs:
883 case Builtin::BI__builtin_llabs: {
Mike Stump11289f42009-09-09 15:08:12 +0000884 Value *ArgValue = EmitScalarExpr(E->getArg(0));
885
Chris Lattner28ee5b32008-07-23 06:53:34 +0000886 Value *NegOp = Builder.CreateNeg(ArgValue, "neg");
Mike Stump11289f42009-09-09 15:08:12 +0000887 Value *CmpResult =
888 Builder.CreateICmpSGE(ArgValue,
Owen Anderson0b75f232009-07-31 20:28:54 +0000889 llvm::Constant::getNullValue(ArgValue->getType()),
Chris Lattner28ee5b32008-07-23 06:53:34 +0000890 "abscond");
Mike Stump11289f42009-09-09 15:08:12 +0000891 Value *Result =
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000892 Builder.CreateSelect(CmpResult, ArgValue, NegOp, "abs");
Mike Stump11289f42009-09-09 15:08:12 +0000893
Anders Carlsson4f8eb122007-11-20 19:05:17 +0000894 return RValue::get(Result);
895 }
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000896 case Builtin::BI__builtin_fabs:
897 case Builtin::BI__builtin_fabsf:
898 case Builtin::BI__builtin_fabsl: {
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000899 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::fabs));
Reid Kleckner06ea7d62014-11-03 23:52:09 +0000900 }
Jan Veselyb4379f92014-09-26 01:19:41 +0000901 case Builtin::BI__builtin_fmod:
902 case Builtin::BI__builtin_fmodf:
903 case Builtin::BI__builtin_fmodl: {
904 Value *Arg1 = EmitScalarExpr(E->getArg(0));
905 Value *Arg2 = EmitScalarExpr(E->getArg(1));
906 Value *Result = Builder.CreateFRem(Arg1, Arg2, "fmod");
907 return RValue::get(Result);
908 }
Matt Arsenaultf652cae2016-07-01 17:38:14 +0000909 case Builtin::BI__builtin_copysign:
910 case Builtin::BI__builtin_copysignf:
911 case Builtin::BI__builtin_copysignl: {
912 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::copysign));
913 }
914 case Builtin::BI__builtin_ceil:
915 case Builtin::BI__builtin_ceilf:
916 case Builtin::BI__builtin_ceill: {
917 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::ceil));
918 }
919 case Builtin::BI__builtin_floor:
920 case Builtin::BI__builtin_floorf:
921 case Builtin::BI__builtin_floorl: {
922 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::floor));
923 }
924 case Builtin::BI__builtin_trunc:
925 case Builtin::BI__builtin_truncf:
926 case Builtin::BI__builtin_truncl: {
927 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::trunc));
928 }
929 case Builtin::BI__builtin_rint:
930 case Builtin::BI__builtin_rintf:
931 case Builtin::BI__builtin_rintl: {
932 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::rint));
933 }
934 case Builtin::BI__builtin_nearbyint:
935 case Builtin::BI__builtin_nearbyintf:
936 case Builtin::BI__builtin_nearbyintl: {
937 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::nearbyint));
938 }
939 case Builtin::BI__builtin_round:
940 case Builtin::BI__builtin_roundf:
941 case Builtin::BI__builtin_roundl: {
942 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::round));
943 }
944 case Builtin::BI__builtin_fmin:
945 case Builtin::BI__builtin_fminf:
946 case Builtin::BI__builtin_fminl: {
947 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::minnum));
948 }
949 case Builtin::BI__builtin_fmax:
950 case Builtin::BI__builtin_fmaxf:
951 case Builtin::BI__builtin_fmaxl: {
952 return RValue::get(emitBinaryBuiltin(*this, E, Intrinsic::maxnum));
953 }
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000954 case Builtin::BI__builtin_conj:
955 case Builtin::BI__builtin_conjf:
956 case Builtin::BI__builtin_conjl: {
957 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
958 Value *Real = ComplexVal.first;
959 Value *Imag = ComplexVal.second;
Jim Grosbachd3608f42012-09-21 00:18:27 +0000960 Value *Zero =
961 Imag->getType()->isFPOrFPVectorTy()
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000962 ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType())
963 : llvm::Constant::getNullValue(Imag->getType());
Jim Grosbachd3608f42012-09-21 00:18:27 +0000964
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000965 Imag = Builder.CreateFSub(Zero, Imag, "sub");
966 return RValue::getComplex(std::make_pair(Real, Imag));
967 }
968 case Builtin::BI__builtin_creal:
969 case Builtin::BI__builtin_crealf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000970 case Builtin::BI__builtin_creall:
971 case Builtin::BIcreal:
972 case Builtin::BIcrealf:
973 case Builtin::BIcreall: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000974 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
975 return RValue::get(ComplexVal.first);
976 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000977
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000978 case Builtin::BI__builtin_cimag:
979 case Builtin::BI__builtin_cimagf:
Meador Ingeb97878a2012-12-18 20:58:04 +0000980 case Builtin::BI__builtin_cimagl:
981 case Builtin::BIcimag:
982 case Builtin::BIcimagf:
983 case Builtin::BIcimagl: {
Fariborz Jahanian1ac11192012-08-14 20:09:28 +0000984 ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0));
985 return RValue::get(ComplexVal.second);
986 }
Jim Grosbachd3608f42012-09-21 00:18:27 +0000987
Benjamin Kramer14128162012-01-28 18:42:57 +0000988 case Builtin::BI__builtin_ctzs:
Anders Carlsson093f1a02008-02-06 07:19:27 +0000989 case Builtin::BI__builtin_ctz:
990 case Builtin::BI__builtin_ctzl:
991 case Builtin::BI__builtin_ctzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +0000992 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +0000993
Chris Lattnera5f58b02011-07-09 17:41:47 +0000994 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +0000995 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Anders Carlsson093f1a02008-02-06 07:19:27 +0000996
Chris Lattner2192fe52011-07-18 04:24:23 +0000997 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +0000998 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +0000999 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Anders Carlsson093f1a02008-02-06 07:19:27 +00001000 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001001 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1002 "cast");
Anders Carlsson093f1a02008-02-06 07:19:27 +00001003 return RValue::get(Result);
1004 }
Benjamin Kramer14128162012-01-28 18:42:57 +00001005 case Builtin::BI__builtin_clzs:
Eli Friedman5e2281e2008-05-27 15:32:46 +00001006 case Builtin::BI__builtin_clz:
1007 case Builtin::BI__builtin_clzl:
1008 case Builtin::BI__builtin_clzll: {
Vedant Kumar10c31022017-07-29 00:19:51 +00001009 Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
Mike Stump11289f42009-09-09 15:08:12 +00001010
Chris Lattnera5f58b02011-07-09 17:41:47 +00001011 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001012 Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
Eli Friedman5e2281e2008-05-27 15:32:46 +00001013
Chris Lattner2192fe52011-07-18 04:24:23 +00001014 llvm::Type *ResultType = ConvertType(E->getType());
John McCallc8e01702013-04-16 22:48:15 +00001015 Value *ZeroUndef = Builder.getInt1(getTarget().isCLZForZeroUndef());
David Blaikie43f9bb72015-05-18 22:14:03 +00001016 Value *Result = Builder.CreateCall(F, {ArgValue, ZeroUndef});
Eli Friedman5e2281e2008-05-27 15:32:46 +00001017 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001018 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1019 "cast");
Eli Friedman5e2281e2008-05-27 15:32:46 +00001020 return RValue::get(Result);
1021 }
Daniel Dunbard93abc32008-07-21 17:19:41 +00001022 case Builtin::BI__builtin_ffs:
1023 case Builtin::BI__builtin_ffsl:
1024 case Builtin::BI__builtin_ffsll: {
1025 // ffs(x) -> x ? cttz(x) + 1 : 0
1026 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +00001027
Chris Lattnera5f58b02011-07-09 17:41:47 +00001028 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001029 Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +00001030
Chris Lattner2192fe52011-07-18 04:24:23 +00001031 llvm::Type *ResultType = ConvertType(E->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00001032 Value *Tmp =
1033 Builder.CreateAdd(Builder.CreateCall(F, {ArgValue, Builder.getTrue()}),
1034 llvm::ConstantInt::get(ArgType, 1));
Owen Anderson0b75f232009-07-31 20:28:54 +00001035 Value *Zero = llvm::Constant::getNullValue(ArgType);
Daniel Dunbard93abc32008-07-21 17:19:41 +00001036 Value *IsZero = Builder.CreateICmpEQ(ArgValue, Zero, "iszero");
1037 Value *Result = Builder.CreateSelect(IsZero, Zero, Tmp, "ffs");
1038 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001039 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1040 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +00001041 return RValue::get(Result);
1042 }
1043 case Builtin::BI__builtin_parity:
1044 case Builtin::BI__builtin_parityl:
1045 case Builtin::BI__builtin_parityll: {
1046 // parity(x) -> ctpop(x) & 1
1047 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +00001048
Chris Lattnera5f58b02011-07-09 17:41:47 +00001049 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001050 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +00001051
Chris Lattner2192fe52011-07-18 04:24:23 +00001052 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001053 Value *Tmp = Builder.CreateCall(F, ArgValue);
1054 Value *Result = Builder.CreateAnd(Tmp, llvm::ConstantInt::get(ArgType, 1));
Daniel Dunbard93abc32008-07-21 17:19:41 +00001055 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001056 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1057 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +00001058 return RValue::get(Result);
1059 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00001060 case Builtin::BI__popcnt16:
1061 case Builtin::BI__popcnt:
1062 case Builtin::BI__popcnt64:
Daniel Dunbard93abc32008-07-21 17:19:41 +00001063 case Builtin::BI__builtin_popcount:
1064 case Builtin::BI__builtin_popcountl:
1065 case Builtin::BI__builtin_popcountll: {
1066 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Mike Stump11289f42009-09-09 15:08:12 +00001067
Chris Lattnera5f58b02011-07-09 17:41:47 +00001068 llvm::Type *ArgType = ArgValue->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001069 Value *F = CGM.getIntrinsic(Intrinsic::ctpop, ArgType);
Mike Stump11289f42009-09-09 15:08:12 +00001070
Chris Lattner2192fe52011-07-18 04:24:23 +00001071 llvm::Type *ResultType = ConvertType(E->getType());
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001072 Value *Result = Builder.CreateCall(F, ArgValue);
Daniel Dunbard93abc32008-07-21 17:19:41 +00001073 if (Result->getType() != ResultType)
Duncan Sands7876dad2009-11-16 13:11:21 +00001074 Result = Builder.CreateIntCast(Result, ResultType, /*isSigned*/true,
1075 "cast");
Daniel Dunbard93abc32008-07-21 17:19:41 +00001076 return RValue::get(Result);
1077 }
Albert Gutowskib6a11ac2016-09-08 22:32:19 +00001078 case Builtin::BI_rotr8:
1079 case Builtin::BI_rotr16:
1080 case Builtin::BI_rotr:
1081 case Builtin::BI_lrotr:
1082 case Builtin::BI_rotr64: {
1083 Value *Val = EmitScalarExpr(E->getArg(0));
1084 Value *Shift = EmitScalarExpr(E->getArg(1));
1085
1086 llvm::Type *ArgType = Val->getType();
1087 Shift = Builder.CreateIntCast(Shift, ArgType, false);
1088 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
1089 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
1090 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
1091
1092 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
1093 Shift = Builder.CreateAnd(Shift, Mask);
1094 Value *LeftShift = Builder.CreateSub(ArgTypeSize, Shift);
1095
1096 Value *RightShifted = Builder.CreateLShr(Val, Shift);
1097 Value *LeftShifted = Builder.CreateShl(Val, LeftShift);
1098 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
1099
1100 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
1101 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
1102 return RValue::get(Result);
1103 }
1104 case Builtin::BI_rotl8:
1105 case Builtin::BI_rotl16:
1106 case Builtin::BI_rotl:
1107 case Builtin::BI_lrotl:
1108 case Builtin::BI_rotl64: {
1109 Value *Val = EmitScalarExpr(E->getArg(0));
1110 Value *Shift = EmitScalarExpr(E->getArg(1));
1111
1112 llvm::Type *ArgType = Val->getType();
1113 Shift = Builder.CreateIntCast(Shift, ArgType, false);
1114 unsigned ArgWidth = cast<llvm::IntegerType>(ArgType)->getBitWidth();
1115 Value *ArgTypeSize = llvm::ConstantInt::get(ArgType, ArgWidth);
1116 Value *ArgZero = llvm::Constant::getNullValue(ArgType);
1117
1118 Value *Mask = llvm::ConstantInt::get(ArgType, ArgWidth - 1);
1119 Shift = Builder.CreateAnd(Shift, Mask);
1120 Value *RightShift = Builder.CreateSub(ArgTypeSize, Shift);
1121
1122 Value *LeftShifted = Builder.CreateShl(Val, Shift);
1123 Value *RightShifted = Builder.CreateLShr(Val, RightShift);
1124 Value *Rotated = Builder.CreateOr(LeftShifted, RightShifted);
1125
1126 Value *ShiftIsZero = Builder.CreateICmpEQ(Shift, ArgZero);
1127 Value *Result = Builder.CreateSelect(ShiftIsZero, Val, Rotated);
1128 return RValue::get(Result);
1129 }
Sanjay Patela24296b2015-09-02 20:01:30 +00001130 case Builtin::BI__builtin_unpredictable: {
1131 // Always return the argument of __builtin_unpredictable. LLVM does not
1132 // handle this builtin. Metadata for this builtin should be added directly
1133 // to instructions such as branches or switches that use it.
1134 return RValue::get(EmitScalarExpr(E->getArg(0)));
1135 }
Fariborz Jahanian0ebca282010-07-26 23:11:03 +00001136 case Builtin::BI__builtin_expect: {
Fariborz Jahanian24ac1592011-04-25 23:10:07 +00001137 Value *ArgValue = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001138 llvm::Type *ArgType = ArgValue->getType();
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001139
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001140 Value *ExpectedValue = EmitScalarExpr(E->getArg(1));
Pete Cooperf051cbf2015-01-26 20:51:58 +00001141 // Don't generate llvm.expect on -O0 as the backend won't use it for
1142 // anything.
1143 // Note, we still IRGen ExpectedValue because it could have side-effects.
1144 if (CGM.getCodeGenOpts().OptimizationLevel == 0)
1145 return RValue::get(ArgValue);
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001146
Pete Cooperf051cbf2015-01-26 20:51:58 +00001147 Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001148 Value *Result =
1149 Builder.CreateCall(FnExpect, {ArgValue, ExpectedValue}, "expval");
Jakub Staszakd2cf2cb2011-07-08 22:45:14 +00001150 return RValue::get(Result);
Fariborz Jahanian0ebca282010-07-26 23:11:03 +00001151 }
Hal Finkelbcc06082014-09-07 22:58:14 +00001152 case Builtin::BI__builtin_assume_aligned: {
1153 Value *PtrValue = EmitScalarExpr(E->getArg(0));
1154 Value *OffsetValue =
1155 (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
1156
1157 Value *AlignmentValue = EmitScalarExpr(E->getArg(1));
1158 ConstantInt *AlignmentCI = cast<ConstantInt>(AlignmentValue);
1159 unsigned Alignment = (unsigned) AlignmentCI->getZExtValue();
1160
1161 EmitAlignmentAssumption(PtrValue, Alignment, OffsetValue);
1162 return RValue::get(PtrValue);
1163 }
1164 case Builtin::BI__assume:
1165 case Builtin::BI__builtin_assume: {
1166 if (E->getArg(0)->HasSideEffects(getContext()))
1167 return RValue::get(nullptr);
1168
1169 Value *ArgValue = EmitScalarExpr(E->getArg(0));
1170 Value *FnAssume = CGM.getIntrinsic(Intrinsic::assume);
1171 return RValue::get(Builder.CreateCall(FnAssume, ArgValue));
1172 }
Benjamin Kramera801f4a2012-10-06 14:42:22 +00001173 case Builtin::BI__builtin_bswap16:
Anders Carlssonef93b9d2007-12-02 21:58:10 +00001174 case Builtin::BI__builtin_bswap32:
1175 case Builtin::BI__builtin_bswap64: {
Matt Arsenault105e8922016-02-03 17:49:38 +00001176 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bswap));
1177 }
Matt Arsenault08087c52016-03-23 22:14:43 +00001178 case Builtin::BI__builtin_bitreverse8:
Matt Arsenault105e8922016-02-03 17:49:38 +00001179 case Builtin::BI__builtin_bitreverse16:
1180 case Builtin::BI__builtin_bitreverse32:
1181 case Builtin::BI__builtin_bitreverse64: {
1182 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::bitreverse));
Mike Stump11289f42009-09-09 15:08:12 +00001183 }
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001184 case Builtin::BI__builtin_object_size: {
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001185 unsigned Type =
1186 E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue();
1187 auto *ResType = cast<llvm::IntegerType>(ConvertType(E->getType()));
Richard Smith01ade172012-05-23 04:13:20 +00001188
George Burgess IV3e3bb95b2015-12-02 21:58:08 +00001189 // We pass this builtin onto the optimizer so that it can figure out the
1190 // object size in more complex cases.
George Burgess IV0d6592a2017-02-23 05:59:56 +00001191 return RValue::get(emitBuiltinObjectSize(E->getArg(0), Type, ResType,
1192 /*EmittedE=*/nullptr));
Daniel Dunbarb0d34c82008-09-03 21:13:56 +00001193 }
Daniel Dunbarb7257262008-07-21 22:59:13 +00001194 case Builtin::BI__builtin_prefetch: {
1195 Value *Locality, *RW, *Address = EmitScalarExpr(E->getArg(0));
1196 // FIXME: Technically these constants should of type 'int', yes?
Mike Stump11289f42009-09-09 15:08:12 +00001197 RW = (E->getNumArgs() > 1) ? EmitScalarExpr(E->getArg(1)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001198 llvm::ConstantInt::get(Int32Ty, 0);
Mike Stump11289f42009-09-09 15:08:12 +00001199 Locality = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) :
Chris Lattner5e016ae2010-06-27 07:15:29 +00001200 llvm::ConstantInt::get(Int32Ty, 3);
Bruno Cardoso Lopes3b0297a2011-06-14 05:00:30 +00001201 Value *Data = llvm::ConstantInt::get(Int32Ty, 1);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001202 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00001203 return RValue::get(Builder.CreateCall(F, {Address, RW, Locality, Data}));
Anders Carlssonef93b9d2007-12-02 21:58:10 +00001204 }
Hal Finkel3fadbb52012-08-05 22:03:08 +00001205 case Builtin::BI__builtin_readcyclecounter: {
1206 Value *F = CGM.getIntrinsic(Intrinsic::readcyclecounter);
David Blaikie4ba525b2015-07-14 17:27:39 +00001207 return RValue::get(Builder.CreateCall(F));
Hal Finkel3fadbb52012-08-05 22:03:08 +00001208 }
Renato Golinc491a8d2014-03-26 15:36:05 +00001209 case Builtin::BI__builtin___clear_cache: {
1210 Value *Begin = EmitScalarExpr(E->getArg(0));
1211 Value *End = EmitScalarExpr(E->getArg(1));
1212 Value *F = CGM.getIntrinsic(Intrinsic::clear_cache);
David Blaikie43f9bb72015-05-18 22:14:03 +00001213 return RValue::get(Builder.CreateCall(F, {Begin, End}));
Renato Golinc491a8d2014-03-26 15:36:05 +00001214 }
Akira Hatanaka85365cd2015-07-02 22:15:41 +00001215 case Builtin::BI__builtin_trap:
1216 return RValue::get(EmitTrapCall(Intrinsic::trap));
1217 case Builtin::BI__debugbreak:
1218 return RValue::get(EmitTrapCall(Intrinsic::debugtrap));
Chris Lattnerbf206382009-09-21 03:09:59 +00001219 case Builtin::BI__builtin_unreachable: {
Alexey Samsonovedf99a92014-11-07 22:29:38 +00001220 if (SanOpts.has(SanitizerKind::Unreachable)) {
Alexey Samsonov24cad992014-07-17 18:46:27 +00001221 SanitizerScope SanScope(this);
Alexey Samsonove396bfc2014-11-11 22:03:54 +00001222 EmitCheck(std::make_pair(static_cast<llvm::Value *>(Builder.getFalse()),
1223 SanitizerKind::Unreachable),
Filipe Cabecinhas322ecd92016-12-12 16:18:40 +00001224 SanitizerHandler::BuiltinUnreachable,
1225 EmitCheckSourceLocation(E->getExprLoc()), None);
Alexey Samsonov24cad992014-07-17 18:46:27 +00001226 } else
John McCall20f6ab82011-01-12 03:41:02 +00001227 Builder.CreateUnreachable();
1228
1229 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001230 EmitBlock(createBasicBlock("unreachable.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001231
Craig Topper8a13c412014-05-21 05:09:00 +00001232 return RValue::get(nullptr);
Chris Lattnerbf206382009-09-21 03:09:59 +00001233 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001234
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001235 case Builtin::BI__builtin_powi:
1236 case Builtin::BI__builtin_powif:
Reid Kleckner1fcccdd2015-02-05 00:24:57 +00001237 case Builtin::BI__builtin_powil: {
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001238 Value *Base = EmitScalarExpr(E->getArg(0));
1239 Value *Exponent = EmitScalarExpr(E->getArg(1));
Chris Lattnera5f58b02011-07-09 17:41:47 +00001240 llvm::Type *ArgType = Base->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001241 Value *F = CGM.getIntrinsic(Intrinsic::powi, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00001242 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbarc2f67962008-07-21 18:44:41 +00001243 }
1244
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001245 case Builtin::BI__builtin_isgreater:
1246 case Builtin::BI__builtin_isgreaterequal:
1247 case Builtin::BI__builtin_isless:
1248 case Builtin::BI__builtin_islessequal:
1249 case Builtin::BI__builtin_islessgreater:
1250 case Builtin::BI__builtin_isunordered: {
1251 // Ordered comparisons: we know the arguments to these are matching scalar
1252 // floating point values.
Mike Stump11289f42009-09-09 15:08:12 +00001253 Value *LHS = EmitScalarExpr(E->getArg(0));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001254 Value *RHS = EmitScalarExpr(E->getArg(1));
Mike Stump11289f42009-09-09 15:08:12 +00001255
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001256 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00001257 default: llvm_unreachable("Unknown ordered comparison");
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001258 case Builtin::BI__builtin_isgreater:
1259 LHS = Builder.CreateFCmpOGT(LHS, RHS, "cmp");
1260 break;
1261 case Builtin::BI__builtin_isgreaterequal:
1262 LHS = Builder.CreateFCmpOGE(LHS, RHS, "cmp");
1263 break;
1264 case Builtin::BI__builtin_isless:
1265 LHS = Builder.CreateFCmpOLT(LHS, RHS, "cmp");
1266 break;
1267 case Builtin::BI__builtin_islessequal:
1268 LHS = Builder.CreateFCmpOLE(LHS, RHS, "cmp");
1269 break;
1270 case Builtin::BI__builtin_islessgreater:
1271 LHS = Builder.CreateFCmpONE(LHS, RHS, "cmp");
1272 break;
Mike Stump11289f42009-09-09 15:08:12 +00001273 case Builtin::BI__builtin_isunordered:
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001274 LHS = Builder.CreateFCmpUNO(LHS, RHS, "cmp");
1275 break;
1276 }
1277 // ZExt bool to int type.
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001278 return RValue::get(Builder.CreateZExt(LHS, ConvertType(E->getType())));
Chris Lattner6c9ffe92007-12-20 00:44:32 +00001279 }
Eli Friedman1c277d02009-09-01 04:19:44 +00001280 case Builtin::BI__builtin_isnan: {
1281 Value *V = EmitScalarExpr(E->getArg(0));
1282 V = Builder.CreateFCmpUNO(V, V, "cmp");
Benjamin Kramer76399eb2011-09-27 21:06:10 +00001283 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
Eli Friedman1c277d02009-09-01 04:19:44 +00001284 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001285
Dehao Chen5d4f0be2016-09-14 17:34:14 +00001286 case Builtin::BIfinite:
1287 case Builtin::BI__finite:
1288 case Builtin::BIfinitef:
1289 case Builtin::BI__finitef:
1290 case Builtin::BIfinitel:
1291 case Builtin::BI__finitel:
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001292 case Builtin::BI__builtin_isinf:
1293 case Builtin::BI__builtin_isfinite: {
1294 // isinf(x) --> fabs(x) == infinity
1295 // isfinite(x) --> fabs(x) != infinity
1296 // x != NaN via the ordered compare in either case.
Chris Lattner43660c52010-05-06 05:35:16 +00001297 Value *V = EmitScalarExpr(E->getArg(0));
Sanjay Patelae7a9df2016-04-07 14:29:05 +00001298 Value *Fabs = EmitFAbs(*this, V);
1299 Constant *Infinity = ConstantFP::getInfinity(V->getType());
1300 CmpInst::Predicate Pred = (BuiltinID == Builtin::BI__builtin_isinf)
1301 ? CmpInst::FCMP_OEQ
1302 : CmpInst::FCMP_ONE;
1303 Value *FCmp = Builder.CreateFCmp(Pred, Fabs, Infinity, "cmpinf");
1304 return RValue::get(Builder.CreateZExt(FCmp, ConvertType(E->getType())));
Chris Lattner43660c52010-05-06 05:35:16 +00001305 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001306
Chandler Carruthc66deaf2015-03-19 22:39:51 +00001307 case Builtin::BI__builtin_isinf_sign: {
1308 // isinf_sign(x) -> fabs(x) == infinity ? (signbit(x) ? -1 : 1) : 0
1309 Value *Arg = EmitScalarExpr(E->getArg(0));
1310 Value *AbsArg = EmitFAbs(*this, Arg);
1311 Value *IsInf = Builder.CreateFCmpOEQ(
1312 AbsArg, ConstantFP::getInfinity(Arg->getType()), "isinf");
1313 Value *IsNeg = EmitSignBit(*this, Arg);
1314
1315 llvm::Type *IntTy = ConvertType(E->getType());
1316 Value *Zero = Constant::getNullValue(IntTy);
1317 Value *One = ConstantInt::get(IntTy, 1);
1318 Value *NegativeOne = ConstantInt::get(IntTy, -1);
1319 Value *SignResult = Builder.CreateSelect(IsNeg, NegativeOne, One);
1320 Value *Result = Builder.CreateSelect(IsInf, SignResult, Zero);
1321 return RValue::get(Result);
1322 }
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001323
1324 case Builtin::BI__builtin_isnormal: {
1325 // isnormal(x) --> x == x && fabsf(x) < infinity && fabsf(x) >= float_min
1326 Value *V = EmitScalarExpr(E->getArg(0));
1327 Value *Eq = Builder.CreateFCmpOEQ(V, V, "iseq");
1328
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001329 Value *Abs = EmitFAbs(*this, V);
Benjamin Kramerfdb61d72010-05-19 11:24:26 +00001330 Value *IsLessThanInf =
1331 Builder.CreateFCmpULT(Abs, ConstantFP::getInfinity(V->getType()),"isinf");
1332 APFloat Smallest = APFloat::getSmallestNormalized(
1333 getContext().getFloatTypeSemantics(E->getArg(0)->getType()));
1334 Value *IsNormal =
1335 Builder.CreateFCmpUGE(Abs, ConstantFP::get(V->getContext(), Smallest),
1336 "isnormal");
1337 V = Builder.CreateAnd(Eq, IsLessThanInf, "and");
1338 V = Builder.CreateAnd(V, IsNormal, "and");
1339 return RValue::get(Builder.CreateZExt(V, ConvertType(E->getType())));
1340 }
1341
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001342 case Builtin::BI__builtin_fpclassify: {
1343 Value *V = EmitScalarExpr(E->getArg(5));
Chris Lattner2192fe52011-07-18 04:24:23 +00001344 llvm::Type *Ty = ConvertType(E->getArg(5)->getType());
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001345
1346 // Create Result
1347 BasicBlock *Begin = Builder.GetInsertBlock();
1348 BasicBlock *End = createBasicBlock("fpclassify_end", this->CurFn);
1349 Builder.SetInsertPoint(End);
1350 PHINode *Result =
Jay Foad20c0f022011-03-30 11:28:58 +00001351 Builder.CreatePHI(ConvertType(E->getArg(0)->getType()), 4,
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001352 "fpclassify_result");
1353
1354 // if (V==0) return FP_ZERO
1355 Builder.SetInsertPoint(Begin);
1356 Value *IsZero = Builder.CreateFCmpOEQ(V, Constant::getNullValue(Ty),
1357 "iszero");
1358 Value *ZeroLiteral = EmitScalarExpr(E->getArg(4));
1359 BasicBlock *NotZero = createBasicBlock("fpclassify_not_zero", this->CurFn);
1360 Builder.CreateCondBr(IsZero, End, NotZero);
1361 Result->addIncoming(ZeroLiteral, Begin);
1362
1363 // if (V != V) return FP_NAN
1364 Builder.SetInsertPoint(NotZero);
1365 Value *IsNan = Builder.CreateFCmpUNO(V, V, "cmp");
1366 Value *NanLiteral = EmitScalarExpr(E->getArg(0));
1367 BasicBlock *NotNan = createBasicBlock("fpclassify_not_nan", this->CurFn);
1368 Builder.CreateCondBr(IsNan, End, NotNan);
1369 Result->addIncoming(NanLiteral, NotZero);
1370
1371 // if (fabs(V) == infinity) return FP_INFINITY
1372 Builder.SetInsertPoint(NotNan);
Reid Kleckner4cad00a2014-11-03 23:51:40 +00001373 Value *VAbs = EmitFAbs(*this, V);
Benjamin Kramer7039fcb2010-06-14 10:30:41 +00001374 Value *IsInf =
1375 Builder.CreateFCmpOEQ(VAbs, ConstantFP::getInfinity(V->getType()),
1376 "isinf");
1377 Value *InfLiteral = EmitScalarExpr(E->getArg(1));
1378 BasicBlock *NotInf = createBasicBlock("fpclassify_not_inf", this->CurFn);
1379 Builder.CreateCondBr(IsInf, End, NotInf);
1380 Result->addIncoming(InfLiteral, NotNan);
1381
1382 // if (fabs(V) >= MIN_NORMAL) return FP_NORMAL else FP_SUBNORMAL
1383 Builder.SetInsertPoint(NotInf);
1384 APFloat Smallest = APFloat::getSmallestNormalized(
1385 getContext().getFloatTypeSemantics(E->getArg(5)->getType()));
1386 Value *IsNormal =
1387 Builder.CreateFCmpUGE(VAbs, ConstantFP::get(V->getContext(), Smallest),
1388 "isnormal");
1389 Value *NormalResult =
1390 Builder.CreateSelect(IsNormal, EmitScalarExpr(E->getArg(2)),
1391 EmitScalarExpr(E->getArg(3)));
1392 Builder.CreateBr(End);
1393 Result->addIncoming(NormalResult, NotInf);
1394
1395 // return Result
1396 Builder.SetInsertPoint(End);
1397 return RValue::get(Result);
1398 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001399
Eli Friedmanf6bd1502009-06-02 07:10:30 +00001400 case Builtin::BIalloca:
Reid Kleckner59e4a6f2013-11-13 22:58:53 +00001401 case Builtin::BI_alloca:
Chris Lattner22b9ff42008-06-16 17:15:14 +00001402 case Builtin::BI__builtin_alloca: {
Chris Lattner22b9ff42008-06-16 17:15:14 +00001403 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemer1878da42016-10-27 17:18:24 +00001404 const TargetInfo &TI = getContext().getTargetInfo();
1405 // The alignment of the alloca should correspond to __BIGGEST_ALIGNMENT__.
1406 unsigned SuitableAlignmentInBytes =
David Majnemerbb103d92016-10-31 16:48:30 +00001407 CGM.getContext()
1408 .toCharUnitsFromBits(TI.getSuitableAlign())
1409 .getQuantity();
David Majnemer1878da42016-10-27 17:18:24 +00001410 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1411 AI->setAlignment(SuitableAlignmentInBytes);
1412 return RValue::get(AI);
Daniel Dunbar327acd72008-07-22 00:26:45 +00001413 }
David Majnemer51169932016-10-31 05:37:48 +00001414
1415 case Builtin::BI__builtin_alloca_with_align: {
1416 Value *Size = EmitScalarExpr(E->getArg(0));
David Majnemerbb103d92016-10-31 16:48:30 +00001417 Value *AlignmentInBitsValue = EmitScalarExpr(E->getArg(1));
1418 auto *AlignmentInBitsCI = cast<ConstantInt>(AlignmentInBitsValue);
1419 unsigned AlignmentInBits = AlignmentInBitsCI->getZExtValue();
1420 unsigned AlignmentInBytes =
1421 CGM.getContext().toCharUnitsFromBits(AlignmentInBits).getQuantity();
David Majnemer51169932016-10-31 05:37:48 +00001422 AllocaInst *AI = Builder.CreateAlloca(Builder.getInt8Ty(), Size);
1423 AI->setAlignment(AlignmentInBytes);
1424 return RValue::get(AI);
1425 }
1426
Eli Friedmand6ef69a2010-01-23 19:00:10 +00001427 case Builtin::BIbzero:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001428 case Builtin::BI__builtin_bzero: {
John McCall7f416cc2015-09-08 08:05:57 +00001429 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001430 Value *SizeVal = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00001431 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001432 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001433 Builder.CreateMemSet(Dest, Builder.getInt8(0), SizeVal, false);
1434 return RValue::get(Dest.getPointer());
Chris Lattner22b9ff42008-06-16 17:15:14 +00001435 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001436 case Builtin::BImemcpy:
Eli Friedmana3a40682008-05-19 23:27:48 +00001437 case Builtin::BI__builtin_memcpy: {
John McCall7f416cc2015-09-08 08:05:57 +00001438 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1439 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001440 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001441 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001442 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001443 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001444 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001445 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1446 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001447 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001448
Richard Smith5e29dd32017-01-20 00:45:35 +00001449 case Builtin::BI__builtin_char_memchr:
1450 BuiltinID = Builtin::BI__builtin_memchr;
1451 break;
1452
Chris Lattner30107ed2011-04-17 00:40:24 +00001453 case Builtin::BI__builtin___memcpy_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001454 // fold __builtin_memcpy_chk(x, y, cst1, cst2) to memcpy iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001455 llvm::APSInt Size, DstSize;
1456 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1457 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001458 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001459 if (Size.ugt(DstSize))
1460 break;
John McCall7f416cc2015-09-08 08:05:57 +00001461 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1462 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001463 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001464 Builder.CreateMemCpy(Dest, Src, SizeVal, false);
1465 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001466 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00001467
Fariborz Jahanian4a303072010-06-16 16:22:04 +00001468 case Builtin::BI__builtin_objc_memmove_collectable: {
John McCall7f416cc2015-09-08 08:05:57 +00001469 Address DestAddr = EmitPointerWithAlignment(E->getArg(0));
1470 Address SrcAddr = EmitPointerWithAlignment(E->getArg(1));
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001471 Value *SizeVal = EmitScalarExpr(E->getArg(2));
Jim Grosbachd3608f42012-09-21 00:18:27 +00001472 CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this,
John McCall7f416cc2015-09-08 08:05:57 +00001473 DestAddr, SrcAddr, SizeVal);
1474 return RValue::get(DestAddr.getPointer());
Fariborz Jahanian021510e2010-06-15 22:44:06 +00001475 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001476
1477 case Builtin::BI__builtin___memmove_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001478 // fold __builtin_memmove_chk(x, y, cst1, cst2) to memmove iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001479 llvm::APSInt Size, DstSize;
1480 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1481 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001482 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001483 if (Size.ugt(DstSize))
1484 break;
John McCall7f416cc2015-09-08 08:05:57 +00001485 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1486 Address Src = EmitPointerWithAlignment(E->getArg(1));
Chris Lattner30107ed2011-04-17 00:40:24 +00001487 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001488 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1489 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001490 }
1491
Eli Friedman7f4933f2009-12-17 00:14:28 +00001492 case Builtin::BImemmove:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001493 case Builtin::BI__builtin_memmove: {
John McCall7f416cc2015-09-08 08:05:57 +00001494 Address Dest = EmitPointerWithAlignment(E->getArg(0));
1495 Address Src = EmitPointerWithAlignment(E->getArg(1));
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001496 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001497 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001498 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001499 EmitNonNullArgCheck(RValue::get(Src.getPointer()), E->getArg(1)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001500 E->getArg(1)->getExprLoc(), FD, 1);
John McCall7f416cc2015-09-08 08:05:57 +00001501 Builder.CreateMemMove(Dest, Src, SizeVal, false);
1502 return RValue::get(Dest.getPointer());
Daniel Dunbar327acd72008-07-22 00:26:45 +00001503 }
Eli Friedman7f4933f2009-12-17 00:14:28 +00001504 case Builtin::BImemset:
Daniel Dunbar327acd72008-07-22 00:26:45 +00001505 case Builtin::BI__builtin_memset: {
John McCall7f416cc2015-09-08 08:05:57 +00001506 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Benjamin Krameracc6b4e2010-12-30 00:13:21 +00001507 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1508 Builder.getInt8Ty());
Mon P Wangcc2ab0c2010-04-04 03:10:52 +00001509 Value *SizeVal = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00001510 EmitNonNullArgCheck(RValue::get(Dest.getPointer()), E->getArg(0)->getType(),
Nuno Lopes1ba2d782015-05-30 16:11:40 +00001511 E->getArg(0)->getExprLoc(), FD, 0);
John McCall7f416cc2015-09-08 08:05:57 +00001512 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1513 return RValue::get(Dest.getPointer());
Eli Friedmana3a40682008-05-19 23:27:48 +00001514 }
Chris Lattner30107ed2011-04-17 00:40:24 +00001515 case Builtin::BI__builtin___memset_chk: {
Sylvestre Ledru33b5baf2012-09-27 10:16:10 +00001516 // fold __builtin_memset_chk(x, y, cst1, cst2) to memset iff cst1<=cst2.
Richard Smithcaf33902011-10-10 18:28:20 +00001517 llvm::APSInt Size, DstSize;
1518 if (!E->getArg(2)->EvaluateAsInt(Size, CGM.getContext()) ||
1519 !E->getArg(3)->EvaluateAsInt(DstSize, CGM.getContext()))
Chris Lattner30107ed2011-04-17 00:40:24 +00001520 break;
Chris Lattner30107ed2011-04-17 00:40:24 +00001521 if (Size.ugt(DstSize))
1522 break;
John McCall7f416cc2015-09-08 08:05:57 +00001523 Address Dest = EmitPointerWithAlignment(E->getArg(0));
Chris Lattner30107ed2011-04-17 00:40:24 +00001524 Value *ByteVal = Builder.CreateTrunc(EmitScalarExpr(E->getArg(1)),
1525 Builder.getInt8Ty());
1526 Value *SizeVal = llvm::ConstantInt::get(Builder.getContext(), Size);
John McCall7f416cc2015-09-08 08:05:57 +00001527 Builder.CreateMemSet(Dest, ByteVal, SizeVal, false);
1528 return RValue::get(Dest.getPointer());
Chris Lattner30107ed2011-04-17 00:40:24 +00001529 }
John McCall515c3c52010-03-03 10:30:05 +00001530 case Builtin::BI__builtin_dwarf_cfa: {
1531 // The offset in bytes from the first argument to the CFA.
1532 //
1533 // Why on earth is this in the frontend? Is there any reason at
1534 // all that the backend can't reasonably determine this while
1535 // lowering llvm.eh.dwarf.cfa()?
1536 //
1537 // TODO: If there's a satisfactory reason, add a target hook for
1538 // this instead of hard-coding 0, which is correct for most targets.
1539 int32_t Offset = 0;
1540
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001541 Value *F = CGM.getIntrinsic(Intrinsic::eh_dwarf_cfa);
Jim Grosbachd3608f42012-09-21 00:18:27 +00001542 return RValue::get(Builder.CreateCall(F,
Chris Lattner5e016ae2010-06-27 07:15:29 +00001543 llvm::ConstantInt::get(Int32Ty, Offset)));
John McCall515c3c52010-03-03 10:30:05 +00001544 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001545 case Builtin::BI__builtin_return_address: {
John McCallde0fe072017-08-15 21:42:52 +00001546 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1547 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001548 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001549 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001550 }
Albert Gutowski397d81b2016-10-13 16:03:42 +00001551 case Builtin::BI_ReturnAddress: {
1552 Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
1553 return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
1554 }
Eli Friedman53e38bd2008-05-20 08:59:34 +00001555 case Builtin::BI__builtin_frame_address: {
John McCallde0fe072017-08-15 21:42:52 +00001556 Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
1557 getContext().UnsignedIntTy);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001558 Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
Anton Korobeynikov73d50b92009-12-27 14:27:22 +00001559 return RValue::get(Builder.CreateCall(F, Depth));
Eli Friedman53e38bd2008-05-20 08:59:34 +00001560 }
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001561 case Builtin::BI__builtin_extract_return_addr: {
John McCalld4f4b7f2010-03-03 04:15:11 +00001562 Value *Address = EmitScalarExpr(E->getArg(0));
1563 Value *Result = getTargetHooks().decodeReturnAddress(*this, Address);
1564 return RValue::get(Result);
1565 }
1566 case Builtin::BI__builtin_frob_return_addr: {
1567 Value *Address = EmitScalarExpr(E->getArg(0));
1568 Value *Result = getTargetHooks().encodeReturnAddress(*this, Address);
1569 return RValue::get(Result);
Eli Friedman5b73b5e2009-05-03 19:23:23 +00001570 }
John McCallbeec5a02010-03-06 00:35:14 +00001571 case Builtin::BI__builtin_dwarf_sp_column: {
Chris Lattner2192fe52011-07-18 04:24:23 +00001572 llvm::IntegerType *Ty
John McCallbeec5a02010-03-06 00:35:14 +00001573 = cast<llvm::IntegerType>(ConvertType(E->getType()));
1574 int Column = getTargetHooks().getDwarfEHStackPointer(CGM);
1575 if (Column == -1) {
1576 CGM.ErrorUnsupported(E, "__builtin_dwarf_sp_column");
1577 return RValue::get(llvm::UndefValue::get(Ty));
1578 }
1579 return RValue::get(llvm::ConstantInt::get(Ty, Column, true));
1580 }
1581 case Builtin::BI__builtin_init_dwarf_reg_size_table: {
1582 Value *Address = EmitScalarExpr(E->getArg(0));
1583 if (getTargetHooks().initDwarfEHRegSizeTable(*this, Address))
1584 CGM.ErrorUnsupported(E, "__builtin_init_dwarf_reg_size_table");
1585 return RValue::get(llvm::UndefValue::get(ConvertType(E->getType())));
1586 }
John McCall66769f82010-03-03 05:38:58 +00001587 case Builtin::BI__builtin_eh_return: {
1588 Value *Int = EmitScalarExpr(E->getArg(0));
1589 Value *Ptr = EmitScalarExpr(E->getArg(1));
1590
Chris Lattner2192fe52011-07-18 04:24:23 +00001591 llvm::IntegerType *IntTy = cast<llvm::IntegerType>(Int->getType());
John McCall66769f82010-03-03 05:38:58 +00001592 assert((IntTy->getBitWidth() == 32 || IntTy->getBitWidth() == 64) &&
1593 "LLVM's __builtin_eh_return only supports 32- and 64-bit variants");
1594 Value *F = CGM.getIntrinsic(IntTy->getBitWidth() == 32
1595 ? Intrinsic::eh_return_i32
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001596 : Intrinsic::eh_return_i64);
David Blaikie43f9bb72015-05-18 22:14:03 +00001597 Builder.CreateCall(F, {Int, Ptr});
John McCall20f6ab82011-01-12 03:41:02 +00001598 Builder.CreateUnreachable();
1599
1600 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001601 EmitBlock(createBasicBlock("builtin_eh_return.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001602
Craig Topper8a13c412014-05-21 05:09:00 +00001603 return RValue::get(nullptr);
John McCall66769f82010-03-03 05:38:58 +00001604 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001605 case Builtin::BI__builtin_unwind_init: {
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00001606 Value *F = CGM.getIntrinsic(Intrinsic::eh_unwind_init);
David Blaikie4ba525b2015-07-14 17:27:39 +00001607 return RValue::get(Builder.CreateCall(F));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001608 }
John McCall4b613fa2010-03-02 02:31:24 +00001609 case Builtin::BI__builtin_extend_pointer: {
1610 // Extends a pointer to the size of an _Unwind_Word, which is
John McCallb6cc2c042010-03-02 03:50:12 +00001611 // uint64_t on all platforms. Generally this gets poked into a
1612 // register and eventually used as an address, so if the
1613 // addressing registers are wider than pointers and the platform
1614 // doesn't implicitly ignore high-order bits when doing
1615 // addressing, we need to make sure we zext / sext based on
1616 // the platform's expectations.
John McCall4b613fa2010-03-02 02:31:24 +00001617 //
1618 // See: http://gcc.gnu.org/ml/gcc-bugs/2002-02/msg00237.html
John McCallb6cc2c042010-03-02 03:50:12 +00001619
John McCallb6cc2c042010-03-02 03:50:12 +00001620 // Cast the pointer to intptr_t.
John McCall4b613fa2010-03-02 02:31:24 +00001621 Value *Ptr = EmitScalarExpr(E->getArg(0));
John McCallb6cc2c042010-03-02 03:50:12 +00001622 Value *Result = Builder.CreatePtrToInt(Ptr, IntPtrTy, "extend.cast");
1623
1624 // If that's 64 bits, we're done.
1625 if (IntPtrTy->getBitWidth() == 64)
1626 return RValue::get(Result);
1627
1628 // Otherwise, ask the codegen data what to do.
John McCalld4f4b7f2010-03-03 04:15:11 +00001629 if (getTargetHooks().extendPointerWithSExt())
John McCallb6cc2c042010-03-02 03:50:12 +00001630 return RValue::get(Builder.CreateSExt(Result, Int64Ty, "extend.sext"));
1631 else
1632 return RValue::get(Builder.CreateZExt(Result, Int64Ty, "extend.zext"));
John McCall4b613fa2010-03-02 02:31:24 +00001633 }
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001634 case Builtin::BI__builtin_setjmp: {
John McCall02269a62010-05-27 18:47:06 +00001635 // Buffer is a void**.
John McCall7f416cc2015-09-08 08:05:57 +00001636 Address Buf = EmitPointerWithAlignment(E->getArg(0));
John McCall02269a62010-05-27 18:47:06 +00001637
1638 // Store the frame pointer to the setjmp buffer.
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001639 Value *FrameAddr =
John McCall02269a62010-05-27 18:47:06 +00001640 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
Chris Lattner5e016ae2010-06-27 07:15:29 +00001641 ConstantInt::get(Int32Ty, 0));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001642 Builder.CreateStore(FrameAddr, Buf);
John McCall02269a62010-05-27 18:47:06 +00001643
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001644 // Store the stack pointer to the setjmp buffer.
1645 Value *StackAddr =
David Blaikie4ba525b2015-07-14 17:27:39 +00001646 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::stacksave));
John McCall7f416cc2015-09-08 08:05:57 +00001647 Address StackSaveSlot =
1648 Builder.CreateConstInBoundsGEP(Buf, 2, getPointerSize());
Jim Grosbach4cf59b92010-05-27 23:54:20 +00001649 Builder.CreateStore(StackAddr, StackSaveSlot);
1650
John McCall02269a62010-05-27 18:47:06 +00001651 // Call LLVM's EH setjmp, which is lightweight.
1652 Value *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp);
John McCallad7c5c12011-02-08 08:22:06 +00001653 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00001654 return RValue::get(Builder.CreateCall(F, Buf.getPointer()));
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001655 }
1656 case Builtin::BI__builtin_longjmp: {
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001657 Value *Buf = EmitScalarExpr(E->getArg(0));
John McCallad7c5c12011-02-08 08:22:06 +00001658 Buf = Builder.CreateBitCast(Buf, Int8PtrTy);
John McCall02269a62010-05-27 18:47:06 +00001659
1660 // Call LLVM's EH longjmp, which is lightweight.
1661 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::eh_sjlj_longjmp), Buf);
1662
John McCall20f6ab82011-01-12 03:41:02 +00001663 // longjmp doesn't return; mark this as unreachable.
1664 Builder.CreateUnreachable();
1665
1666 // We do need to preserve an insertion point.
John McCallad7c5c12011-02-08 08:22:06 +00001667 EmitBlock(createBasicBlock("longjmp.cont"));
John McCall20f6ab82011-01-12 03:41:02 +00001668
Craig Topper8a13c412014-05-21 05:09:00 +00001669 return RValue::get(nullptr);
Eli Friedmancb9d07c2009-06-02 09:37:50 +00001670 }
Mon P Wangb84407d2008-05-09 22:40:52 +00001671 case Builtin::BI__sync_fetch_and_add:
Mon P Wangb84407d2008-05-09 22:40:52 +00001672 case Builtin::BI__sync_fetch_and_sub:
Chris Lattnerdc046542009-05-08 06:58:22 +00001673 case Builtin::BI__sync_fetch_and_or:
1674 case Builtin::BI__sync_fetch_and_and:
1675 case Builtin::BI__sync_fetch_and_xor:
Hal Finkeld2208b52014-10-02 20:53:50 +00001676 case Builtin::BI__sync_fetch_and_nand:
Chris Lattnerdc046542009-05-08 06:58:22 +00001677 case Builtin::BI__sync_add_and_fetch:
1678 case Builtin::BI__sync_sub_and_fetch:
1679 case Builtin::BI__sync_and_and_fetch:
1680 case Builtin::BI__sync_or_and_fetch:
1681 case Builtin::BI__sync_xor_and_fetch:
Hal Finkeld2208b52014-10-02 20:53:50 +00001682 case Builtin::BI__sync_nand_and_fetch:
Chris Lattnerdc046542009-05-08 06:58:22 +00001683 case Builtin::BI__sync_val_compare_and_swap:
1684 case Builtin::BI__sync_bool_compare_and_swap:
1685 case Builtin::BI__sync_lock_test_and_set:
1686 case Builtin::BI__sync_lock_release:
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001687 case Builtin::BI__sync_swap:
David Blaikie83d382b2011-09-23 05:06:16 +00001688 llvm_unreachable("Shouldn't make it through sema");
Chris Lattnerdc046542009-05-08 06:58:22 +00001689 case Builtin::BI__sync_fetch_and_add_1:
1690 case Builtin::BI__sync_fetch_and_add_2:
1691 case Builtin::BI__sync_fetch_and_add_4:
1692 case Builtin::BI__sync_fetch_and_add_8:
1693 case Builtin::BI__sync_fetch_and_add_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001694 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Add, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001695 case Builtin::BI__sync_fetch_and_sub_1:
1696 case Builtin::BI__sync_fetch_and_sub_2:
1697 case Builtin::BI__sync_fetch_and_sub_4:
1698 case Builtin::BI__sync_fetch_and_sub_8:
1699 case Builtin::BI__sync_fetch_and_sub_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001700 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Sub, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001701 case Builtin::BI__sync_fetch_and_or_1:
1702 case Builtin::BI__sync_fetch_and_or_2:
1703 case Builtin::BI__sync_fetch_and_or_4:
1704 case Builtin::BI__sync_fetch_and_or_8:
1705 case Builtin::BI__sync_fetch_and_or_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001706 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Or, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001707 case Builtin::BI__sync_fetch_and_and_1:
1708 case Builtin::BI__sync_fetch_and_and_2:
1709 case Builtin::BI__sync_fetch_and_and_4:
1710 case Builtin::BI__sync_fetch_and_and_8:
1711 case Builtin::BI__sync_fetch_and_and_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001712 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::And, E);
Chris Lattnerdc046542009-05-08 06:58:22 +00001713 case Builtin::BI__sync_fetch_and_xor_1:
1714 case Builtin::BI__sync_fetch_and_xor_2:
1715 case Builtin::BI__sync_fetch_and_xor_4:
1716 case Builtin::BI__sync_fetch_and_xor_8:
1717 case Builtin::BI__sync_fetch_and_xor_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001718 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xor, E);
Hal Finkeld2208b52014-10-02 20:53:50 +00001719 case Builtin::BI__sync_fetch_and_nand_1:
1720 case Builtin::BI__sync_fetch_and_nand_2:
1721 case Builtin::BI__sync_fetch_and_nand_4:
1722 case Builtin::BI__sync_fetch_and_nand_8:
1723 case Builtin::BI__sync_fetch_and_nand_16:
1724 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Nand, E);
Mike Stump11289f42009-09-09 15:08:12 +00001725
Chris Lattnerdc046542009-05-08 06:58:22 +00001726 // Clang extensions: not overloaded yet.
Mon P Wangb84407d2008-05-09 22:40:52 +00001727 case Builtin::BI__sync_fetch_and_min:
Eli Friedmane9f81132011-09-07 01:41:24 +00001728 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Min, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001729 case Builtin::BI__sync_fetch_and_max:
Eli Friedmane9f81132011-09-07 01:41:24 +00001730 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Max, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001731 case Builtin::BI__sync_fetch_and_umin:
Eli Friedmane9f81132011-09-07 01:41:24 +00001732 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMin, E);
Mon P Wangb84407d2008-05-09 22:40:52 +00001733 case Builtin::BI__sync_fetch_and_umax:
Eli Friedmane9f81132011-09-07 01:41:24 +00001734 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::UMax, E);
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001735
Chris Lattnerdc046542009-05-08 06:58:22 +00001736 case Builtin::BI__sync_add_and_fetch_1:
1737 case Builtin::BI__sync_add_and_fetch_2:
1738 case Builtin::BI__sync_add_and_fetch_4:
1739 case Builtin::BI__sync_add_and_fetch_8:
1740 case Builtin::BI__sync_add_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001741 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Add, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001742 llvm::Instruction::Add);
Chris Lattnerdc046542009-05-08 06:58:22 +00001743 case Builtin::BI__sync_sub_and_fetch_1:
1744 case Builtin::BI__sync_sub_and_fetch_2:
1745 case Builtin::BI__sync_sub_and_fetch_4:
1746 case Builtin::BI__sync_sub_and_fetch_8:
1747 case Builtin::BI__sync_sub_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001748 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Sub, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001749 llvm::Instruction::Sub);
Chris Lattnerdc046542009-05-08 06:58:22 +00001750 case Builtin::BI__sync_and_and_fetch_1:
1751 case Builtin::BI__sync_and_and_fetch_2:
1752 case Builtin::BI__sync_and_and_fetch_4:
1753 case Builtin::BI__sync_and_and_fetch_8:
1754 case Builtin::BI__sync_and_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001755 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::And, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001756 llvm::Instruction::And);
Chris Lattnerdc046542009-05-08 06:58:22 +00001757 case Builtin::BI__sync_or_and_fetch_1:
1758 case Builtin::BI__sync_or_and_fetch_2:
1759 case Builtin::BI__sync_or_and_fetch_4:
1760 case Builtin::BI__sync_or_and_fetch_8:
1761 case Builtin::BI__sync_or_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001762 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Or, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001763 llvm::Instruction::Or);
Chris Lattnerdc046542009-05-08 06:58:22 +00001764 case Builtin::BI__sync_xor_and_fetch_1:
1765 case Builtin::BI__sync_xor_and_fetch_2:
1766 case Builtin::BI__sync_xor_and_fetch_4:
1767 case Builtin::BI__sync_xor_and_fetch_8:
1768 case Builtin::BI__sync_xor_and_fetch_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001769 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Xor, E,
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001770 llvm::Instruction::Xor);
Hal Finkeld2208b52014-10-02 20:53:50 +00001771 case Builtin::BI__sync_nand_and_fetch_1:
1772 case Builtin::BI__sync_nand_and_fetch_2:
1773 case Builtin::BI__sync_nand_and_fetch_4:
1774 case Builtin::BI__sync_nand_and_fetch_8:
1775 case Builtin::BI__sync_nand_and_fetch_16:
1776 return EmitBinaryAtomicPost(*this, llvm::AtomicRMWInst::Nand, E,
1777 llvm::Instruction::And, true);
Mike Stump11289f42009-09-09 15:08:12 +00001778
Chris Lattnerdc046542009-05-08 06:58:22 +00001779 case Builtin::BI__sync_val_compare_and_swap_1:
1780 case Builtin::BI__sync_val_compare_and_swap_2:
1781 case Builtin::BI__sync_val_compare_and_swap_4:
1782 case Builtin::BI__sync_val_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001783 case Builtin::BI__sync_val_compare_and_swap_16:
1784 return RValue::get(MakeAtomicCmpXchgValue(*this, E, false));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001785
Chris Lattnerdc046542009-05-08 06:58:22 +00001786 case Builtin::BI__sync_bool_compare_and_swap_1:
1787 case Builtin::BI__sync_bool_compare_and_swap_2:
1788 case Builtin::BI__sync_bool_compare_and_swap_4:
1789 case Builtin::BI__sync_bool_compare_and_swap_8:
Artem Belevichd21e5c62015-06-25 18:29:42 +00001790 case Builtin::BI__sync_bool_compare_and_swap_16:
1791 return RValue::get(MakeAtomicCmpXchgValue(*this, E, true));
Daniel Dunbar4fab57d2009-04-07 00:55:51 +00001792
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001793 case Builtin::BI__sync_swap_1:
1794 case Builtin::BI__sync_swap_2:
1795 case Builtin::BI__sync_swap_4:
1796 case Builtin::BI__sync_swap_8:
1797 case Builtin::BI__sync_swap_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001798 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Chris Lattner9cb59fa2011-04-09 03:57:26 +00001799
Chris Lattnerdc046542009-05-08 06:58:22 +00001800 case Builtin::BI__sync_lock_test_and_set_1:
1801 case Builtin::BI__sync_lock_test_and_set_2:
1802 case Builtin::BI__sync_lock_test_and_set_4:
1803 case Builtin::BI__sync_lock_test_and_set_8:
1804 case Builtin::BI__sync_lock_test_and_set_16:
Eli Friedmane9f81132011-09-07 01:41:24 +00001805 return EmitBinaryAtomic(*this, llvm::AtomicRMWInst::Xchg, E);
Daniel Dunbar4ff562d2010-03-20 07:04:11 +00001806
Chris Lattnerdc046542009-05-08 06:58:22 +00001807 case Builtin::BI__sync_lock_release_1:
1808 case Builtin::BI__sync_lock_release_2:
1809 case Builtin::BI__sync_lock_release_4:
1810 case Builtin::BI__sync_lock_release_8:
Chris Lattnerafde2592009-05-13 04:46:13 +00001811 case Builtin::BI__sync_lock_release_16: {
1812 Value *Ptr = EmitScalarExpr(E->getArg(0));
Eli Friedman84d28122011-09-13 22:21:56 +00001813 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
1814 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
Eli Friedmanfefe0d02012-03-16 01:48:04 +00001815 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
1816 StoreSize.getQuantity() * 8);
1817 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
Jim Grosbachd3608f42012-09-21 00:18:27 +00001818 llvm::StoreInst *Store =
John McCall7f416cc2015-09-08 08:05:57 +00001819 Builder.CreateAlignedStore(llvm::Constant::getNullValue(ITy), Ptr,
1820 StoreSize);
JF Bastien92f4ef12016-04-06 17:26:42 +00001821 Store->setAtomic(llvm::AtomicOrdering::Release);
Craig Topper8a13c412014-05-21 05:09:00 +00001822 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001823 }
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00001824
Chris Lattnerafde2592009-05-13 04:46:13 +00001825 case Builtin::BI__sync_synchronize: {
Eli Friedmane9f81132011-09-07 01:41:24 +00001826 // We assume this is supposed to correspond to a C++0x-style
1827 // sequentially-consistent fence (i.e. this is only usable for
1828 // synchonization, not device I/O or anything like that). This intrinsic
Jim Grosbachd3608f42012-09-21 00:18:27 +00001829 // is really badly designed in the sense that in theory, there isn't
Eli Friedmane9f81132011-09-07 01:41:24 +00001830 // any way to safely use it... but in practice, it mostly works
1831 // to use it with non-atomic loads and stores to get acquire/release
1832 // semantics.
JF Bastien92f4ef12016-04-06 17:26:42 +00001833 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent);
Craig Topper8a13c412014-05-21 05:09:00 +00001834 return RValue::get(nullptr);
Chris Lattnerafde2592009-05-13 04:46:13 +00001835 }
Mike Stump11289f42009-09-09 15:08:12 +00001836
Michael Zolotukhin84df1232015-09-08 23:52:33 +00001837 case Builtin::BI__builtin_nontemporal_load:
1838 return RValue::get(EmitNontemporalLoad(*this, E));
1839 case Builtin::BI__builtin_nontemporal_store:
1840 return RValue::get(EmitNontemporalStore(*this, E));
Richard Smith01ba47d2012-04-13 00:45:38 +00001841 case Builtin::BI__c11_atomic_is_lock_free:
1842 case Builtin::BI__atomic_is_lock_free: {
1843 // Call "bool __atomic_is_lock_free(size_t size, void *ptr)". For the
1844 // __c11 builtin, ptr is 0 (indicating a properly-aligned object), since
1845 // _Atomic(T) is always properly-aligned.
1846 const char *LibCallName = "__atomic_is_lock_free";
1847 CallArgList Args;
1848 Args.add(RValue::get(EmitScalarExpr(E->getArg(0))),
1849 getContext().getSizeType());
1850 if (BuiltinID == Builtin::BI__atomic_is_lock_free)
1851 Args.add(RValue::get(EmitScalarExpr(E->getArg(1))),
1852 getContext().VoidPtrTy);
1853 else
1854 Args.add(RValue::get(llvm::Constant::getNullValue(VoidPtrTy)),
1855 getContext().VoidPtrTy);
1856 const CGFunctionInfo &FuncInfo =
John McCallc56a8b32016-03-11 04:30:31 +00001857 CGM.getTypes().arrangeBuiltinFunctionCall(E->getType(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001858 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
1859 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
John McCallb92ab1a2016-10-26 23:46:34 +00001860 return EmitCall(FuncInfo, CGCallee::forDirect(Func),
1861 ReturnValueSlot(), Args);
Richard Smith01ba47d2012-04-13 00:45:38 +00001862 }
1863
1864 case Builtin::BI__atomic_test_and_set: {
1865 // Look at the argument type to determine whether this is a volatile
1866 // operation. The parameter type is always volatile.
1867 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1868 bool Volatile =
1869 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1870
1871 Value *Ptr = EmitScalarExpr(E->getArg(0));
Micah Villmowea2fea22012-10-25 15:39:14 +00001872 unsigned AddrSpace = Ptr->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001873 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1874 Value *NewVal = Builder.getInt8(1);
1875 Value *Order = EmitScalarExpr(E->getArg(1));
1876 if (isa<llvm::ConstantInt>(Order)) {
1877 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
Craig Topper8a13c412014-05-21 05:09:00 +00001878 AtomicRMWInst *Result = nullptr;
Richard Smith01ba47d2012-04-13 00:45:38 +00001879 switch (ord) {
1880 case 0: // memory_order_relaxed
1881 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001882 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1883 llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001884 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001885 case 1: // memory_order_consume
1886 case 2: // memory_order_acquire
1887 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1888 llvm::AtomicOrdering::Acquire);
Richard Smith01ba47d2012-04-13 00:45:38 +00001889 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001890 case 3: // memory_order_release
1891 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1892 llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001893 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001894 case 4: // memory_order_acq_rel
1895
1896 Result = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1897 llvm::AtomicOrdering::AcquireRelease);
Richard Smith01ba47d2012-04-13 00:45:38 +00001898 break;
JF Bastien92f4ef12016-04-06 17:26:42 +00001899 case 5: // memory_order_seq_cst
1900 Result = Builder.CreateAtomicRMW(
1901 llvm::AtomicRMWInst::Xchg, Ptr, NewVal,
1902 llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001903 break;
1904 }
1905 Result->setVolatile(Volatile);
1906 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1907 }
1908
1909 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1910
1911 llvm::BasicBlock *BBs[5] = {
1912 createBasicBlock("monotonic", CurFn),
1913 createBasicBlock("acquire", CurFn),
1914 createBasicBlock("release", CurFn),
1915 createBasicBlock("acqrel", CurFn),
1916 createBasicBlock("seqcst", CurFn)
1917 };
1918 llvm::AtomicOrdering Orders[5] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001919 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Acquire,
1920 llvm::AtomicOrdering::Release, llvm::AtomicOrdering::AcquireRelease,
1921 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001922
1923 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1924 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1925
1926 Builder.SetInsertPoint(ContBB);
1927 PHINode *Result = Builder.CreatePHI(Int8Ty, 5, "was_set");
1928
1929 for (unsigned i = 0; i < 5; ++i) {
1930 Builder.SetInsertPoint(BBs[i]);
1931 AtomicRMWInst *RMW = Builder.CreateAtomicRMW(llvm::AtomicRMWInst::Xchg,
1932 Ptr, NewVal, Orders[i]);
1933 RMW->setVolatile(Volatile);
1934 Result->addIncoming(RMW, BBs[i]);
1935 Builder.CreateBr(ContBB);
1936 }
1937
1938 SI->addCase(Builder.getInt32(0), BBs[0]);
1939 SI->addCase(Builder.getInt32(1), BBs[1]);
1940 SI->addCase(Builder.getInt32(2), BBs[1]);
1941 SI->addCase(Builder.getInt32(3), BBs[2]);
1942 SI->addCase(Builder.getInt32(4), BBs[3]);
1943 SI->addCase(Builder.getInt32(5), BBs[4]);
1944
1945 Builder.SetInsertPoint(ContBB);
1946 return RValue::get(Builder.CreateIsNotNull(Result, "tobool"));
1947 }
1948
1949 case Builtin::BI__atomic_clear: {
1950 QualType PtrTy = E->getArg(0)->IgnoreImpCasts()->getType();
1951 bool Volatile =
1952 PtrTy->castAs<PointerType>()->getPointeeType().isVolatileQualified();
1953
John McCall7f416cc2015-09-08 08:05:57 +00001954 Address Ptr = EmitPointerWithAlignment(E->getArg(0));
1955 unsigned AddrSpace = Ptr.getPointer()->getType()->getPointerAddressSpace();
Richard Smith01ba47d2012-04-13 00:45:38 +00001956 Ptr = Builder.CreateBitCast(Ptr, Int8Ty->getPointerTo(AddrSpace));
1957 Value *NewVal = Builder.getInt8(0);
1958 Value *Order = EmitScalarExpr(E->getArg(1));
1959 if (isa<llvm::ConstantInt>(Order)) {
1960 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
1961 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001962 switch (ord) {
1963 case 0: // memory_order_relaxed
1964 default: // invalid order
JF Bastien92f4ef12016-04-06 17:26:42 +00001965 Store->setOrdering(llvm::AtomicOrdering::Monotonic);
Richard Smith01ba47d2012-04-13 00:45:38 +00001966 break;
1967 case 3: // memory_order_release
JF Bastien92f4ef12016-04-06 17:26:42 +00001968 Store->setOrdering(llvm::AtomicOrdering::Release);
Richard Smith01ba47d2012-04-13 00:45:38 +00001969 break;
1970 case 5: // memory_order_seq_cst
JF Bastien92f4ef12016-04-06 17:26:42 +00001971 Store->setOrdering(llvm::AtomicOrdering::SequentiallyConsistent);
Richard Smith01ba47d2012-04-13 00:45:38 +00001972 break;
1973 }
Craig Topper8a13c412014-05-21 05:09:00 +00001974 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00001975 }
1976
1977 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
1978
1979 llvm::BasicBlock *BBs[3] = {
1980 createBasicBlock("monotonic", CurFn),
1981 createBasicBlock("release", CurFn),
1982 createBasicBlock("seqcst", CurFn)
1983 };
1984 llvm::AtomicOrdering Orders[3] = {
JF Bastien92f4ef12016-04-06 17:26:42 +00001985 llvm::AtomicOrdering::Monotonic, llvm::AtomicOrdering::Release,
1986 llvm::AtomicOrdering::SequentiallyConsistent};
Richard Smith01ba47d2012-04-13 00:45:38 +00001987
1988 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
1989 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, BBs[0]);
1990
1991 for (unsigned i = 0; i < 3; ++i) {
1992 Builder.SetInsertPoint(BBs[i]);
1993 StoreInst *Store = Builder.CreateStore(NewVal, Ptr, Volatile);
Richard Smith01ba47d2012-04-13 00:45:38 +00001994 Store->setOrdering(Orders[i]);
1995 Builder.CreateBr(ContBB);
1996 }
1997
1998 SI->addCase(Builder.getInt32(0), BBs[0]);
1999 SI->addCase(Builder.getInt32(3), BBs[1]);
2000 SI->addCase(Builder.getInt32(5), BBs[2]);
2001
2002 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00002003 return RValue::get(nullptr);
Richard Smith01ba47d2012-04-13 00:45:38 +00002004 }
2005
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002006 case Builtin::BI__atomic_thread_fence:
Richard Smithb1e36c62012-04-11 17:55:32 +00002007 case Builtin::BI__atomic_signal_fence:
2008 case Builtin::BI__c11_atomic_thread_fence:
2009 case Builtin::BI__c11_atomic_signal_fence: {
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002010 llvm::SyncScope::ID SSID;
Richard Smithb1e36c62012-04-11 17:55:32 +00002011 if (BuiltinID == Builtin::BI__atomic_signal_fence ||
2012 BuiltinID == Builtin::BI__c11_atomic_signal_fence)
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002013 SSID = llvm::SyncScope::SingleThread;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002014 else
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002015 SSID = llvm::SyncScope::System;
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002016 Value *Order = EmitScalarExpr(E->getArg(0));
2017 if (isa<llvm::ConstantInt>(Order)) {
2018 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
2019 switch (ord) {
2020 case 0: // memory_order_relaxed
2021 default: // invalid order
2022 break;
2023 case 1: // memory_order_consume
2024 case 2: // memory_order_acquire
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002025 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002026 break;
2027 case 3: // memory_order_release
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002028 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002029 break;
2030 case 4: // memory_order_acq_rel
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002031 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002032 break;
2033 case 5: // memory_order_seq_cst
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002034 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002035 break;
2036 }
Craig Topper8a13c412014-05-21 05:09:00 +00002037 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002038 }
2039
2040 llvm::BasicBlock *AcquireBB, *ReleaseBB, *AcqRelBB, *SeqCstBB;
2041 AcquireBB = createBasicBlock("acquire", CurFn);
2042 ReleaseBB = createBasicBlock("release", CurFn);
2043 AcqRelBB = createBasicBlock("acqrel", CurFn);
2044 SeqCstBB = createBasicBlock("seqcst", CurFn);
2045 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
2046
2047 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
2048 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, ContBB);
2049
2050 Builder.SetInsertPoint(AcquireBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002051 Builder.CreateFence(llvm::AtomicOrdering::Acquire, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002052 Builder.CreateBr(ContBB);
2053 SI->addCase(Builder.getInt32(1), AcquireBB);
2054 SI->addCase(Builder.getInt32(2), AcquireBB);
2055
2056 Builder.SetInsertPoint(ReleaseBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002057 Builder.CreateFence(llvm::AtomicOrdering::Release, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002058 Builder.CreateBr(ContBB);
2059 SI->addCase(Builder.getInt32(3), ReleaseBB);
2060
2061 Builder.SetInsertPoint(AcqRelBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002062 Builder.CreateFence(llvm::AtomicOrdering::AcquireRelease, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002063 Builder.CreateBr(ContBB);
2064 SI->addCase(Builder.getInt32(4), AcqRelBB);
2065
2066 Builder.SetInsertPoint(SeqCstBB);
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00002067 Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent, SSID);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002068 Builder.CreateBr(ContBB);
2069 SI->addCase(Builder.getInt32(5), SeqCstBB);
2070
2071 Builder.SetInsertPoint(ContBB);
Craig Topper8a13c412014-05-21 05:09:00 +00002072 return RValue::get(nullptr);
Eli Friedmandf14b3a2011-10-11 02:20:01 +00002073 }
2074
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002075 // Library functions with special handling.
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002076 case Builtin::BIsqrt:
2077 case Builtin::BIsqrtf:
2078 case Builtin::BIsqrtl: {
Hal Finkel28b2ae32013-09-12 23:57:55 +00002079 // Transform a call to sqrt* into a @llvm.sqrt.* intrinsic call, but only
2080 // in finite- or unsafe-math mode (the intrinsic has different semantics
2081 // for handling negative numbers compared to the library function, so
2082 // -fmath-errno=0 is not enough).
2083 if (!FD->hasAttr<ConstAttr>())
2084 break;
2085 if (!(CGM.getCodeGenOpts().UnsafeFPMath ||
2086 CGM.getCodeGenOpts().NoNaNsFPMath))
2087 break;
2088 Value *Arg0 = EmitScalarExpr(E->getArg(0));
2089 llvm::Type *ArgType = Arg0->getType();
2090 Value *F = CGM.getIntrinsic(Intrinsic::sqrt, ArgType);
2091 return RValue::get(Builder.CreateCall(F, Arg0));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002092 }
2093
Reid Kleckner8a8c1292015-02-05 00:18:01 +00002094 case Builtin::BI__builtin_pow:
2095 case Builtin::BI__builtin_powf:
2096 case Builtin::BI__builtin_powl:
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002097 case Builtin::BIpow:
2098 case Builtin::BIpowf:
2099 case Builtin::BIpowl: {
Eli Benderskyc3496b02013-07-24 21:22:01 +00002100 // Transform a call to pow* into a @llvm.pow.* intrinsic call.
2101 if (!FD->hasAttr<ConstAttr>())
2102 break;
2103 Value *Base = EmitScalarExpr(E->getArg(0));
2104 Value *Exponent = EmitScalarExpr(E->getArg(1));
2105 llvm::Type *ArgType = Base->getType();
2106 Value *F = CGM.getIntrinsic(Intrinsic::pow, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00002107 return RValue::get(Builder.CreateCall(F, {Base, Exponent}));
Daniel Dunbar8eb018a2009-02-16 22:43:43 +00002108 }
Eli Friedman99d20f82010-03-06 02:17:52 +00002109
Cameron Zwarichae7bc982011-07-08 21:39:34 +00002110 case Builtin::BIfma:
2111 case Builtin::BIfmaf:
2112 case Builtin::BIfmal:
2113 case Builtin::BI__builtin_fma:
2114 case Builtin::BI__builtin_fmaf:
2115 case Builtin::BI__builtin_fmal: {
2116 // Rewrite fma to intrinsic.
2117 Value *FirstArg = EmitScalarExpr(E->getArg(0));
Chris Lattnera5f58b02011-07-09 17:41:47 +00002118 llvm::Type *ArgType = FirstArg->getType();
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00002119 Value *F = CGM.getIntrinsic(Intrinsic::fma, ArgType);
David Blaikie43f9bb72015-05-18 22:14:03 +00002120 return RValue::get(
2121 Builder.CreateCall(F, {FirstArg, EmitScalarExpr(E->getArg(1)),
2122 EmitScalarExpr(E->getArg(2))}));
Cameron Zwarichae7bc982011-07-08 21:39:34 +00002123 }
2124
Eli Friedman99d20f82010-03-06 02:17:52 +00002125 case Builtin::BI__builtin_signbit:
2126 case Builtin::BI__builtin_signbitf:
2127 case Builtin::BI__builtin_signbitl: {
Chandler Carruthc66deaf2015-03-19 22:39:51 +00002128 return RValue::get(
2129 Builder.CreateZExt(EmitSignBit(*this, EmitScalarExpr(E->getArg(0))),
2130 ConvertType(E->getType())));
Eli Friedman99d20f82010-03-06 02:17:52 +00002131 }
Reid Kleckner30701ed2017-09-05 20:27:35 +00002132 case Builtin::BI__annotation: {
2133 // Re-encode each wide string to UTF8 and make an MDString.
2134 SmallVector<Metadata *, 1> Strings;
2135 for (const Expr *Arg : E->arguments()) {
2136 const auto *Str = cast<StringLiteral>(Arg->IgnoreParenCasts());
2137 assert(Str->getCharByteWidth() == 2);
2138 StringRef WideBytes = Str->getBytes();
2139 std::string StrUtf8;
2140 if (!convertUTF16ToUTF8String(
2141 makeArrayRef(WideBytes.data(), WideBytes.size()), StrUtf8)) {
2142 CGM.ErrorUnsupported(E, "non-UTF16 __annotation argument");
2143 continue;
2144 }
2145 Strings.push_back(llvm::MDString::get(getLLVMContext(), StrUtf8));
2146 }
2147
2148 // Build and MDTuple of MDStrings and emit the intrinsic call.
Reid Klecknerd53c39b2017-09-05 20:38:29 +00002149 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::codeview_annotation, {});
Reid Kleckner30701ed2017-09-05 20:27:35 +00002150 MDTuple *StrTuple = MDTuple::get(getLLVMContext(), Strings);
2151 Builder.CreateCall(F, MetadataAsValue::get(getLLVMContext(), StrTuple));
2152 return RValue::getIgnored();
2153 }
Julien Lerouge5a6b6982011-09-09 22:41:49 +00002154 case Builtin::BI__builtin_annotation: {
2155 llvm::Value *AnnVal = EmitScalarExpr(E->getArg(0));
2156 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::annotation,
2157 AnnVal->getType());
2158
2159 // Get the annotation string, go through casts. Sema requires this to be a
2160 // non-wide string literal, potentially casted, so the cast<> is safe.
2161 const Expr *AnnotationStrExpr = E->getArg(1)->IgnoreParenCasts();
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002162 StringRef Str = cast<StringLiteral>(AnnotationStrExpr)->getString();
Julien Lerouge5a6b6982011-09-09 22:41:49 +00002163 return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc()));
2164 }
Michael Gottesman15343992013-06-18 20:40:40 +00002165 case Builtin::BI__builtin_addcb:
Michael Gottesman54398012013-01-13 02:22:39 +00002166 case Builtin::BI__builtin_addcs:
2167 case Builtin::BI__builtin_addc:
2168 case Builtin::BI__builtin_addcl:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002169 case Builtin::BI__builtin_addcll:
Michael Gottesman15343992013-06-18 20:40:40 +00002170 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002171 case Builtin::BI__builtin_subcs:
2172 case Builtin::BI__builtin_subc:
2173 case Builtin::BI__builtin_subcl:
2174 case Builtin::BI__builtin_subcll: {
Michael Gottesman54398012013-01-13 02:22:39 +00002175
2176 // We translate all of these builtins from expressions of the form:
2177 // int x = ..., y = ..., carryin = ..., carryout, result;
2178 // result = __builtin_addc(x, y, carryin, &carryout);
2179 //
2180 // to LLVM IR of the form:
2181 //
2182 // %tmp1 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %x, i32 %y)
2183 // %tmpsum1 = extractvalue {i32, i1} %tmp1, 0
2184 // %carry1 = extractvalue {i32, i1} %tmp1, 1
2185 // %tmp2 = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %tmpsum1,
2186 // i32 %carryin)
2187 // %result = extractvalue {i32, i1} %tmp2, 0
2188 // %carry2 = extractvalue {i32, i1} %tmp2, 1
2189 // %tmp3 = or i1 %carry1, %carry2
2190 // %tmp4 = zext i1 %tmp3 to i32
2191 // store i32 %tmp4, i32* %carryout
2192
2193 // Scalarize our inputs.
2194 llvm::Value *X = EmitScalarExpr(E->getArg(0));
2195 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
2196 llvm::Value *Carryin = EmitScalarExpr(E->getArg(2));
John McCall7f416cc2015-09-08 08:05:57 +00002197 Address CarryOutPtr = EmitPointerWithAlignment(E->getArg(3));
Michael Gottesman54398012013-01-13 02:22:39 +00002198
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002199 // Decide if we are lowering to a uadd.with.overflow or usub.with.overflow.
2200 llvm::Intrinsic::ID IntrinsicId;
2201 switch (BuiltinID) {
2202 default: llvm_unreachable("Unknown multiprecision builtin id.");
Michael Gottesman15343992013-06-18 20:40:40 +00002203 case Builtin::BI__builtin_addcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002204 case Builtin::BI__builtin_addcs:
2205 case Builtin::BI__builtin_addc:
2206 case Builtin::BI__builtin_addcl:
2207 case Builtin::BI__builtin_addcll:
2208 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2209 break;
Michael Gottesman15343992013-06-18 20:40:40 +00002210 case Builtin::BI__builtin_subcb:
Michael Gottesmana2b5c4b2013-01-14 21:44:30 +00002211 case Builtin::BI__builtin_subcs:
2212 case Builtin::BI__builtin_subc:
2213 case Builtin::BI__builtin_subcl:
2214 case Builtin::BI__builtin_subcll:
2215 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2216 break;
2217 }
Michael Gottesman54398012013-01-13 02:22:39 +00002218
2219 // Construct our resulting LLVM IR expression.
2220 llvm::Value *Carry1;
2221 llvm::Value *Sum1 = EmitOverflowIntrinsic(*this, IntrinsicId,
2222 X, Y, Carry1);
2223 llvm::Value *Carry2;
2224 llvm::Value *Sum2 = EmitOverflowIntrinsic(*this, IntrinsicId,
2225 Sum1, Carryin, Carry2);
2226 llvm::Value *CarryOut = Builder.CreateZExt(Builder.CreateOr(Carry1, Carry2),
2227 X->getType());
John McCall7f416cc2015-09-08 08:05:57 +00002228 Builder.CreateStore(CarryOut, CarryOutPtr);
Michael Gottesman54398012013-01-13 02:22:39 +00002229 return RValue::get(Sum2);
2230 }
John McCall03107a42015-10-29 20:48:01 +00002231
2232 case Builtin::BI__builtin_add_overflow:
2233 case Builtin::BI__builtin_sub_overflow:
2234 case Builtin::BI__builtin_mul_overflow: {
2235 const clang::Expr *LeftArg = E->getArg(0);
2236 const clang::Expr *RightArg = E->getArg(1);
2237 const clang::Expr *ResultArg = E->getArg(2);
2238
2239 clang::QualType ResultQTy =
2240 ResultArg->getType()->castAs<PointerType>()->getPointeeType();
2241
2242 WidthAndSignedness LeftInfo =
2243 getIntegerWidthAndSignedness(CGM.getContext(), LeftArg->getType());
2244 WidthAndSignedness RightInfo =
2245 getIntegerWidthAndSignedness(CGM.getContext(), RightArg->getType());
2246 WidthAndSignedness ResultInfo =
2247 getIntegerWidthAndSignedness(CGM.getContext(), ResultQTy);
2248 WidthAndSignedness EncompassingInfo =
2249 EncompassingIntegerType({LeftInfo, RightInfo, ResultInfo});
2250
2251 llvm::Type *EncompassingLLVMTy =
2252 llvm::IntegerType::get(CGM.getLLVMContext(), EncompassingInfo.Width);
2253
2254 llvm::Type *ResultLLVMTy = CGM.getTypes().ConvertType(ResultQTy);
2255
2256 llvm::Intrinsic::ID IntrinsicId;
2257 switch (BuiltinID) {
2258 default:
2259 llvm_unreachable("Unknown overflow builtin id.");
2260 case Builtin::BI__builtin_add_overflow:
2261 IntrinsicId = EncompassingInfo.Signed
2262 ? llvm::Intrinsic::sadd_with_overflow
2263 : llvm::Intrinsic::uadd_with_overflow;
2264 break;
2265 case Builtin::BI__builtin_sub_overflow:
2266 IntrinsicId = EncompassingInfo.Signed
2267 ? llvm::Intrinsic::ssub_with_overflow
2268 : llvm::Intrinsic::usub_with_overflow;
2269 break;
2270 case Builtin::BI__builtin_mul_overflow:
2271 IntrinsicId = EncompassingInfo.Signed
2272 ? llvm::Intrinsic::smul_with_overflow
2273 : llvm::Intrinsic::umul_with_overflow;
2274 break;
2275 }
2276
2277 llvm::Value *Left = EmitScalarExpr(LeftArg);
2278 llvm::Value *Right = EmitScalarExpr(RightArg);
2279 Address ResultPtr = EmitPointerWithAlignment(ResultArg);
2280
2281 // Extend each operand to the encompassing type.
2282 Left = Builder.CreateIntCast(Left, EncompassingLLVMTy, LeftInfo.Signed);
2283 Right = Builder.CreateIntCast(Right, EncompassingLLVMTy, RightInfo.Signed);
2284
2285 // Perform the operation on the extended values.
2286 llvm::Value *Overflow, *Result;
2287 Result = EmitOverflowIntrinsic(*this, IntrinsicId, Left, Right, Overflow);
2288
2289 if (EncompassingInfo.Width > ResultInfo.Width) {
2290 // The encompassing type is wider than the result type, so we need to
2291 // truncate it.
2292 llvm::Value *ResultTrunc = Builder.CreateTrunc(Result, ResultLLVMTy);
2293
2294 // To see if the truncation caused an overflow, we will extend
2295 // the result and then compare it to the original result.
2296 llvm::Value *ResultTruncExt = Builder.CreateIntCast(
2297 ResultTrunc, EncompassingLLVMTy, ResultInfo.Signed);
2298 llvm::Value *TruncationOverflow =
2299 Builder.CreateICmpNE(Result, ResultTruncExt);
2300
2301 Overflow = Builder.CreateOr(Overflow, TruncationOverflow);
2302 Result = ResultTrunc;
2303 }
2304
2305 // Finally, store the result using the pointer.
2306 bool isVolatile =
2307 ResultArg->getType()->getPointeeType().isVolatileQualified();
2308 Builder.CreateStore(EmitToMemory(Result, ResultQTy), ResultPtr, isVolatile);
2309
2310 return RValue::get(Overflow);
2311 }
2312
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002313 case Builtin::BI__builtin_uadd_overflow:
2314 case Builtin::BI__builtin_uaddl_overflow:
2315 case Builtin::BI__builtin_uaddll_overflow:
2316 case Builtin::BI__builtin_usub_overflow:
2317 case Builtin::BI__builtin_usubl_overflow:
2318 case Builtin::BI__builtin_usubll_overflow:
2319 case Builtin::BI__builtin_umul_overflow:
2320 case Builtin::BI__builtin_umull_overflow:
2321 case Builtin::BI__builtin_umulll_overflow:
2322 case Builtin::BI__builtin_sadd_overflow:
2323 case Builtin::BI__builtin_saddl_overflow:
2324 case Builtin::BI__builtin_saddll_overflow:
2325 case Builtin::BI__builtin_ssub_overflow:
2326 case Builtin::BI__builtin_ssubl_overflow:
2327 case Builtin::BI__builtin_ssubll_overflow:
2328 case Builtin::BI__builtin_smul_overflow:
2329 case Builtin::BI__builtin_smull_overflow:
2330 case Builtin::BI__builtin_smulll_overflow: {
2331
2332 // We translate all of these builtins directly to the relevant llvm IR node.
2333
2334 // Scalarize our inputs.
2335 llvm::Value *X = EmitScalarExpr(E->getArg(0));
2336 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
John McCall7f416cc2015-09-08 08:05:57 +00002337 Address SumOutPtr = EmitPointerWithAlignment(E->getArg(2));
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002338
2339 // Decide which of the overflow intrinsics we are lowering to:
2340 llvm::Intrinsic::ID IntrinsicId;
2341 switch (BuiltinID) {
John McCall03107a42015-10-29 20:48:01 +00002342 default: llvm_unreachable("Unknown overflow builtin id.");
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002343 case Builtin::BI__builtin_uadd_overflow:
2344 case Builtin::BI__builtin_uaddl_overflow:
2345 case Builtin::BI__builtin_uaddll_overflow:
2346 IntrinsicId = llvm::Intrinsic::uadd_with_overflow;
2347 break;
2348 case Builtin::BI__builtin_usub_overflow:
2349 case Builtin::BI__builtin_usubl_overflow:
2350 case Builtin::BI__builtin_usubll_overflow:
2351 IntrinsicId = llvm::Intrinsic::usub_with_overflow;
2352 break;
2353 case Builtin::BI__builtin_umul_overflow:
2354 case Builtin::BI__builtin_umull_overflow:
2355 case Builtin::BI__builtin_umulll_overflow:
2356 IntrinsicId = llvm::Intrinsic::umul_with_overflow;
2357 break;
2358 case Builtin::BI__builtin_sadd_overflow:
2359 case Builtin::BI__builtin_saddl_overflow:
2360 case Builtin::BI__builtin_saddll_overflow:
2361 IntrinsicId = llvm::Intrinsic::sadd_with_overflow;
2362 break;
2363 case Builtin::BI__builtin_ssub_overflow:
2364 case Builtin::BI__builtin_ssubl_overflow:
2365 case Builtin::BI__builtin_ssubll_overflow:
2366 IntrinsicId = llvm::Intrinsic::ssub_with_overflow;
2367 break;
2368 case Builtin::BI__builtin_smul_overflow:
2369 case Builtin::BI__builtin_smull_overflow:
2370 case Builtin::BI__builtin_smulll_overflow:
2371 IntrinsicId = llvm::Intrinsic::smul_with_overflow;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00002372 break;
2373 }
2374
2375
2376 llvm::Value *Carry;
2377 llvm::Value *Sum = EmitOverflowIntrinsic(*this, IntrinsicId, X, Y, Carry);
2378 Builder.CreateStore(Sum, SumOutPtr);
Michael Gottesman930ecdb2013-06-20 23:28:10 +00002379
2380 return RValue::get(Carry);
2381 }
Richard Smith6cbd65d2013-07-11 02:27:57 +00002382 case Builtin::BI__builtin_addressof:
John McCall7f416cc2015-09-08 08:05:57 +00002383 return RValue::get(EmitLValue(E->getArg(0)).getPointer());
Richard Smith760520b2014-06-03 23:27:44 +00002384 case Builtin::BI__builtin_operator_new:
2385 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2386 E->getArg(0), false);
2387 case Builtin::BI__builtin_operator_delete:
2388 return EmitBuiltinNewDeleteCall(FD->getType()->castAs<FunctionProtoType>(),
2389 E->getArg(0), true);
Nico Weber636fc092012-10-13 22:30:41 +00002390 case Builtin::BI__noop:
Reid Klecknered5d4ad2014-07-11 20:22:55 +00002391 // __noop always evaluates to an integer literal zero.
2392 return RValue::get(ConstantInt::get(IntTy, 0));
Peter Collingbournef7706832014-12-12 23:41:25 +00002393 case Builtin::BI__builtin_call_with_static_chain: {
2394 const CallExpr *Call = cast<CallExpr>(E->getArg(0));
2395 const Expr *Chain = E->getArg(1);
2396 return EmitCall(Call->getCallee()->getType(),
John McCallb92ab1a2016-10-26 23:46:34 +00002397 EmitCallee(Call->getCallee()), Call, ReturnValue,
2398 EmitScalarExpr(Chain));
Peter Collingbournef7706832014-12-12 23:41:25 +00002399 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002400 case Builtin::BI_InterlockedExchange8:
2401 case Builtin::BI_InterlockedExchange16:
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002402 case Builtin::BI_InterlockedExchange:
2403 case Builtin::BI_InterlockedExchangePointer:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002404 return RValue::get(
2405 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E));
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002406 case Builtin::BI_InterlockedCompareExchangePointer: {
2407 llvm::Type *RTy;
2408 llvm::IntegerType *IntType =
2409 IntegerType::get(getLLVMContext(),
2410 getContext().getTypeSize(E->getType()));
2411 llvm::Type *IntPtrType = IntType->getPointerTo();
2412
2413 llvm::Value *Destination =
2414 Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), IntPtrType);
2415
2416 llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
2417 RTy = Exchange->getType();
2418 Exchange = Builder.CreatePtrToInt(Exchange, IntType);
2419
2420 llvm::Value *Comparand =
2421 Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
2422
JF Bastien92f4ef12016-04-06 17:26:42 +00002423 auto Result =
2424 Builder.CreateAtomicCmpXchg(Destination, Comparand, Exchange,
2425 AtomicOrdering::SequentiallyConsistent,
2426 AtomicOrdering::SequentiallyConsistent);
Saleem Abdulrasool114efe02014-06-18 20:51:10 +00002427 Result->setVolatile(true);
2428
2429 return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
2430 0),
2431 RTy));
2432 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002433 case Builtin::BI_InterlockedCompareExchange8:
2434 case Builtin::BI_InterlockedCompareExchange16:
2435 case Builtin::BI_InterlockedCompareExchange:
2436 case Builtin::BI_InterlockedCompareExchange64: {
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002437 AtomicCmpXchgInst *CXI = Builder.CreateAtomicCmpXchg(
2438 EmitScalarExpr(E->getArg(0)),
2439 EmitScalarExpr(E->getArg(2)),
2440 EmitScalarExpr(E->getArg(1)),
JF Bastien92f4ef12016-04-06 17:26:42 +00002441 AtomicOrdering::SequentiallyConsistent,
2442 AtomicOrdering::SequentiallyConsistent);
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002443 CXI->setVolatile(true);
Tim Northoverb49b04b2014-06-13 14:24:59 +00002444 return RValue::get(Builder.CreateExtractValue(CXI, 0));
Warren Hunt20e4a5d2014-02-21 23:08:53 +00002445 }
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002446 case Builtin::BI_InterlockedIncrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002447 case Builtin::BI_InterlockedIncrement:
2448 return RValue::get(
2449 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002450 case Builtin::BI_InterlockedDecrement16:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002451 case Builtin::BI_InterlockedDecrement:
2452 return RValue::get(
2453 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002454 case Builtin::BI_InterlockedAnd8:
2455 case Builtin::BI_InterlockedAnd16:
2456 case Builtin::BI_InterlockedAnd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002457 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002458 case Builtin::BI_InterlockedExchangeAdd8:
2459 case Builtin::BI_InterlockedExchangeAdd16:
2460 case Builtin::BI_InterlockedExchangeAdd:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002461 return RValue::get(
2462 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002463 case Builtin::BI_InterlockedExchangeSub8:
2464 case Builtin::BI_InterlockedExchangeSub16:
2465 case Builtin::BI_InterlockedExchangeSub:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002466 return RValue::get(
2467 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002468 case Builtin::BI_InterlockedOr8:
2469 case Builtin::BI_InterlockedOr16:
2470 case Builtin::BI_InterlockedOr:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002471 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E));
Albert Gutowskice7a9a42016-09-13 19:43:33 +00002472 case Builtin::BI_InterlockedXor8:
2473 case Builtin::BI_InterlockedXor16:
2474 case Builtin::BI_InterlockedXor:
Albert Gutowski5e08df02016-10-13 22:35:07 +00002475 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E));
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002476 case Builtin::BI_interlockedbittestandset:
2477 return RValue::get(
2478 EmitMSVCBuiltinExpr(MSVCIntrin::_interlockedbittestandset, E));
Reid Kleckner1d59f992015-01-22 01:36:17 +00002479
2480 case Builtin::BI__exception_code:
2481 case Builtin::BI_exception_code:
2482 return RValue::get(EmitSEHExceptionCode());
2483 case Builtin::BI__exception_info:
2484 case Builtin::BI_exception_info:
2485 return RValue::get(EmitSEHExceptionInfo());
Reid Kleckneraca01db2015-02-04 22:37:07 +00002486 case Builtin::BI__abnormal_termination:
2487 case Builtin::BI_abnormal_termination:
2488 return RValue::get(EmitSEHAbnormalTermination());
David Majnemer310e3a82015-01-29 09:29:21 +00002489 case Builtin::BI_setjmpex: {
2490 if (getTarget().getTriple().isOSMSVCRT()) {
2491 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
Reid Klecknerde864822017-03-21 16:57:30 +00002492 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2493 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2494 llvm::Attribute::ReturnsTwice);
David Majnemer310e3a82015-01-29 09:29:21 +00002495 llvm::Constant *SetJmpEx = CGM.CreateRuntimeFunction(
2496 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002497 "_setjmpex", ReturnsTwiceAttr, /*Local=*/true);
David Majnemerc403a1c2015-03-20 17:03:35 +00002498 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2499 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002500 llvm::Value *FrameAddr =
2501 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2502 ConstantInt::get(Int32Ty, 0));
2503 llvm::Value *Args[] = {Buf, FrameAddr};
2504 llvm::CallSite CS = EmitRuntimeCallOrInvoke(SetJmpEx, Args);
2505 CS.setAttributes(ReturnsTwiceAttr);
2506 return RValue::get(CS.getInstruction());
2507 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002508 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002509 }
2510 case Builtin::BI_setjmp: {
2511 if (getTarget().getTriple().isOSMSVCRT()) {
Reid Klecknerde864822017-03-21 16:57:30 +00002512 llvm::AttributeList ReturnsTwiceAttr = llvm::AttributeList::get(
2513 getLLVMContext(), llvm::AttributeList::FunctionIndex,
2514 llvm::Attribute::ReturnsTwice);
David Majnemerc403a1c2015-03-20 17:03:35 +00002515 llvm::Value *Buf = Builder.CreateBitOrPointerCast(
2516 EmitScalarExpr(E->getArg(0)), Int8PtrTy);
David Majnemer310e3a82015-01-29 09:29:21 +00002517 llvm::CallSite CS;
2518 if (getTarget().getTriple().getArch() == llvm::Triple::x86) {
2519 llvm::Type *ArgTypes[] = {Int8PtrTy, IntTy};
2520 llvm::Constant *SetJmp3 = CGM.CreateRuntimeFunction(
2521 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/true),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002522 "_setjmp3", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002523 llvm::Value *Count = ConstantInt::get(IntTy, 0);
2524 llvm::Value *Args[] = {Buf, Count};
2525 CS = EmitRuntimeCallOrInvoke(SetJmp3, Args);
2526 } else {
2527 llvm::Type *ArgTypes[] = {Int8PtrTy, Int8PtrTy};
2528 llvm::Constant *SetJmp = CGM.CreateRuntimeFunction(
2529 llvm::FunctionType::get(IntTy, ArgTypes, /*isVarArg=*/false),
Saleem Abdulrasool342beeb2016-12-15 07:29:04 +00002530 "_setjmp", ReturnsTwiceAttr, /*Local=*/true);
David Majnemer310e3a82015-01-29 09:29:21 +00002531 llvm::Value *FrameAddr =
2532 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::frameaddress),
2533 ConstantInt::get(Int32Ty, 0));
2534 llvm::Value *Args[] = {Buf, FrameAddr};
2535 CS = EmitRuntimeCallOrInvoke(SetJmp, Args);
2536 }
2537 CS.setAttributes(ReturnsTwiceAttr);
2538 return RValue::get(CS.getInstruction());
2539 }
David Majnemerc403a1c2015-03-20 17:03:35 +00002540 break;
David Majnemer310e3a82015-01-29 09:29:21 +00002541 }
David Majnemerba3e5ec2015-03-13 18:26:17 +00002542
2543 case Builtin::BI__GetExceptionInfo: {
2544 if (llvm::GlobalVariable *GV =
2545 CGM.getCXXABI().getThrowInfo(FD->getParamDecl(0)->getType()))
2546 return RValue::get(llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy));
2547 break;
2548 }
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002549
Hans Wennborg5c3c51f2017-04-07 16:41:47 +00002550 case Builtin::BI__fastfail:
Reid Kleckner04f9f912017-02-09 18:31:06 +00002551 return RValue::get(EmitMSVCBuiltinExpr(MSVCIntrin::__fastfail, E));
Reid Kleckner04f9f912017-02-09 18:31:06 +00002552
Gor Nishanov97e3b6d2016-10-03 22:44:48 +00002553 case Builtin::BI__builtin_coro_size: {
2554 auto & Context = getContext();
2555 auto SizeTy = Context.getSizeType();
2556 auto T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
2557 Value *F = CGM.getIntrinsic(Intrinsic::coro_size, T);
2558 return RValue::get(Builder.CreateCall(F));
2559 }
2560
2561 case Builtin::BI__builtin_coro_id:
2562 return EmitCoroutineIntrinsic(E, Intrinsic::coro_id);
2563 case Builtin::BI__builtin_coro_promise:
2564 return EmitCoroutineIntrinsic(E, Intrinsic::coro_promise);
2565 case Builtin::BI__builtin_coro_resume:
2566 return EmitCoroutineIntrinsic(E, Intrinsic::coro_resume);
2567 case Builtin::BI__builtin_coro_frame:
2568 return EmitCoroutineIntrinsic(E, Intrinsic::coro_frame);
2569 case Builtin::BI__builtin_coro_free:
2570 return EmitCoroutineIntrinsic(E, Intrinsic::coro_free);
2571 case Builtin::BI__builtin_coro_destroy:
2572 return EmitCoroutineIntrinsic(E, Intrinsic::coro_destroy);
2573 case Builtin::BI__builtin_coro_done:
2574 return EmitCoroutineIntrinsic(E, Intrinsic::coro_done);
2575 case Builtin::BI__builtin_coro_alloc:
2576 return EmitCoroutineIntrinsic(E, Intrinsic::coro_alloc);
2577 case Builtin::BI__builtin_coro_begin:
2578 return EmitCoroutineIntrinsic(E, Intrinsic::coro_begin);
2579 case Builtin::BI__builtin_coro_end:
2580 return EmitCoroutineIntrinsic(E, Intrinsic::coro_end);
2581 case Builtin::BI__builtin_coro_suspend:
2582 return EmitCoroutineIntrinsic(E, Intrinsic::coro_suspend);
2583 case Builtin::BI__builtin_coro_param:
2584 return EmitCoroutineIntrinsic(E, Intrinsic::coro_param);
2585
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002586 // OpenCL v2.0 s6.13.16.2, Built-in pipe read and write functions
2587 case Builtin::BIread_pipe:
2588 case Builtin::BIwrite_pipe: {
2589 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2590 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002591 CGOpenCLRuntime OpenCLRT(CGM);
2592 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2593 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002594
2595 // Type of the generic packet parameter.
2596 unsigned GenericAS =
2597 getContext().getTargetAddressSpace(LangAS::opencl_generic);
2598 llvm::Type *I8PTy = llvm::PointerType::get(
2599 llvm::Type::getInt8Ty(getLLVMContext()), GenericAS);
2600
2601 // Testing which overloaded version we should generate the call for.
2602 if (2U == E->getNumArgs()) {
2603 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_2"
2604 : "__write_pipe_2";
2605 // Creating a generic function type to be able to call with any builtin or
2606 // user defined type.
Alexey Bader465c1892016-09-23 14:20:00 +00002607 llvm::Type *ArgTys[] = {Arg0->getType(), I8PTy, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002608 llvm::FunctionType *FTy = llvm::FunctionType::get(
2609 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2610 Value *BCast = Builder.CreatePointerCast(Arg1, I8PTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002611 return RValue::get(
2612 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2613 {Arg0, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002614 } else {
2615 assert(4 == E->getNumArgs() &&
2616 "Illegal number of parameters to pipe function");
2617 const char *Name = (BuiltinID == Builtin::BIread_pipe) ? "__read_pipe_4"
2618 : "__write_pipe_4";
2619
Alexey Bader465c1892016-09-23 14:20:00 +00002620 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, I8PTy,
2621 Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002622 Value *Arg2 = EmitScalarExpr(E->getArg(2)),
2623 *Arg3 = EmitScalarExpr(E->getArg(3));
2624 llvm::FunctionType *FTy = llvm::FunctionType::get(
2625 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2626 Value *BCast = Builder.CreatePointerCast(Arg3, I8PTy);
2627 // We know the third argument is an integer type, but we may need to cast
2628 // it to i32.
2629 if (Arg2->getType() != Int32Ty)
2630 Arg2 = Builder.CreateZExtOrTrunc(Arg2, Int32Ty);
2631 return RValue::get(Builder.CreateCall(
Alexey Bader465c1892016-09-23 14:20:00 +00002632 CGM.CreateRuntimeFunction(FTy, Name),
2633 {Arg0, Arg1, Arg2, BCast, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002634 }
2635 }
2636 // OpenCL v2.0 s6.13.16 ,s9.17.3.5 - Built-in pipe reserve read and write
2637 // functions
2638 case Builtin::BIreserve_read_pipe:
2639 case Builtin::BIreserve_write_pipe:
2640 case Builtin::BIwork_group_reserve_read_pipe:
2641 case Builtin::BIwork_group_reserve_write_pipe:
2642 case Builtin::BIsub_group_reserve_read_pipe:
2643 case Builtin::BIsub_group_reserve_write_pipe: {
2644 // Composing the mangled name for the function.
2645 const char *Name;
2646 if (BuiltinID == Builtin::BIreserve_read_pipe)
2647 Name = "__reserve_read_pipe";
2648 else if (BuiltinID == Builtin::BIreserve_write_pipe)
2649 Name = "__reserve_write_pipe";
2650 else if (BuiltinID == Builtin::BIwork_group_reserve_read_pipe)
2651 Name = "__work_group_reserve_read_pipe";
2652 else if (BuiltinID == Builtin::BIwork_group_reserve_write_pipe)
2653 Name = "__work_group_reserve_write_pipe";
2654 else if (BuiltinID == Builtin::BIsub_group_reserve_read_pipe)
2655 Name = "__sub_group_reserve_read_pipe";
2656 else
2657 Name = "__sub_group_reserve_write_pipe";
2658
2659 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2660 *Arg1 = EmitScalarExpr(E->getArg(1));
2661 llvm::Type *ReservedIDTy = ConvertType(getContext().OCLReserveIDTy);
Alexey Bader465c1892016-09-23 14:20:00 +00002662 CGOpenCLRuntime OpenCLRT(CGM);
2663 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2664 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002665
2666 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002667 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002668 llvm::FunctionType *FTy = llvm::FunctionType::get(
2669 ReservedIDTy, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2670 // We know the second argument is an integer type, but we may need to cast
2671 // it to i32.
2672 if (Arg1->getType() != Int32Ty)
2673 Arg1 = Builder.CreateZExtOrTrunc(Arg1, Int32Ty);
2674 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002675 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2676 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002677 }
Anastasia Stulova7f8d6dc2016-07-04 16:07:18 +00002678 // OpenCL v2.0 s6.13.16, s9.17.3.5 - Built-in pipe commit read and write
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002679 // functions
2680 case Builtin::BIcommit_read_pipe:
2681 case Builtin::BIcommit_write_pipe:
2682 case Builtin::BIwork_group_commit_read_pipe:
2683 case Builtin::BIwork_group_commit_write_pipe:
2684 case Builtin::BIsub_group_commit_read_pipe:
2685 case Builtin::BIsub_group_commit_write_pipe: {
2686 const char *Name;
2687 if (BuiltinID == Builtin::BIcommit_read_pipe)
2688 Name = "__commit_read_pipe";
2689 else if (BuiltinID == Builtin::BIcommit_write_pipe)
2690 Name = "__commit_write_pipe";
2691 else if (BuiltinID == Builtin::BIwork_group_commit_read_pipe)
2692 Name = "__work_group_commit_read_pipe";
2693 else if (BuiltinID == Builtin::BIwork_group_commit_write_pipe)
2694 Name = "__work_group_commit_write_pipe";
2695 else if (BuiltinID == Builtin::BIsub_group_commit_read_pipe)
2696 Name = "__sub_group_commit_read_pipe";
2697 else
2698 Name = "__sub_group_commit_write_pipe";
2699
2700 Value *Arg0 = EmitScalarExpr(E->getArg(0)),
2701 *Arg1 = EmitScalarExpr(E->getArg(1));
Alexey Bader465c1892016-09-23 14:20:00 +00002702 CGOpenCLRuntime OpenCLRT(CGM);
2703 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2704 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002705
2706 // Building the generic function prototype.
Alexey Bader465c1892016-09-23 14:20:00 +00002707 llvm::Type *ArgTys[] = {Arg0->getType(), Arg1->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002708 llvm::FunctionType *FTy =
2709 llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()),
2710 llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2711
2712 return RValue::get(
Alexey Bader465c1892016-09-23 14:20:00 +00002713 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2714 {Arg0, Arg1, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002715 }
2716 // OpenCL v2.0 s6.13.16.4 Built-in pipe query functions
2717 case Builtin::BIget_pipe_num_packets:
2718 case Builtin::BIget_pipe_max_packets: {
2719 const char *Name;
2720 if (BuiltinID == Builtin::BIget_pipe_num_packets)
2721 Name = "__get_pipe_num_packets";
2722 else
2723 Name = "__get_pipe_max_packets";
2724
2725 // Building the generic function prototype.
2726 Value *Arg0 = EmitScalarExpr(E->getArg(0));
Alexey Bader465c1892016-09-23 14:20:00 +00002727 CGOpenCLRuntime OpenCLRT(CGM);
2728 Value *PacketSize = OpenCLRT.getPipeElemSize(E->getArg(0));
2729 Value *PacketAlign = OpenCLRT.getPipeElemAlign(E->getArg(0));
2730 llvm::Type *ArgTys[] = {Arg0->getType(), Int32Ty, Int32Ty};
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002731 llvm::FunctionType *FTy = llvm::FunctionType::get(
2732 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2733
Alexey Bader465c1892016-09-23 14:20:00 +00002734 return RValue::get(Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2735 {Arg0, PacketSize, PacketAlign}));
Xiuli Panbb4d8d32016-01-26 04:03:48 +00002736 }
2737
Yaxun Liuf7449a12016-05-20 19:54:38 +00002738 // OpenCL v2.0 s6.13.9 - Address space qualifier functions.
2739 case Builtin::BIto_global:
2740 case Builtin::BIto_local:
2741 case Builtin::BIto_private: {
2742 auto Arg0 = EmitScalarExpr(E->getArg(0));
2743 auto NewArgT = llvm::PointerType::get(Int8Ty,
2744 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
2745 auto NewRetT = llvm::PointerType::get(Int8Ty,
2746 CGM.getContext().getTargetAddressSpace(
2747 E->getType()->getPointeeType().getAddressSpace()));
2748 auto FTy = llvm::FunctionType::get(NewRetT, {NewArgT}, false);
2749 llvm::Value *NewArg;
2750 if (Arg0->getType()->getPointerAddressSpace() !=
2751 NewArgT->getPointerAddressSpace())
2752 NewArg = Builder.CreateAddrSpaceCast(Arg0, NewArgT);
2753 else
2754 NewArg = Builder.CreateBitOrPointerCast(Arg0, NewArgT);
Alexey Baderd81623262016-08-04 18:06:27 +00002755 auto NewName = std::string("__") + E->getDirectCallee()->getName().str();
2756 auto NewCall =
2757 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, NewName), {NewArg});
Yaxun Liuf7449a12016-05-20 19:54:38 +00002758 return RValue::get(Builder.CreateBitOrPointerCast(NewCall,
2759 ConvertType(E->getType())));
2760 }
2761
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002762 // OpenCL v2.0, s6.13.17 - Enqueue kernel function.
2763 // It contains four different overload formats specified in Table 6.13.17.1.
2764 case Builtin::BIenqueue_kernel: {
2765 StringRef Name; // Generated function call name
2766 unsigned NumArgs = E->getNumArgs();
2767
2768 llvm::Type *QueueTy = ConvertType(getContext().OCLQueueTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002769 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2770 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002771
2772 llvm::Value *Queue = EmitScalarExpr(E->getArg(0));
2773 llvm::Value *Flags = EmitScalarExpr(E->getArg(1));
Anastasia Stulova58984e72017-02-16 12:27:47 +00002774 LValue NDRangeL = EmitAggExprToLValue(E->getArg(2));
2775 llvm::Value *Range = NDRangeL.getAddress().getPointer();
2776 llvm::Type *RangeTy = NDRangeL.getAddress().getType();
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002777
2778 if (NumArgs == 4) {
2779 // The most basic form of the call with parameters:
2780 // queue_t, kernel_enqueue_flags_t, ndrange_t, block(void)
2781 Name = "__enqueue_kernel_basic";
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002782 llvm::Type *ArgTys[] = {QueueTy, Int32Ty, RangeTy, GenericVoidPtrTy,
2783 GenericVoidPtrTy};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002784 llvm::FunctionType *FTy = llvm::FunctionType::get(
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002785 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002786
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002787 auto Info =
2788 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3));
2789 llvm::Value *Kernel =
2790 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy);
2791 llvm::Value *Block =
2792 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002793
Anastasia Stulova58984e72017-02-16 12:27:47 +00002794 AttrBuilder B;
2795 B.addAttribute(Attribute::ByVal);
Reid Klecknerde864822017-03-21 16:57:30 +00002796 llvm::AttributeList ByValAttrSet =
2797 llvm::AttributeList::get(CGM.getModule().getContext(), 3U, B);
Anastasia Stulova58984e72017-02-16 12:27:47 +00002798
2799 auto RTCall =
2800 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name, ByValAttrSet),
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002801 {Queue, Flags, Range, Kernel, Block});
Anastasia Stulova58984e72017-02-16 12:27:47 +00002802 RTCall->setAttributes(ByValAttrSet);
2803 return RValue::get(RTCall);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002804 }
2805 assert(NumArgs >= 5 && "Invalid enqueue_kernel signature");
2806
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002807 // Create a temporary array to hold the sizes of local pointer arguments
2808 // for the block. \p First is the position of the first size argument.
2809 auto CreateArrayForSizeVar = [=](unsigned First) {
2810 auto *AT = llvm::ArrayType::get(SizeTy, NumArgs - First);
2811 auto *Arr = Builder.CreateAlloca(AT);
2812 llvm::Value *Ptr;
2813 // Each of the following arguments specifies the size of the corresponding
2814 // argument passed to the enqueued block.
2815 auto *Zero = llvm::ConstantInt::get(IntTy, 0);
2816 for (unsigned I = First; I < NumArgs; ++I) {
2817 auto *Index = llvm::ConstantInt::get(IntTy, I - First);
2818 auto *GEP = Builder.CreateGEP(Arr, {Zero, Index});
2819 if (I == First)
2820 Ptr = GEP;
2821 auto *V =
2822 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(I)), SizeTy);
2823 Builder.CreateAlignedStore(
2824 V, GEP, CGM.getDataLayout().getPrefTypeAlignment(SizeTy));
2825 }
2826 return Ptr;
2827 };
2828
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002829 // Could have events and/or vaargs.
2830 if (E->getArg(3)->getType()->isBlockPointerType()) {
2831 // No events passed, but has variadic arguments.
2832 Name = "__enqueue_kernel_vaargs";
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002833 auto Info =
2834 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(3));
2835 llvm::Value *Kernel =
2836 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy);
2837 auto *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002838 auto *PtrToSizeArray = CreateArrayForSizeVar(4);
2839
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002840 // Create a vector of the arguments, as well as a constant value to
2841 // express to the runtime the number of variadic arguments.
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002842 std::vector<llvm::Value *> Args = {
2843 Queue, Flags, Range,
2844 Kernel, Block, ConstantInt::get(IntTy, NumArgs - 4),
2845 PtrToSizeArray};
2846 std::vector<llvm::Type *> ArgTys = {
2847 QueueTy, IntTy, RangeTy,
2848 GenericVoidPtrTy, GenericVoidPtrTy, IntTy,
2849 PtrToSizeArray->getType()};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002850
2851 llvm::FunctionType *FTy = llvm::FunctionType::get(
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002852 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002853 return RValue::get(
2854 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2855 llvm::ArrayRef<llvm::Value *>(Args)));
2856 }
2857 // Any calls now have event arguments passed.
2858 if (NumArgs >= 7) {
2859 llvm::Type *EventTy = ConvertType(getContext().OCLClkEventTy);
Anastasia Stulova2b461202016-11-14 15:34:01 +00002860 llvm::Type *EventPtrTy = EventTy->getPointerTo(
2861 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002862
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002863 llvm::Value *NumEvents =
2864 Builder.CreateZExtOrTrunc(EmitScalarExpr(E->getArg(3)), Int32Ty);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002865 llvm::Value *EventList =
2866 E->getArg(4)->getType()->isArrayType()
2867 ? EmitArrayToPointerDecay(E->getArg(4)).getPointer()
2868 : EmitScalarExpr(E->getArg(4));
2869 llvm::Value *ClkEvent = EmitScalarExpr(E->getArg(5));
Anastasia Stulova2b461202016-11-14 15:34:01 +00002870 // Convert to generic address space.
2871 EventList = Builder.CreatePointerCast(EventList, EventPtrTy);
2872 ClkEvent = Builder.CreatePointerCast(ClkEvent, EventPtrTy);
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002873 auto Info =
2874 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(6));
2875 llvm::Value *Kernel =
2876 Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy);
2877 llvm::Value *Block =
2878 Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002879
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002880 std::vector<llvm::Type *> ArgTys = {
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002881 QueueTy, Int32Ty, RangeTy, Int32Ty,
2882 EventPtrTy, EventPtrTy, GenericVoidPtrTy, GenericVoidPtrTy};
Anastasia Stulova2b461202016-11-14 15:34:01 +00002883
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002884 std::vector<llvm::Value *> Args = {Queue, Flags, Range, NumEvents,
2885 EventList, ClkEvent, Kernel, Block};
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002886
2887 if (NumArgs == 7) {
2888 // Has events but no variadics.
2889 Name = "__enqueue_kernel_basic_events";
2890 llvm::FunctionType *FTy = llvm::FunctionType::get(
2891 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
2892 return RValue::get(
2893 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2894 llvm::ArrayRef<llvm::Value *>(Args)));
2895 }
2896 // Has event info and variadics
2897 // Pass the number of variadics to the runtime function too.
2898 Args.push_back(ConstantInt::get(Int32Ty, NumArgs - 7));
2899 ArgTys.push_back(Int32Ty);
2900 Name = "__enqueue_kernel_events_vaargs";
2901
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002902 auto *PtrToSizeArray = CreateArrayForSizeVar(7);
2903 Args.push_back(PtrToSizeArray);
2904 ArgTys.push_back(PtrToSizeArray->getType());
Anastasia Stulova0df4ac32016-11-14 17:39:58 +00002905
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002906 llvm::FunctionType *FTy = llvm::FunctionType::get(
Yaxun Liu29a5ee32017-09-03 13:52:24 +00002907 Int32Ty, llvm::ArrayRef<llvm::Type *>(ArgTys), false);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002908 return RValue::get(
2909 Builder.CreateCall(CGM.CreateRuntimeFunction(FTy, Name),
2910 llvm::ArrayRef<llvm::Value *>(Args)));
2911 }
Galina Kistanova0872d6c2017-06-03 06:30:46 +00002912 LLVM_FALLTHROUGH;
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002913 }
2914 // OpenCL v2.0 s6.13.17.6 - Kernel query functions need bitcast of block
2915 // parameter.
2916 case Builtin::BIget_kernel_work_group_size: {
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002917 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2918 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002919 auto Info =
2920 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0));
2921 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy);
2922 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002923 return RValue::get(Builder.CreateCall(
2924 CGM.CreateRuntimeFunction(
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002925 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy},
2926 false),
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002927 "__get_kernel_work_group_size_impl"),
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002928 {Kernel, Arg}));
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002929 }
2930 case Builtin::BIget_kernel_preferred_work_group_size_multiple: {
2931 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2932 getContext().getTargetAddressSpace(LangAS::opencl_generic));
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002933 auto Info =
2934 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(0));
2935 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy);
2936 Value *Arg = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
Anastasia Stulovaaf0a7bb2017-01-27 15:11:34 +00002937 return RValue::get(Builder.CreateCall(
2938 CGM.CreateRuntimeFunction(
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002939 llvm::FunctionType::get(IntTy, {GenericVoidPtrTy, GenericVoidPtrTy},
2940 false),
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002941 "__get_kernel_preferred_work_group_multiple_impl"),
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002942 {Kernel, Arg}));
Anastasia Stulovadb7a31c2016-07-05 11:31:24 +00002943 }
Joey Goulyfa76b492017-08-01 13:27:09 +00002944 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2945 case Builtin::BIget_kernel_sub_group_count_for_ndrange: {
2946 llvm::Type *GenericVoidPtrTy = Builder.getInt8PtrTy(
2947 getContext().getTargetAddressSpace(LangAS::opencl_generic));
2948 LValue NDRangeL = EmitAggExprToLValue(E->getArg(0));
2949 llvm::Value *NDRange = NDRangeL.getAddress().getPointer();
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002950 auto Info =
2951 CGM.getOpenCLRuntime().emitOpenCLEnqueuedBlock(*this, E->getArg(1));
2952 Value *Kernel = Builder.CreatePointerCast(Info.Kernel, GenericVoidPtrTy);
2953 Value *Block = Builder.CreatePointerCast(Info.BlockArg, GenericVoidPtrTy);
Joey Goulyfa76b492017-08-01 13:27:09 +00002954 const char *Name =
2955 BuiltinID == Builtin::BIget_kernel_max_sub_group_size_for_ndrange
2956 ? "__get_kernel_max_sub_group_size_for_ndrange_impl"
2957 : "__get_kernel_sub_group_count_for_ndrange_impl";
2958 return RValue::get(Builder.CreateCall(
2959 CGM.CreateRuntimeFunction(
2960 llvm::FunctionType::get(
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002961 IntTy, {NDRange->getType(), GenericVoidPtrTy, GenericVoidPtrTy},
2962 false),
Joey Goulyfa76b492017-08-01 13:27:09 +00002963 Name),
Yaxun Liuc2a87a02017-10-14 12:23:50 +00002964 {NDRange, Kernel, Block}));
Joey Goulyfa76b492017-08-01 13:27:09 +00002965 }
Jan Vesely31ecb4b2017-09-07 19:39:10 +00002966
2967 case Builtin::BI__builtin_store_half:
2968 case Builtin::BI__builtin_store_halff: {
2969 Value *Val = EmitScalarExpr(E->getArg(0));
2970 Address Address = EmitPointerWithAlignment(E->getArg(1));
2971 Value *HalfVal = Builder.CreateFPTrunc(Val, Builder.getHalfTy());
2972 return RValue::get(Builder.CreateStore(HalfVal, Address));
2973 }
2974 case Builtin::BI__builtin_load_half: {
2975 Address Address = EmitPointerWithAlignment(E->getArg(0));
2976 Value *HalfVal = Builder.CreateLoad(Address);
2977 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getDoubleTy()));
2978 }
2979 case Builtin::BI__builtin_load_halff: {
2980 Address Address = EmitPointerWithAlignment(E->getArg(0));
2981 Value *HalfVal = Builder.CreateLoad(Address);
2982 return RValue::get(Builder.CreateFPExt(HalfVal, Builder.getFloatTy()));
2983 }
Justin Lebar3039a592016-01-23 21:28:14 +00002984 case Builtin::BIprintf:
Arpith Chacko Jacobcdda3daa2017-01-29 20:49:31 +00002985 if (getTarget().getTriple().isNVPTX())
2986 return EmitNVPTXDevicePrintfCallExpr(E, ReturnValue);
Matt Arsenault2d933982016-02-27 09:06:18 +00002987 break;
2988 case Builtin::BI__builtin_canonicalize:
2989 case Builtin::BI__builtin_canonicalizef:
2990 case Builtin::BI__builtin_canonicalizel:
2991 return RValue::get(emitUnaryBuiltin(*this, E, Intrinsic::canonicalize));
Marcin Koscielnickia46fade2016-06-16 13:41:54 +00002992
2993 case Builtin::BI__builtin_thread_pointer: {
2994 if (!getContext().getTargetInfo().isTLSSupported())
2995 CGM.ErrorUnsupported(E, "__builtin_thread_pointer");
2996 // Fall through - it's already mapped to the intrinsic by GCCBuiltin.
2997 break;
2998 }
Akira Hatanaka6b103bc2017-10-06 07:12:46 +00002999 case Builtin::BI__builtin_os_log_format:
3000 return emitBuiltinOSLogFormat(*E);
Mehdi Amini06d367c2016-10-24 20:39:34 +00003001
3002 case Builtin::BI__builtin_os_log_format_buffer_size: {
3003 analyze_os_log::OSLogBufferLayout Layout;
3004 analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);
3005 return RValue::get(ConstantInt::get(ConvertType(E->getType()),
3006 Layout.size().getQuantity()));
3007 }
Dean Michael Berris42af6512017-05-09 00:45:40 +00003008
3009 case Builtin::BI__xray_customevent: {
3010 if (!ShouldXRayInstrumentFunction())
3011 return RValue::getIgnored();
3012 if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
3013 if (XRayAttr->neverXRayInstrument())
3014 return RValue::getIgnored();
3015 }
3016 Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
3017 auto FTy = F->getFunctionType();
3018 auto Arg0 = E->getArg(0);
3019 auto Arg0Val = EmitScalarExpr(Arg0);
3020 auto Arg0Ty = Arg0->getType();
3021 auto PTy0 = FTy->getParamType(0);
3022 if (PTy0 != Arg0Val->getType()) {
3023 if (Arg0Ty->isArrayType())
3024 Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer();
3025 else
3026 Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0);
3027 }
3028 auto Arg1 = EmitScalarExpr(E->getArg(1));
3029 auto PTy1 = FTy->getParamType(1);
3030 if (PTy1 != Arg1->getType())
3031 Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
3032 return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
3033 }
Martin Storsjo022e7822017-07-17 20:49:45 +00003034
3035 case Builtin::BI__builtin_ms_va_start:
3036 case Builtin::BI__builtin_ms_va_end:
3037 return RValue::get(
3038 EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(),
3039 BuiltinID == Builtin::BI__builtin_ms_va_start));
3040
3041 case Builtin::BI__builtin_ms_va_copy: {
3042 // Lower this manually. We can't reliably determine whether or not any
3043 // given va_copy() is for a Win64 va_list from the calling convention
3044 // alone, because it's legal to do this from a System V ABI function.
3045 // With opaque pointer types, we won't have enough information in LLVM
3046 // IR to determine this from the argument types, either. Best to do it
3047 // now, while we have enough information.
3048 Address DestAddr = EmitMSVAListRef(E->getArg(0));
3049 Address SrcAddr = EmitMSVAListRef(E->getArg(1));
3050
3051 llvm::Type *BPP = Int8PtrPtrTy;
3052
3053 DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"),
3054 DestAddr.getAlignment());
3055 SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"),
3056 SrcAddr.getAlignment());
3057
3058 Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val");
3059 return RValue::get(Builder.CreateStore(ArgPtr, DestAddr));
3060 }
Nate Begeman6c591322008-05-15 07:38:03 +00003061 }
Mike Stump11289f42009-09-09 15:08:12 +00003062
John McCall30e4efd2011-09-13 23:05:03 +00003063 // If this is an alias for a lib function (e.g. __builtin_sin), emit
3064 // the call using the normal call path, but using the unmangled
3065 // version of the function name.
3066 if (getContext().BuiltinInfo.isLibFunction(BuiltinID))
3067 return emitLibraryCall(*this, FD, E,
3068 CGM.getBuiltinLibFunction(FD, BuiltinID));
Jim Grosbachd3608f42012-09-21 00:18:27 +00003069
John McCall30e4efd2011-09-13 23:05:03 +00003070 // If this is a predefined lib function (e.g. malloc), emit the call
3071 // using exactly the normal call path.
3072 if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID))
John McCallb92ab1a2016-10-26 23:46:34 +00003073 return emitLibraryCall(*this, FD, E,
3074 cast<llvm::Constant>(EmitScalarExpr(E->getCallee())));
Mike Stump11289f42009-09-09 15:08:12 +00003075
Eric Christopher15709992015-10-15 23:47:11 +00003076 // Check that a call to a target specific builtin has the correct target
3077 // features.
3078 // This is down here to avoid non-target specific builtins, however, if
3079 // generic builtins start to require generic target features then we
3080 // can move this up to the beginning of the function.
Eric Christopherc7e79db2015-11-12 00:44:04 +00003081 checkTargetFeatures(E, FD);
Eric Christopher15709992015-10-15 23:47:11 +00003082
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003083 // See if we have a target specific intrinsic.
Mehdi Amini7186a432016-10-11 19:04:24 +00003084 const char *Name = getContext().BuiltinInfo.getName(BuiltinID);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003085 Intrinsic::ID IntrinsicID = Intrinsic::not_intrinsic;
Mehdi Aminib7fb1242016-10-01 01:16:22 +00003086 StringRef Prefix =
3087 llvm::Triple::getArchTypePrefix(getTarget().getTriple().getArch());
3088 if (!Prefix.empty()) {
3089 IntrinsicID = Intrinsic::getIntrinsicForGCCBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00003090 // NOTE we dont need to perform a compatibility flag check here since the
3091 // intrinsics are declared in Builtins*.def via LANGBUILTIN which filter the
3092 // MS builtins via ALL_MS_LANGUAGES and are filtered earlier.
3093 if (IntrinsicID == Intrinsic::not_intrinsic)
Mehdi Aminib7fb1242016-10-01 01:16:22 +00003094 IntrinsicID = Intrinsic::getIntrinsicForMSBuiltin(Prefix.data(), Name);
Saleem Abdulrasool96bfda82014-07-04 21:49:39 +00003095 }
Mike Stump11289f42009-09-09 15:08:12 +00003096
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003097 if (IntrinsicID != Intrinsic::not_intrinsic) {
3098 SmallVector<Value*, 16> Args;
Mike Stump11289f42009-09-09 15:08:12 +00003099
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003100 // Find out if any arguments are required to be integer constant
3101 // expressions.
3102 unsigned ICEArguments = 0;
3103 ASTContext::GetBuiltinTypeError Error;
3104 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
3105 assert(Error == ASTContext::GE_None && "Should not codegen an error");
3106
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003107 Function *F = CGM.getIntrinsic(IntrinsicID);
Chris Lattner2192fe52011-07-18 04:24:23 +00003108 llvm::FunctionType *FTy = F->getFunctionType();
Mike Stump11289f42009-09-09 15:08:12 +00003109
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003110 for (unsigned i = 0, e = E->getNumArgs(); i != e; ++i) {
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003111 Value *ArgValue;
3112 // If this is a normal argument, just emit it as a scalar.
3113 if ((ICEArguments & (1 << i)) == 0) {
3114 ArgValue = EmitScalarExpr(E->getArg(i));
3115 } else {
Jim Grosbachd3608f42012-09-21 00:18:27 +00003116 // If this is required to be a constant, constant fold it so that we
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003117 // know that the generated intrinsic gets a ConstantInt.
3118 llvm::APSInt Result;
3119 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result,getContext());
3120 assert(IsConst && "Constant arg isn't actually constant?");
3121 (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00003122 ArgValue = llvm::ConstantInt::get(getLLVMContext(), Result);
Chris Lattner64d7f2a2010-10-02 00:09:12 +00003123 }
Mike Stump11289f42009-09-09 15:08:12 +00003124
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003125 // If the intrinsic arg type is different from the builtin arg type
3126 // we need to do a bit cast.
Chris Lattner2192fe52011-07-18 04:24:23 +00003127 llvm::Type *PTy = FTy->getParamType(i);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003128 if (PTy != ArgValue->getType()) {
3129 assert(PTy->canLosslesslyBitCastTo(FTy->getParamType(i)) &&
3130 "Must be able to losslessly bit cast to param");
3131 ArgValue = Builder.CreateBitCast(ArgValue, PTy);
3132 }
Mike Stump11289f42009-09-09 15:08:12 +00003133
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003134 Args.push_back(ArgValue);
3135 }
Mike Stump11289f42009-09-09 15:08:12 +00003136
Jay Foad5bd375a2011-07-15 08:37:34 +00003137 Value *V = Builder.CreateCall(F, Args);
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003138 QualType BuiltinRetType = E->getType();
Mike Stump11289f42009-09-09 15:08:12 +00003139
Chris Lattnerece04092012-02-07 00:39:47 +00003140 llvm::Type *RetTy = VoidTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00003141 if (!BuiltinRetType->isVoidType())
Chris Lattnerece04092012-02-07 00:39:47 +00003142 RetTy = ConvertType(BuiltinRetType);
Mike Stump11289f42009-09-09 15:08:12 +00003143
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003144 if (RetTy != V->getType()) {
3145 assert(V->getType()->canLosslesslyBitCastTo(RetTy) &&
3146 "Must be able to losslessly bit cast result type");
3147 V = Builder.CreateBitCast(V, RetTy);
3148 }
Mike Stump11289f42009-09-09 15:08:12 +00003149
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003150 return RValue::get(V);
3151 }
Mike Stump11289f42009-09-09 15:08:12 +00003152
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003153 // See if we have a target specific builtin that needs to be lowered.
Daniel Dunbareca513d2008-10-10 00:24:54 +00003154 if (Value *V = EmitTargetBuiltinExpr(BuiltinID, E))
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003155 return RValue::get(V);
Mike Stump11289f42009-09-09 15:08:12 +00003156
Daniel Dunbara7c8cf62008-08-16 00:56:44 +00003157 ErrorUnsupported(E, "builtin function");
Mike Stump11289f42009-09-09 15:08:12 +00003158
Chris Lattner9a8d1d92008-06-30 18:32:54 +00003159 // Unknown builtin, for now just dump it out and return undef.
John McCall47fb9502013-03-07 21:37:08 +00003160 return GetUndefRValue(E->getType());
Mike Stump11289f42009-09-09 15:08:12 +00003161}
Anders Carlsson895af082007-12-09 23:17:02 +00003162
Artem Belevichb5bc9232015-09-22 17:23:22 +00003163static Value *EmitTargetArchBuiltinExpr(CodeGenFunction *CGF,
3164 unsigned BuiltinID, const CallExpr *E,
3165 llvm::Triple::ArchType Arch) {
3166 switch (Arch) {
Chris Lattner5cc15e02010-03-03 19:03:45 +00003167 case llvm::Triple::arm:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003168 case llvm::Triple::armeb:
Chris Lattner5cc15e02010-03-03 19:03:45 +00003169 case llvm::Triple::thumb:
Christian Pirkerf01cd6f2014-03-28 14:40:46 +00003170 case llvm::Triple::thumbeb:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003171 return CGF->EmitARMBuiltinExpr(BuiltinID, E);
Tim Northover25e8a672014-05-24 12:51:25 +00003172 case llvm::Triple::aarch64:
3173 case llvm::Triple::aarch64_be:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003174 return CGF->EmitAArch64BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003175 case llvm::Triple::x86:
3176 case llvm::Triple::x86_64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003177 return CGF->EmitX86BuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003178 case llvm::Triple::ppc:
3179 case llvm::Triple::ppc64:
Bill Schmidt778d3872013-07-26 01:36:11 +00003180 case llvm::Triple::ppc64le:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003181 return CGF->EmitPPCBuiltinExpr(BuiltinID, E);
Matt Arsenault56f008d2014-06-24 20:45:01 +00003182 case llvm::Triple::r600:
Tom Stellardd8e38a32015-01-06 20:34:47 +00003183 case llvm::Triple::amdgcn:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003184 return CGF->EmitAMDGPUBuiltinExpr(BuiltinID, E);
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00003185 case llvm::Triple::systemz:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003186 return CGF->EmitSystemZBuiltinExpr(BuiltinID, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00003187 case llvm::Triple::nvptx:
3188 case llvm::Triple::nvptx64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003189 return CGF->EmitNVPTXBuiltinExpr(BuiltinID, E);
Dan Gohmanc2853072015-09-03 22:51:53 +00003190 case llvm::Triple::wasm32:
3191 case llvm::Triple::wasm64:
Artem Belevichb5bc9232015-09-22 17:23:22 +00003192 return CGF->EmitWebAssemblyBuiltinExpr(BuiltinID, E);
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003193 default:
Craig Topper8a13c412014-05-21 05:09:00 +00003194 return nullptr;
Daniel Dunbar576d90d2009-08-24 09:54:37 +00003195 }
Daniel Dunbareca513d2008-10-10 00:24:54 +00003196}
3197
Artem Belevichb5bc9232015-09-22 17:23:22 +00003198Value *CodeGenFunction::EmitTargetBuiltinExpr(unsigned BuiltinID,
3199 const CallExpr *E) {
3200 if (getContext().BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3201 assert(getContext().getAuxTargetInfo() && "Missing aux target info");
3202 return EmitTargetArchBuiltinExpr(
3203 this, getContext().BuiltinInfo.getAuxBuiltinID(BuiltinID), E,
3204 getContext().getAuxTargetInfo()->getTriple().getArch());
3205 }
3206
3207 return EmitTargetArchBuiltinExpr(this, BuiltinID, E,
3208 getTarget().getTriple().getArch());
3209}
3210
Chris Lattnerece04092012-02-07 00:39:47 +00003211static llvm::VectorType *GetNeonType(CodeGenFunction *CGF,
Jiangning Liu036f16d2013-09-24 02:48:06 +00003212 NeonTypeFlags TypeFlags,
3213 bool V1Ty=false) {
NAKAMURA Takumidabda6b2011-11-08 03:27:04 +00003214 int IsQuad = TypeFlags.isQuad();
3215 switch (TypeFlags.getEltType()) {
Bob Wilson98bc98c2011-11-08 01:16:11 +00003216 case NeonTypeFlags::Int8:
3217 case NeonTypeFlags::Poly8:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003218 return llvm::VectorType::get(CGF->Int8Ty, V1Ty ? 1 : (8 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003219 case NeonTypeFlags::Int16:
3220 case NeonTypeFlags::Poly16:
Abderrazek Zaafranif10ca932017-06-20 18:54:57 +00003221 case NeonTypeFlags::Float16:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00003222 return llvm::VectorType::get(CGF->Int16Ty, V1Ty ? 1 : (4 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003223 case NeonTypeFlags::Int32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003224 return llvm::VectorType::get(CGF->Int32Ty, V1Ty ? 1 : (2 << IsQuad));
Bob Wilson98bc98c2011-11-08 01:16:11 +00003225 case NeonTypeFlags::Int64:
Kevin Qincaac85e2013-11-14 03:29:16 +00003226 case NeonTypeFlags::Poly64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003227 return llvm::VectorType::get(CGF->Int64Ty, V1Ty ? 1 : (1 << IsQuad));
Kevin Qinfb79d7f2013-12-10 06:49:01 +00003228 case NeonTypeFlags::Poly128:
3229 // FIXME: i128 and f128 doesn't get fully support in Clang and llvm.
3230 // There is a lot of i128 and f128 API missing.
3231 // so we use v16i8 to represent poly128 and get pattern matched.
3232 return llvm::VectorType::get(CGF->Int8Ty, 16);
Bob Wilson98bc98c2011-11-08 01:16:11 +00003233 case NeonTypeFlags::Float32:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003234 return llvm::VectorType::get(CGF->FloatTy, V1Ty ? 1 : (2 << IsQuad));
Tim Northover2fe823a2013-08-01 09:23:19 +00003235 case NeonTypeFlags::Float64:
Jiangning Liu036f16d2013-09-24 02:48:06 +00003236 return llvm::VectorType::get(CGF->DoubleTy, V1Ty ? 1 : (1 << IsQuad));
David Blaikief47fa302012-01-17 02:30:50 +00003237 }
Benjamin Kramer9b1dfe82013-09-26 16:36:08 +00003238 llvm_unreachable("Unknown vector element type!");
Nate Begeman5968eb22010-06-07 16:01:56 +00003239}
3240
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00003241static llvm::VectorType *GetFloatNeonType(CodeGenFunction *CGF,
3242 NeonTypeFlags IntTypeFlags) {
3243 int IsQuad = IntTypeFlags.isQuad();
3244 switch (IntTypeFlags.getEltType()) {
3245 case NeonTypeFlags::Int32:
3246 return llvm::VectorType::get(CGF->FloatTy, (2 << IsQuad));
3247 case NeonTypeFlags::Int64:
3248 return llvm::VectorType::get(CGF->DoubleTy, (1 << IsQuad));
3249 default:
3250 llvm_unreachable("Type can't be converted to floating-point!");
3251 }
3252}
3253
Bob Wilson210f6dd2010-12-07 22:40:02 +00003254Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) {
Craig Topperf2f1a092016-07-08 02:17:35 +00003255 unsigned nElts = V->getType()->getVectorNumElements();
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003256 Value* SV = llvm::ConstantVector::getSplat(nElts, C);
Nate Begeman4a04b462010-06-10 00:17:56 +00003257 return Builder.CreateShuffleVector(V, V, SV, "lane");
3258}
3259
Nate Begemanae6b1d82010-06-08 06:03:01 +00003260Value *CodeGenFunction::EmitNeonCall(Function *F, SmallVectorImpl<Value*> &Ops,
Bob Wilson482afae2010-12-08 22:37:56 +00003261 const char *name,
Nate Begeman91e1fea2010-06-14 05:21:25 +00003262 unsigned shift, bool rightshift) {
Nate Begemanae6b1d82010-06-08 06:03:01 +00003263 unsigned j = 0;
3264 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3265 ai != ae; ++ai, ++j)
Nate Begeman91e1fea2010-06-14 05:21:25 +00003266 if (shift > 0 && shift == j)
3267 Ops[j] = EmitNeonShiftVector(Ops[j], ai->getType(), rightshift);
3268 else
3269 Ops[j] = Builder.CreateBitCast(Ops[j], ai->getType(), name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003270
Jay Foad5bd375a2011-07-15 08:37:34 +00003271 return Builder.CreateCall(F, Ops, name);
Nate Begemanae6b1d82010-06-08 06:03:01 +00003272}
3273
Jim Grosbachd3608f42012-09-21 00:18:27 +00003274Value *CodeGenFunction::EmitNeonShiftVector(Value *V, llvm::Type *Ty,
Nate Begeman8ed060b2010-06-11 22:57:12 +00003275 bool neg) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00003276 int SV = cast<ConstantInt>(V)->getSExtValue();
Benjamin Kramerc385a802015-07-28 15:40:11 +00003277 return ConstantInt::get(Ty, neg ? -SV : SV);
Nate Begeman8ed060b2010-06-11 22:57:12 +00003278}
3279
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003280// \brief Right-shift a vector by a constant.
3281Value *CodeGenFunction::EmitNeonRShiftImm(Value *Vec, Value *Shift,
3282 llvm::Type *Ty, bool usgn,
3283 const char *name) {
3284 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
3285
3286 int ShiftAmt = cast<ConstantInt>(Shift)->getSExtValue();
3287 int EltSize = VTy->getScalarSizeInBits();
3288
3289 Vec = Builder.CreateBitCast(Vec, Ty);
3290
3291 // lshr/ashr are undefined when the shift amount is equal to the vector
3292 // element size.
3293 if (ShiftAmt == EltSize) {
3294 if (usgn) {
3295 // Right-shifting an unsigned value by its size yields 0.
Benjamin Kramerc385a802015-07-28 15:40:11 +00003296 return llvm::ConstantAggregateZero::get(VTy);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00003297 } else {
3298 // Right-shifting a signed value by its size is equivalent
3299 // to a shift of size-1.
3300 --ShiftAmt;
3301 Shift = ConstantInt::get(VTy->getElementType(), ShiftAmt);
3302 }
3303 }
3304
3305 Shift = EmitNeonShiftVector(Shift, Ty, false);
3306 if (usgn)
3307 return Builder.CreateLShr(Vec, Shift, name);
3308 else
3309 return Builder.CreateAShr(Vec, Shift, name);
3310}
3311
Tim Northover2d837962014-02-21 11:57:20 +00003312enum {
3313 AddRetType = (1 << 0),
3314 Add1ArgType = (1 << 1),
3315 Add2ArgTypes = (1 << 2),
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003316
Tim Northover2d837962014-02-21 11:57:20 +00003317 VectorizeRetType = (1 << 3),
3318 VectorizeArgTypes = (1 << 4),
3319
3320 InventFloatType = (1 << 5),
Tim Northover8fe03d62014-02-21 11:57:24 +00003321 UnsignedAlts = (1 << 6),
Tim Northover2d837962014-02-21 11:57:20 +00003322
Tim Northovera2ee4332014-03-29 15:09:45 +00003323 Use64BitVectors = (1 << 7),
3324 Use128BitVectors = (1 << 8),
3325
Tim Northover2d837962014-02-21 11:57:20 +00003326 Vectorize1ArgType = Add1ArgType | VectorizeArgTypes,
3327 VectorRet = AddRetType | VectorizeRetType,
3328 VectorRetGetArgs01 =
3329 AddRetType | Add2ArgTypes | VectorizeRetType | VectorizeArgTypes,
3330 FpCmpzModifiers =
Tim Northovera0c95eb2014-02-21 12:16:59 +00003331 AddRetType | VectorizeRetType | Add1ArgType | InventFloatType
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003332};
3333
Benjamin Kramere003ca22015-10-28 13:54:16 +00003334namespace {
3335struct NeonIntrinsicInfo {
Ben Craigcd7e9f12015-12-14 21:54:11 +00003336 const char *NameHint;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003337 unsigned BuiltinID;
3338 unsigned LLVMIntrinsic;
Tim Northover8fe03d62014-02-21 11:57:24 +00003339 unsigned AltLLVMIntrinsic;
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003340 unsigned TypeModifier;
3341
3342 bool operator<(unsigned RHSBuiltinID) const {
3343 return BuiltinID < RHSBuiltinID;
3344 }
Eric Christophered60b432015-11-11 02:04:08 +00003345 bool operator<(const NeonIntrinsicInfo &TE) const {
3346 return BuiltinID < TE.BuiltinID;
3347 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003348};
Benjamin Kramere003ca22015-10-28 13:54:16 +00003349} // end anonymous namespace
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003350
Tim Northover8fe03d62014-02-21 11:57:24 +00003351#define NEONMAP0(NameBase) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003352 { #NameBase, NEON::BI__builtin_neon_ ## NameBase, 0, 0, 0 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003353
Tim Northover8fe03d62014-02-21 11:57:24 +00003354#define NEONMAP1(NameBase, LLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003355 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
3356 Intrinsic::LLVMIntrinsic, 0, TypeModifier }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003357
Tim Northover8fe03d62014-02-21 11:57:24 +00003358#define NEONMAP2(NameBase, LLVMIntrinsic, AltLLVMIntrinsic, TypeModifier) \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003359 { #NameBase, NEON:: BI__builtin_neon_ ## NameBase, \
Tim Northover8fe03d62014-02-21 11:57:24 +00003360 Intrinsic::LLVMIntrinsic, Intrinsic::AltLLVMIntrinsic, \
Ben Craigcd7e9f12015-12-14 21:54:11 +00003361 TypeModifier }
Tim Northover8fe03d62014-02-21 11:57:24 +00003362
Craig Topper273dbc62015-10-18 05:29:26 +00003363static const NeonIntrinsicInfo ARMSIMDIntrinsicMap [] = {
Tim Northover8fe03d62014-02-21 11:57:24 +00003364 NEONMAP2(vabd_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3365 NEONMAP2(vabdq_v, arm_neon_vabdu, arm_neon_vabds, Add1ArgType | UnsignedAlts),
3366 NEONMAP1(vabs_v, arm_neon_vabs, 0),
3367 NEONMAP1(vabsq_v, arm_neon_vabs, 0),
3368 NEONMAP0(vaddhn_v),
3369 NEONMAP1(vaesdq_v, arm_neon_aesd, 0),
3370 NEONMAP1(vaeseq_v, arm_neon_aese, 0),
3371 NEONMAP1(vaesimcq_v, arm_neon_aesimc, 0),
3372 NEONMAP1(vaesmcq_v, arm_neon_aesmc, 0),
3373 NEONMAP1(vbsl_v, arm_neon_vbsl, AddRetType),
3374 NEONMAP1(vbslq_v, arm_neon_vbsl, AddRetType),
3375 NEONMAP1(vcage_v, arm_neon_vacge, 0),
3376 NEONMAP1(vcageq_v, arm_neon_vacge, 0),
3377 NEONMAP1(vcagt_v, arm_neon_vacgt, 0),
3378 NEONMAP1(vcagtq_v, arm_neon_vacgt, 0),
3379 NEONMAP1(vcale_v, arm_neon_vacge, 0),
3380 NEONMAP1(vcaleq_v, arm_neon_vacge, 0),
3381 NEONMAP1(vcalt_v, arm_neon_vacgt, 0),
3382 NEONMAP1(vcaltq_v, arm_neon_vacgt, 0),
3383 NEONMAP1(vcls_v, arm_neon_vcls, Add1ArgType),
3384 NEONMAP1(vclsq_v, arm_neon_vcls, Add1ArgType),
3385 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3386 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3387 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3388 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003389 NEONMAP1(vcvt_f16_f32, arm_neon_vcvtfp2hf, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003390 NEONMAP1(vcvt_f32_f16, arm_neon_vcvthf2fp, 0),
3391 NEONMAP0(vcvt_f32_v),
3392 NEONMAP2(vcvt_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3393 NEONMAP1(vcvt_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3394 NEONMAP1(vcvt_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3395 NEONMAP1(vcvt_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3396 NEONMAP1(vcvt_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3397 NEONMAP0(vcvt_s32_v),
3398 NEONMAP0(vcvt_s64_v),
3399 NEONMAP0(vcvt_u32_v),
3400 NEONMAP0(vcvt_u64_v),
3401 NEONMAP1(vcvta_s32_v, arm_neon_vcvtas, 0),
3402 NEONMAP1(vcvta_s64_v, arm_neon_vcvtas, 0),
3403 NEONMAP1(vcvta_u32_v, arm_neon_vcvtau, 0),
3404 NEONMAP1(vcvta_u64_v, arm_neon_vcvtau, 0),
3405 NEONMAP1(vcvtaq_s32_v, arm_neon_vcvtas, 0),
3406 NEONMAP1(vcvtaq_s64_v, arm_neon_vcvtas, 0),
3407 NEONMAP1(vcvtaq_u32_v, arm_neon_vcvtau, 0),
3408 NEONMAP1(vcvtaq_u64_v, arm_neon_vcvtau, 0),
3409 NEONMAP1(vcvtm_s32_v, arm_neon_vcvtms, 0),
3410 NEONMAP1(vcvtm_s64_v, arm_neon_vcvtms, 0),
3411 NEONMAP1(vcvtm_u32_v, arm_neon_vcvtmu, 0),
3412 NEONMAP1(vcvtm_u64_v, arm_neon_vcvtmu, 0),
3413 NEONMAP1(vcvtmq_s32_v, arm_neon_vcvtms, 0),
3414 NEONMAP1(vcvtmq_s64_v, arm_neon_vcvtms, 0),
3415 NEONMAP1(vcvtmq_u32_v, arm_neon_vcvtmu, 0),
3416 NEONMAP1(vcvtmq_u64_v, arm_neon_vcvtmu, 0),
3417 NEONMAP1(vcvtn_s32_v, arm_neon_vcvtns, 0),
3418 NEONMAP1(vcvtn_s64_v, arm_neon_vcvtns, 0),
3419 NEONMAP1(vcvtn_u32_v, arm_neon_vcvtnu, 0),
3420 NEONMAP1(vcvtn_u64_v, arm_neon_vcvtnu, 0),
3421 NEONMAP1(vcvtnq_s32_v, arm_neon_vcvtns, 0),
3422 NEONMAP1(vcvtnq_s64_v, arm_neon_vcvtns, 0),
3423 NEONMAP1(vcvtnq_u32_v, arm_neon_vcvtnu, 0),
3424 NEONMAP1(vcvtnq_u64_v, arm_neon_vcvtnu, 0),
3425 NEONMAP1(vcvtp_s32_v, arm_neon_vcvtps, 0),
3426 NEONMAP1(vcvtp_s64_v, arm_neon_vcvtps, 0),
3427 NEONMAP1(vcvtp_u32_v, arm_neon_vcvtpu, 0),
3428 NEONMAP1(vcvtp_u64_v, arm_neon_vcvtpu, 0),
3429 NEONMAP1(vcvtpq_s32_v, arm_neon_vcvtps, 0),
3430 NEONMAP1(vcvtpq_s64_v, arm_neon_vcvtps, 0),
3431 NEONMAP1(vcvtpq_u32_v, arm_neon_vcvtpu, 0),
3432 NEONMAP1(vcvtpq_u64_v, arm_neon_vcvtpu, 0),
3433 NEONMAP0(vcvtq_f32_v),
3434 NEONMAP2(vcvtq_n_f32_v, arm_neon_vcvtfxu2fp, arm_neon_vcvtfxs2fp, 0),
3435 NEONMAP1(vcvtq_n_s32_v, arm_neon_vcvtfp2fxs, 0),
3436 NEONMAP1(vcvtq_n_s64_v, arm_neon_vcvtfp2fxs, 0),
3437 NEONMAP1(vcvtq_n_u32_v, arm_neon_vcvtfp2fxu, 0),
3438 NEONMAP1(vcvtq_n_u64_v, arm_neon_vcvtfp2fxu, 0),
3439 NEONMAP0(vcvtq_s32_v),
3440 NEONMAP0(vcvtq_s64_v),
3441 NEONMAP0(vcvtq_u32_v),
3442 NEONMAP0(vcvtq_u64_v),
3443 NEONMAP0(vext_v),
3444 NEONMAP0(vextq_v),
3445 NEONMAP0(vfma_v),
3446 NEONMAP0(vfmaq_v),
3447 NEONMAP2(vhadd_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3448 NEONMAP2(vhaddq_v, arm_neon_vhaddu, arm_neon_vhadds, Add1ArgType | UnsignedAlts),
3449 NEONMAP2(vhsub_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3450 NEONMAP2(vhsubq_v, arm_neon_vhsubu, arm_neon_vhsubs, Add1ArgType | UnsignedAlts),
3451 NEONMAP0(vld1_dup_v),
3452 NEONMAP1(vld1_v, arm_neon_vld1, 0),
3453 NEONMAP0(vld1q_dup_v),
3454 NEONMAP1(vld1q_v, arm_neon_vld1, 0),
3455 NEONMAP1(vld2_lane_v, arm_neon_vld2lane, 0),
3456 NEONMAP1(vld2_v, arm_neon_vld2, 0),
3457 NEONMAP1(vld2q_lane_v, arm_neon_vld2lane, 0),
3458 NEONMAP1(vld2q_v, arm_neon_vld2, 0),
3459 NEONMAP1(vld3_lane_v, arm_neon_vld3lane, 0),
3460 NEONMAP1(vld3_v, arm_neon_vld3, 0),
3461 NEONMAP1(vld3q_lane_v, arm_neon_vld3lane, 0),
3462 NEONMAP1(vld3q_v, arm_neon_vld3, 0),
3463 NEONMAP1(vld4_lane_v, arm_neon_vld4lane, 0),
3464 NEONMAP1(vld4_v, arm_neon_vld4, 0),
3465 NEONMAP1(vld4q_lane_v, arm_neon_vld4lane, 0),
3466 NEONMAP1(vld4q_v, arm_neon_vld4, 0),
3467 NEONMAP2(vmax_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003468 NEONMAP1(vmaxnm_v, arm_neon_vmaxnm, Add1ArgType),
3469 NEONMAP1(vmaxnmq_v, arm_neon_vmaxnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003470 NEONMAP2(vmaxq_v, arm_neon_vmaxu, arm_neon_vmaxs, Add1ArgType | UnsignedAlts),
3471 NEONMAP2(vmin_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003472 NEONMAP1(vminnm_v, arm_neon_vminnm, Add1ArgType),
3473 NEONMAP1(vminnmq_v, arm_neon_vminnm, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003474 NEONMAP2(vminq_v, arm_neon_vminu, arm_neon_vmins, Add1ArgType | UnsignedAlts),
3475 NEONMAP0(vmovl_v),
3476 NEONMAP0(vmovn_v),
3477 NEONMAP1(vmul_v, arm_neon_vmulp, Add1ArgType),
3478 NEONMAP0(vmull_v),
3479 NEONMAP1(vmulq_v, arm_neon_vmulp, Add1ArgType),
3480 NEONMAP2(vpadal_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3481 NEONMAP2(vpadalq_v, arm_neon_vpadalu, arm_neon_vpadals, UnsignedAlts),
3482 NEONMAP1(vpadd_v, arm_neon_vpadd, Add1ArgType),
3483 NEONMAP2(vpaddl_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3484 NEONMAP2(vpaddlq_v, arm_neon_vpaddlu, arm_neon_vpaddls, UnsignedAlts),
3485 NEONMAP1(vpaddq_v, arm_neon_vpadd, Add1ArgType),
3486 NEONMAP2(vpmax_v, arm_neon_vpmaxu, arm_neon_vpmaxs, Add1ArgType | UnsignedAlts),
3487 NEONMAP2(vpmin_v, arm_neon_vpminu, arm_neon_vpmins, Add1ArgType | UnsignedAlts),
3488 NEONMAP1(vqabs_v, arm_neon_vqabs, Add1ArgType),
3489 NEONMAP1(vqabsq_v, arm_neon_vqabs, Add1ArgType),
3490 NEONMAP2(vqadd_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3491 NEONMAP2(vqaddq_v, arm_neon_vqaddu, arm_neon_vqadds, Add1ArgType | UnsignedAlts),
3492 NEONMAP2(vqdmlal_v, arm_neon_vqdmull, arm_neon_vqadds, 0),
3493 NEONMAP2(vqdmlsl_v, arm_neon_vqdmull, arm_neon_vqsubs, 0),
3494 NEONMAP1(vqdmulh_v, arm_neon_vqdmulh, Add1ArgType),
3495 NEONMAP1(vqdmulhq_v, arm_neon_vqdmulh, Add1ArgType),
3496 NEONMAP1(vqdmull_v, arm_neon_vqdmull, Add1ArgType),
3497 NEONMAP2(vqmovn_v, arm_neon_vqmovnu, arm_neon_vqmovns, Add1ArgType | UnsignedAlts),
3498 NEONMAP1(vqmovun_v, arm_neon_vqmovnsu, Add1ArgType),
3499 NEONMAP1(vqneg_v, arm_neon_vqneg, Add1ArgType),
3500 NEONMAP1(vqnegq_v, arm_neon_vqneg, Add1ArgType),
3501 NEONMAP1(vqrdmulh_v, arm_neon_vqrdmulh, Add1ArgType),
3502 NEONMAP1(vqrdmulhq_v, arm_neon_vqrdmulh, Add1ArgType),
3503 NEONMAP2(vqrshl_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3504 NEONMAP2(vqrshlq_v, arm_neon_vqrshiftu, arm_neon_vqrshifts, Add1ArgType | UnsignedAlts),
3505 NEONMAP2(vqshl_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3506 NEONMAP2(vqshl_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
3507 NEONMAP2(vqshlq_n_v, arm_neon_vqshiftu, arm_neon_vqshifts, UnsignedAlts),
3508 NEONMAP2(vqshlq_v, arm_neon_vqshiftu, arm_neon_vqshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003509 NEONMAP1(vqshlu_n_v, arm_neon_vqshiftsu, 0),
3510 NEONMAP1(vqshluq_n_v, arm_neon_vqshiftsu, 0),
Tim Northover8fe03d62014-02-21 11:57:24 +00003511 NEONMAP2(vqsub_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3512 NEONMAP2(vqsubq_v, arm_neon_vqsubu, arm_neon_vqsubs, Add1ArgType | UnsignedAlts),
3513 NEONMAP1(vraddhn_v, arm_neon_vraddhn, Add1ArgType),
3514 NEONMAP2(vrecpe_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3515 NEONMAP2(vrecpeq_v, arm_neon_vrecpe, arm_neon_vrecpe, 0),
3516 NEONMAP1(vrecps_v, arm_neon_vrecps, Add1ArgType),
3517 NEONMAP1(vrecpsq_v, arm_neon_vrecps, Add1ArgType),
3518 NEONMAP2(vrhadd_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
3519 NEONMAP2(vrhaddq_v, arm_neon_vrhaddu, arm_neon_vrhadds, Add1ArgType | UnsignedAlts),
James Molloy163b1ba2014-09-05 13:50:34 +00003520 NEONMAP1(vrnd_v, arm_neon_vrintz, Add1ArgType),
3521 NEONMAP1(vrnda_v, arm_neon_vrinta, Add1ArgType),
3522 NEONMAP1(vrndaq_v, arm_neon_vrinta, Add1ArgType),
3523 NEONMAP1(vrndm_v, arm_neon_vrintm, Add1ArgType),
3524 NEONMAP1(vrndmq_v, arm_neon_vrintm, Add1ArgType),
3525 NEONMAP1(vrndn_v, arm_neon_vrintn, Add1ArgType),
3526 NEONMAP1(vrndnq_v, arm_neon_vrintn, Add1ArgType),
3527 NEONMAP1(vrndp_v, arm_neon_vrintp, Add1ArgType),
3528 NEONMAP1(vrndpq_v, arm_neon_vrintp, Add1ArgType),
3529 NEONMAP1(vrndq_v, arm_neon_vrintz, Add1ArgType),
3530 NEONMAP1(vrndx_v, arm_neon_vrintx, Add1ArgType),
3531 NEONMAP1(vrndxq_v, arm_neon_vrintx, Add1ArgType),
Tim Northover8fe03d62014-02-21 11:57:24 +00003532 NEONMAP2(vrshl_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
3533 NEONMAP2(vrshlq_v, arm_neon_vrshiftu, arm_neon_vrshifts, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003534 NEONMAP2(vrshr_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
3535 NEONMAP2(vrshrq_n_v, arm_neon_vrshiftu, arm_neon_vrshifts, UnsignedAlts),
Tim Northover8fe03d62014-02-21 11:57:24 +00003536 NEONMAP2(vrsqrte_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3537 NEONMAP2(vrsqrteq_v, arm_neon_vrsqrte, arm_neon_vrsqrte, 0),
3538 NEONMAP1(vrsqrts_v, arm_neon_vrsqrts, Add1ArgType),
3539 NEONMAP1(vrsqrtsq_v, arm_neon_vrsqrts, Add1ArgType),
3540 NEONMAP1(vrsubhn_v, arm_neon_vrsubhn, Add1ArgType),
3541 NEONMAP1(vsha1su0q_v, arm_neon_sha1su0, 0),
3542 NEONMAP1(vsha1su1q_v, arm_neon_sha1su1, 0),
3543 NEONMAP1(vsha256h2q_v, arm_neon_sha256h2, 0),
3544 NEONMAP1(vsha256hq_v, arm_neon_sha256h, 0),
3545 NEONMAP1(vsha256su0q_v, arm_neon_sha256su0, 0),
3546 NEONMAP1(vsha256su1q_v, arm_neon_sha256su1, 0),
3547 NEONMAP0(vshl_n_v),
3548 NEONMAP2(vshl_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3549 NEONMAP0(vshll_n_v),
3550 NEONMAP0(vshlq_n_v),
3551 NEONMAP2(vshlq_v, arm_neon_vshiftu, arm_neon_vshifts, Add1ArgType | UnsignedAlts),
3552 NEONMAP0(vshr_n_v),
3553 NEONMAP0(vshrn_n_v),
3554 NEONMAP0(vshrq_n_v),
3555 NEONMAP1(vst1_v, arm_neon_vst1, 0),
3556 NEONMAP1(vst1q_v, arm_neon_vst1, 0),
3557 NEONMAP1(vst2_lane_v, arm_neon_vst2lane, 0),
3558 NEONMAP1(vst2_v, arm_neon_vst2, 0),
3559 NEONMAP1(vst2q_lane_v, arm_neon_vst2lane, 0),
3560 NEONMAP1(vst2q_v, arm_neon_vst2, 0),
3561 NEONMAP1(vst3_lane_v, arm_neon_vst3lane, 0),
3562 NEONMAP1(vst3_v, arm_neon_vst3, 0),
3563 NEONMAP1(vst3q_lane_v, arm_neon_vst3lane, 0),
3564 NEONMAP1(vst3q_v, arm_neon_vst3, 0),
3565 NEONMAP1(vst4_lane_v, arm_neon_vst4lane, 0),
3566 NEONMAP1(vst4_v, arm_neon_vst4, 0),
3567 NEONMAP1(vst4q_lane_v, arm_neon_vst4lane, 0),
3568 NEONMAP1(vst4q_v, arm_neon_vst4, 0),
3569 NEONMAP0(vsubhn_v),
3570 NEONMAP0(vtrn_v),
3571 NEONMAP0(vtrnq_v),
3572 NEONMAP0(vtst_v),
3573 NEONMAP0(vtstq_v),
3574 NEONMAP0(vuzp_v),
3575 NEONMAP0(vuzpq_v),
3576 NEONMAP0(vzip_v),
Tim Northovera0c95eb2014-02-21 12:16:59 +00003577 NEONMAP0(vzipq_v)
Tim Northover8fe03d62014-02-21 11:57:24 +00003578};
3579
Craig Topper273dbc62015-10-18 05:29:26 +00003580static const NeonIntrinsicInfo AArch64SIMDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003581 NEONMAP1(vabs_v, aarch64_neon_abs, 0),
3582 NEONMAP1(vabsq_v, aarch64_neon_abs, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003583 NEONMAP0(vaddhn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003584 NEONMAP1(vaesdq_v, aarch64_crypto_aesd, 0),
3585 NEONMAP1(vaeseq_v, aarch64_crypto_aese, 0),
3586 NEONMAP1(vaesimcq_v, aarch64_crypto_aesimc, 0),
3587 NEONMAP1(vaesmcq_v, aarch64_crypto_aesmc, 0),
3588 NEONMAP1(vcage_v, aarch64_neon_facge, 0),
3589 NEONMAP1(vcageq_v, aarch64_neon_facge, 0),
3590 NEONMAP1(vcagt_v, aarch64_neon_facgt, 0),
3591 NEONMAP1(vcagtq_v, aarch64_neon_facgt, 0),
3592 NEONMAP1(vcale_v, aarch64_neon_facge, 0),
3593 NEONMAP1(vcaleq_v, aarch64_neon_facge, 0),
3594 NEONMAP1(vcalt_v, aarch64_neon_facgt, 0),
3595 NEONMAP1(vcaltq_v, aarch64_neon_facgt, 0),
3596 NEONMAP1(vcls_v, aarch64_neon_cls, Add1ArgType),
3597 NEONMAP1(vclsq_v, aarch64_neon_cls, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003598 NEONMAP1(vclz_v, ctlz, Add1ArgType),
3599 NEONMAP1(vclzq_v, ctlz, Add1ArgType),
3600 NEONMAP1(vcnt_v, ctpop, Add1ArgType),
3601 NEONMAP1(vcntq_v, ctpop, Add1ArgType),
Ahmed Bougachacd5b8a02015-08-21 23:34:20 +00003602 NEONMAP1(vcvt_f16_f32, aarch64_neon_vcvtfp2hf, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003603 NEONMAP1(vcvt_f32_f16, aarch64_neon_vcvthf2fp, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003604 NEONMAP0(vcvt_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003605 NEONMAP2(vcvt_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3606 NEONMAP2(vcvt_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3607 NEONMAP1(vcvt_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3608 NEONMAP1(vcvt_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3609 NEONMAP1(vcvt_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3610 NEONMAP1(vcvt_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003611 NEONMAP0(vcvtq_f32_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003612 NEONMAP2(vcvtq_n_f32_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3613 NEONMAP2(vcvtq_n_f64_v, aarch64_neon_vcvtfxu2fp, aarch64_neon_vcvtfxs2fp, 0),
3614 NEONMAP1(vcvtq_n_s32_v, aarch64_neon_vcvtfp2fxs, 0),
3615 NEONMAP1(vcvtq_n_s64_v, aarch64_neon_vcvtfp2fxs, 0),
3616 NEONMAP1(vcvtq_n_u32_v, aarch64_neon_vcvtfp2fxu, 0),
3617 NEONMAP1(vcvtq_n_u64_v, aarch64_neon_vcvtfp2fxu, 0),
3618 NEONMAP1(vcvtx_f32_v, aarch64_neon_fcvtxn, AddRetType | Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003619 NEONMAP0(vext_v),
3620 NEONMAP0(vextq_v),
3621 NEONMAP0(vfma_v),
3622 NEONMAP0(vfmaq_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003623 NEONMAP2(vhadd_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3624 NEONMAP2(vhaddq_v, aarch64_neon_uhadd, aarch64_neon_shadd, Add1ArgType | UnsignedAlts),
3625 NEONMAP2(vhsub_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
3626 NEONMAP2(vhsubq_v, aarch64_neon_uhsub, aarch64_neon_shsub, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003627 NEONMAP0(vmovl_v),
3628 NEONMAP0(vmovn_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003629 NEONMAP1(vmul_v, aarch64_neon_pmul, Add1ArgType),
3630 NEONMAP1(vmulq_v, aarch64_neon_pmul, Add1ArgType),
3631 NEONMAP1(vpadd_v, aarch64_neon_addp, Add1ArgType),
3632 NEONMAP2(vpaddl_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3633 NEONMAP2(vpaddlq_v, aarch64_neon_uaddlp, aarch64_neon_saddlp, UnsignedAlts),
3634 NEONMAP1(vpaddq_v, aarch64_neon_addp, Add1ArgType),
3635 NEONMAP1(vqabs_v, aarch64_neon_sqabs, Add1ArgType),
3636 NEONMAP1(vqabsq_v, aarch64_neon_sqabs, Add1ArgType),
3637 NEONMAP2(vqadd_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3638 NEONMAP2(vqaddq_v, aarch64_neon_uqadd, aarch64_neon_sqadd, Add1ArgType | UnsignedAlts),
3639 NEONMAP2(vqdmlal_v, aarch64_neon_sqdmull, aarch64_neon_sqadd, 0),
3640 NEONMAP2(vqdmlsl_v, aarch64_neon_sqdmull, aarch64_neon_sqsub, 0),
3641 NEONMAP1(vqdmulh_v, aarch64_neon_sqdmulh, Add1ArgType),
3642 NEONMAP1(vqdmulhq_v, aarch64_neon_sqdmulh, Add1ArgType),
3643 NEONMAP1(vqdmull_v, aarch64_neon_sqdmull, Add1ArgType),
3644 NEONMAP2(vqmovn_v, aarch64_neon_uqxtn, aarch64_neon_sqxtn, Add1ArgType | UnsignedAlts),
3645 NEONMAP1(vqmovun_v, aarch64_neon_sqxtun, Add1ArgType),
3646 NEONMAP1(vqneg_v, aarch64_neon_sqneg, Add1ArgType),
3647 NEONMAP1(vqnegq_v, aarch64_neon_sqneg, Add1ArgType),
3648 NEONMAP1(vqrdmulh_v, aarch64_neon_sqrdmulh, Add1ArgType),
3649 NEONMAP1(vqrdmulhq_v, aarch64_neon_sqrdmulh, Add1ArgType),
3650 NEONMAP2(vqrshl_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3651 NEONMAP2(vqrshlq_v, aarch64_neon_uqrshl, aarch64_neon_sqrshl, Add1ArgType | UnsignedAlts),
3652 NEONMAP2(vqshl_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl, UnsignedAlts),
3653 NEONMAP2(vqshl_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
3654 NEONMAP2(vqshlq_n_v, aarch64_neon_uqshl, aarch64_neon_sqshl,UnsignedAlts),
3655 NEONMAP2(vqshlq_v, aarch64_neon_uqshl, aarch64_neon_sqshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003656 NEONMAP1(vqshlu_n_v, aarch64_neon_sqshlu, 0),
3657 NEONMAP1(vqshluq_n_v, aarch64_neon_sqshlu, 0),
Tim Northover573cbee2014-05-24 12:52:07 +00003658 NEONMAP2(vqsub_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3659 NEONMAP2(vqsubq_v, aarch64_neon_uqsub, aarch64_neon_sqsub, Add1ArgType | UnsignedAlts),
3660 NEONMAP1(vraddhn_v, aarch64_neon_raddhn, Add1ArgType),
3661 NEONMAP2(vrecpe_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3662 NEONMAP2(vrecpeq_v, aarch64_neon_frecpe, aarch64_neon_urecpe, 0),
3663 NEONMAP1(vrecps_v, aarch64_neon_frecps, Add1ArgType),
3664 NEONMAP1(vrecpsq_v, aarch64_neon_frecps, Add1ArgType),
3665 NEONMAP2(vrhadd_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3666 NEONMAP2(vrhaddq_v, aarch64_neon_urhadd, aarch64_neon_srhadd, Add1ArgType | UnsignedAlts),
3667 NEONMAP2(vrshl_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
3668 NEONMAP2(vrshlq_v, aarch64_neon_urshl, aarch64_neon_srshl, Add1ArgType | UnsignedAlts),
Yi Kong1083eb52014-07-29 09:25:17 +00003669 NEONMAP2(vrshr_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
3670 NEONMAP2(vrshrq_n_v, aarch64_neon_urshl, aarch64_neon_srshl, UnsignedAlts),
Tim Northover573cbee2014-05-24 12:52:07 +00003671 NEONMAP2(vrsqrte_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3672 NEONMAP2(vrsqrteq_v, aarch64_neon_frsqrte, aarch64_neon_ursqrte, 0),
3673 NEONMAP1(vrsqrts_v, aarch64_neon_frsqrts, Add1ArgType),
3674 NEONMAP1(vrsqrtsq_v, aarch64_neon_frsqrts, Add1ArgType),
3675 NEONMAP1(vrsubhn_v, aarch64_neon_rsubhn, Add1ArgType),
3676 NEONMAP1(vsha1su0q_v, aarch64_crypto_sha1su0, 0),
3677 NEONMAP1(vsha1su1q_v, aarch64_crypto_sha1su1, 0),
3678 NEONMAP1(vsha256h2q_v, aarch64_crypto_sha256h2, 0),
3679 NEONMAP1(vsha256hq_v, aarch64_crypto_sha256h, 0),
3680 NEONMAP1(vsha256su0q_v, aarch64_crypto_sha256su0, 0),
3681 NEONMAP1(vsha256su1q_v, aarch64_crypto_sha256su1, 0),
Tim Northovera2ee4332014-03-29 15:09:45 +00003682 NEONMAP0(vshl_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003683 NEONMAP2(vshl_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003684 NEONMAP0(vshll_n_v),
3685 NEONMAP0(vshlq_n_v),
Tim Northover573cbee2014-05-24 12:52:07 +00003686 NEONMAP2(vshlq_v, aarch64_neon_ushl, aarch64_neon_sshl, Add1ArgType | UnsignedAlts),
Tim Northovera2ee4332014-03-29 15:09:45 +00003687 NEONMAP0(vshr_n_v),
3688 NEONMAP0(vshrn_n_v),
3689 NEONMAP0(vshrq_n_v),
3690 NEONMAP0(vsubhn_v),
3691 NEONMAP0(vtst_v),
3692 NEONMAP0(vtstq_v),
3693};
3694
Craig Topper273dbc62015-10-18 05:29:26 +00003695static const NeonIntrinsicInfo AArch64SISDIntrinsicMap[] = {
Tim Northover573cbee2014-05-24 12:52:07 +00003696 NEONMAP1(vabdd_f64, aarch64_sisd_fabd, Add1ArgType),
3697 NEONMAP1(vabds_f32, aarch64_sisd_fabd, Add1ArgType),
3698 NEONMAP1(vabsd_s64, aarch64_neon_abs, Add1ArgType),
3699 NEONMAP1(vaddlv_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3700 NEONMAP1(vaddlv_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3701 NEONMAP1(vaddlvq_s32, aarch64_neon_saddlv, AddRetType | Add1ArgType),
3702 NEONMAP1(vaddlvq_u32, aarch64_neon_uaddlv, AddRetType | Add1ArgType),
3703 NEONMAP1(vaddv_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3704 NEONMAP1(vaddv_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3705 NEONMAP1(vaddv_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3706 NEONMAP1(vaddvq_f32, aarch64_neon_faddv, AddRetType | Add1ArgType),
3707 NEONMAP1(vaddvq_f64, aarch64_neon_faddv, AddRetType | Add1ArgType),
3708 NEONMAP1(vaddvq_s32, aarch64_neon_saddv, AddRetType | Add1ArgType),
3709 NEONMAP1(vaddvq_s64, aarch64_neon_saddv, AddRetType | Add1ArgType),
3710 NEONMAP1(vaddvq_u32, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3711 NEONMAP1(vaddvq_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3712 NEONMAP1(vcaged_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3713 NEONMAP1(vcages_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3714 NEONMAP1(vcagtd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3715 NEONMAP1(vcagts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3716 NEONMAP1(vcaled_f64, aarch64_neon_facge, AddRetType | Add1ArgType),
3717 NEONMAP1(vcales_f32, aarch64_neon_facge, AddRetType | Add1ArgType),
3718 NEONMAP1(vcaltd_f64, aarch64_neon_facgt, AddRetType | Add1ArgType),
3719 NEONMAP1(vcalts_f32, aarch64_neon_facgt, AddRetType | Add1ArgType),
3720 NEONMAP1(vcvtad_s64_f64, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3721 NEONMAP1(vcvtad_u64_f64, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3722 NEONMAP1(vcvtas_s32_f32, aarch64_neon_fcvtas, AddRetType | Add1ArgType),
3723 NEONMAP1(vcvtas_u32_f32, aarch64_neon_fcvtau, AddRetType | Add1ArgType),
3724 NEONMAP1(vcvtd_n_f64_s64, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3725 NEONMAP1(vcvtd_n_f64_u64, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3726 NEONMAP1(vcvtd_n_s64_f64, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3727 NEONMAP1(vcvtd_n_u64_f64, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3728 NEONMAP1(vcvtmd_s64_f64, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3729 NEONMAP1(vcvtmd_u64_f64, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3730 NEONMAP1(vcvtms_s32_f32, aarch64_neon_fcvtms, AddRetType | Add1ArgType),
3731 NEONMAP1(vcvtms_u32_f32, aarch64_neon_fcvtmu, AddRetType | Add1ArgType),
3732 NEONMAP1(vcvtnd_s64_f64, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3733 NEONMAP1(vcvtnd_u64_f64, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3734 NEONMAP1(vcvtns_s32_f32, aarch64_neon_fcvtns, AddRetType | Add1ArgType),
3735 NEONMAP1(vcvtns_u32_f32, aarch64_neon_fcvtnu, AddRetType | Add1ArgType),
3736 NEONMAP1(vcvtpd_s64_f64, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3737 NEONMAP1(vcvtpd_u64_f64, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3738 NEONMAP1(vcvtps_s32_f32, aarch64_neon_fcvtps, AddRetType | Add1ArgType),
3739 NEONMAP1(vcvtps_u32_f32, aarch64_neon_fcvtpu, AddRetType | Add1ArgType),
3740 NEONMAP1(vcvts_n_f32_s32, aarch64_neon_vcvtfxs2fp, AddRetType | Add1ArgType),
3741 NEONMAP1(vcvts_n_f32_u32, aarch64_neon_vcvtfxu2fp, AddRetType | Add1ArgType),
3742 NEONMAP1(vcvts_n_s32_f32, aarch64_neon_vcvtfp2fxs, AddRetType | Add1ArgType),
3743 NEONMAP1(vcvts_n_u32_f32, aarch64_neon_vcvtfp2fxu, AddRetType | Add1ArgType),
3744 NEONMAP1(vcvtxd_f32_f64, aarch64_sisd_fcvtxn, 0),
3745 NEONMAP1(vmaxnmv_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3746 NEONMAP1(vmaxnmvq_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3747 NEONMAP1(vmaxnmvq_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3748 NEONMAP1(vmaxv_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3749 NEONMAP1(vmaxv_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3750 NEONMAP1(vmaxv_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3751 NEONMAP1(vmaxvq_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3752 NEONMAP1(vmaxvq_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3753 NEONMAP1(vmaxvq_s32, aarch64_neon_smaxv, AddRetType | Add1ArgType),
3754 NEONMAP1(vmaxvq_u32, aarch64_neon_umaxv, AddRetType | Add1ArgType),
3755 NEONMAP1(vminnmv_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3756 NEONMAP1(vminnmvq_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3757 NEONMAP1(vminnmvq_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3758 NEONMAP1(vminv_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3759 NEONMAP1(vminv_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3760 NEONMAP1(vminv_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3761 NEONMAP1(vminvq_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3762 NEONMAP1(vminvq_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3763 NEONMAP1(vminvq_s32, aarch64_neon_sminv, AddRetType | Add1ArgType),
3764 NEONMAP1(vminvq_u32, aarch64_neon_uminv, AddRetType | Add1ArgType),
3765 NEONMAP1(vmull_p64, aarch64_neon_pmull64, 0),
3766 NEONMAP1(vmulxd_f64, aarch64_neon_fmulx, Add1ArgType),
3767 NEONMAP1(vmulxs_f32, aarch64_neon_fmulx, Add1ArgType),
3768 NEONMAP1(vpaddd_s64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3769 NEONMAP1(vpaddd_u64, aarch64_neon_uaddv, AddRetType | Add1ArgType),
3770 NEONMAP1(vpmaxnmqd_f64, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3771 NEONMAP1(vpmaxnms_f32, aarch64_neon_fmaxnmv, AddRetType | Add1ArgType),
3772 NEONMAP1(vpmaxqd_f64, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3773 NEONMAP1(vpmaxs_f32, aarch64_neon_fmaxv, AddRetType | Add1ArgType),
3774 NEONMAP1(vpminnmqd_f64, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3775 NEONMAP1(vpminnms_f32, aarch64_neon_fminnmv, AddRetType | Add1ArgType),
3776 NEONMAP1(vpminqd_f64, aarch64_neon_fminv, AddRetType | Add1ArgType),
3777 NEONMAP1(vpmins_f32, aarch64_neon_fminv, AddRetType | Add1ArgType),
3778 NEONMAP1(vqabsb_s8, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3779 NEONMAP1(vqabsd_s64, aarch64_neon_sqabs, Add1ArgType),
3780 NEONMAP1(vqabsh_s16, aarch64_neon_sqabs, Vectorize1ArgType | Use64BitVectors),
3781 NEONMAP1(vqabss_s32, aarch64_neon_sqabs, Add1ArgType),
3782 NEONMAP1(vqaddb_s8, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3783 NEONMAP1(vqaddb_u8, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3784 NEONMAP1(vqaddd_s64, aarch64_neon_sqadd, Add1ArgType),
3785 NEONMAP1(vqaddd_u64, aarch64_neon_uqadd, Add1ArgType),
3786 NEONMAP1(vqaddh_s16, aarch64_neon_sqadd, Vectorize1ArgType | Use64BitVectors),
3787 NEONMAP1(vqaddh_u16, aarch64_neon_uqadd, Vectorize1ArgType | Use64BitVectors),
3788 NEONMAP1(vqadds_s32, aarch64_neon_sqadd, Add1ArgType),
3789 NEONMAP1(vqadds_u32, aarch64_neon_uqadd, Add1ArgType),
3790 NEONMAP1(vqdmulhh_s16, aarch64_neon_sqdmulh, Vectorize1ArgType | Use64BitVectors),
3791 NEONMAP1(vqdmulhs_s32, aarch64_neon_sqdmulh, Add1ArgType),
3792 NEONMAP1(vqdmullh_s16, aarch64_neon_sqdmull, VectorRet | Use128BitVectors),
3793 NEONMAP1(vqdmulls_s32, aarch64_neon_sqdmulls_scalar, 0),
3794 NEONMAP1(vqmovnd_s64, aarch64_neon_scalar_sqxtn, AddRetType | Add1ArgType),
3795 NEONMAP1(vqmovnd_u64, aarch64_neon_scalar_uqxtn, AddRetType | Add1ArgType),
3796 NEONMAP1(vqmovnh_s16, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3797 NEONMAP1(vqmovnh_u16, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3798 NEONMAP1(vqmovns_s32, aarch64_neon_sqxtn, VectorRet | Use64BitVectors),
3799 NEONMAP1(vqmovns_u32, aarch64_neon_uqxtn, VectorRet | Use64BitVectors),
3800 NEONMAP1(vqmovund_s64, aarch64_neon_scalar_sqxtun, AddRetType | Add1ArgType),
3801 NEONMAP1(vqmovunh_s16, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3802 NEONMAP1(vqmovuns_s32, aarch64_neon_sqxtun, VectorRet | Use64BitVectors),
3803 NEONMAP1(vqnegb_s8, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3804 NEONMAP1(vqnegd_s64, aarch64_neon_sqneg, Add1ArgType),
3805 NEONMAP1(vqnegh_s16, aarch64_neon_sqneg, Vectorize1ArgType | Use64BitVectors),
3806 NEONMAP1(vqnegs_s32, aarch64_neon_sqneg, Add1ArgType),
3807 NEONMAP1(vqrdmulhh_s16, aarch64_neon_sqrdmulh, Vectorize1ArgType | Use64BitVectors),
3808 NEONMAP1(vqrdmulhs_s32, aarch64_neon_sqrdmulh, Add1ArgType),
3809 NEONMAP1(vqrshlb_s8, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3810 NEONMAP1(vqrshlb_u8, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3811 NEONMAP1(vqrshld_s64, aarch64_neon_sqrshl, Add1ArgType),
3812 NEONMAP1(vqrshld_u64, aarch64_neon_uqrshl, Add1ArgType),
3813 NEONMAP1(vqrshlh_s16, aarch64_neon_sqrshl, Vectorize1ArgType | Use64BitVectors),
3814 NEONMAP1(vqrshlh_u16, aarch64_neon_uqrshl, Vectorize1ArgType | Use64BitVectors),
3815 NEONMAP1(vqrshls_s32, aarch64_neon_sqrshl, Add1ArgType),
3816 NEONMAP1(vqrshls_u32, aarch64_neon_uqrshl, Add1ArgType),
3817 NEONMAP1(vqrshrnd_n_s64, aarch64_neon_sqrshrn, AddRetType),
3818 NEONMAP1(vqrshrnd_n_u64, aarch64_neon_uqrshrn, AddRetType),
3819 NEONMAP1(vqrshrnh_n_s16, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3820 NEONMAP1(vqrshrnh_n_u16, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3821 NEONMAP1(vqrshrns_n_s32, aarch64_neon_sqrshrn, VectorRet | Use64BitVectors),
3822 NEONMAP1(vqrshrns_n_u32, aarch64_neon_uqrshrn, VectorRet | Use64BitVectors),
3823 NEONMAP1(vqrshrund_n_s64, aarch64_neon_sqrshrun, AddRetType),
3824 NEONMAP1(vqrshrunh_n_s16, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3825 NEONMAP1(vqrshruns_n_s32, aarch64_neon_sqrshrun, VectorRet | Use64BitVectors),
3826 NEONMAP1(vqshlb_n_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3827 NEONMAP1(vqshlb_n_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3828 NEONMAP1(vqshlb_s8, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3829 NEONMAP1(vqshlb_u8, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3830 NEONMAP1(vqshld_s64, aarch64_neon_sqshl, Add1ArgType),
3831 NEONMAP1(vqshld_u64, aarch64_neon_uqshl, Add1ArgType),
3832 NEONMAP1(vqshlh_n_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3833 NEONMAP1(vqshlh_n_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3834 NEONMAP1(vqshlh_s16, aarch64_neon_sqshl, Vectorize1ArgType | Use64BitVectors),
3835 NEONMAP1(vqshlh_u16, aarch64_neon_uqshl, Vectorize1ArgType | Use64BitVectors),
3836 NEONMAP1(vqshls_n_s32, aarch64_neon_sqshl, Add1ArgType),
3837 NEONMAP1(vqshls_n_u32, aarch64_neon_uqshl, Add1ArgType),
3838 NEONMAP1(vqshls_s32, aarch64_neon_sqshl, Add1ArgType),
3839 NEONMAP1(vqshls_u32, aarch64_neon_uqshl, Add1ArgType),
3840 NEONMAP1(vqshlub_n_s8, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3841 NEONMAP1(vqshluh_n_s16, aarch64_neon_sqshlu, Vectorize1ArgType | Use64BitVectors),
3842 NEONMAP1(vqshlus_n_s32, aarch64_neon_sqshlu, Add1ArgType),
3843 NEONMAP1(vqshrnd_n_s64, aarch64_neon_sqshrn, AddRetType),
3844 NEONMAP1(vqshrnd_n_u64, aarch64_neon_uqshrn, AddRetType),
3845 NEONMAP1(vqshrnh_n_s16, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3846 NEONMAP1(vqshrnh_n_u16, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3847 NEONMAP1(vqshrns_n_s32, aarch64_neon_sqshrn, VectorRet | Use64BitVectors),
3848 NEONMAP1(vqshrns_n_u32, aarch64_neon_uqshrn, VectorRet | Use64BitVectors),
3849 NEONMAP1(vqshrund_n_s64, aarch64_neon_sqshrun, AddRetType),
3850 NEONMAP1(vqshrunh_n_s16, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3851 NEONMAP1(vqshruns_n_s32, aarch64_neon_sqshrun, VectorRet | Use64BitVectors),
3852 NEONMAP1(vqsubb_s8, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3853 NEONMAP1(vqsubb_u8, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3854 NEONMAP1(vqsubd_s64, aarch64_neon_sqsub, Add1ArgType),
3855 NEONMAP1(vqsubd_u64, aarch64_neon_uqsub, Add1ArgType),
3856 NEONMAP1(vqsubh_s16, aarch64_neon_sqsub, Vectorize1ArgType | Use64BitVectors),
3857 NEONMAP1(vqsubh_u16, aarch64_neon_uqsub, Vectorize1ArgType | Use64BitVectors),
3858 NEONMAP1(vqsubs_s32, aarch64_neon_sqsub, Add1ArgType),
3859 NEONMAP1(vqsubs_u32, aarch64_neon_uqsub, Add1ArgType),
3860 NEONMAP1(vrecped_f64, aarch64_neon_frecpe, Add1ArgType),
3861 NEONMAP1(vrecpes_f32, aarch64_neon_frecpe, Add1ArgType),
3862 NEONMAP1(vrecpxd_f64, aarch64_neon_frecpx, Add1ArgType),
3863 NEONMAP1(vrecpxs_f32, aarch64_neon_frecpx, Add1ArgType),
3864 NEONMAP1(vrshld_s64, aarch64_neon_srshl, Add1ArgType),
3865 NEONMAP1(vrshld_u64, aarch64_neon_urshl, Add1ArgType),
3866 NEONMAP1(vrsqrted_f64, aarch64_neon_frsqrte, Add1ArgType),
3867 NEONMAP1(vrsqrtes_f32, aarch64_neon_frsqrte, Add1ArgType),
3868 NEONMAP1(vrsqrtsd_f64, aarch64_neon_frsqrts, Add1ArgType),
3869 NEONMAP1(vrsqrtss_f32, aarch64_neon_frsqrts, Add1ArgType),
3870 NEONMAP1(vsha1cq_u32, aarch64_crypto_sha1c, 0),
3871 NEONMAP1(vsha1h_u32, aarch64_crypto_sha1h, 0),
3872 NEONMAP1(vsha1mq_u32, aarch64_crypto_sha1m, 0),
3873 NEONMAP1(vsha1pq_u32, aarch64_crypto_sha1p, 0),
3874 NEONMAP1(vshld_s64, aarch64_neon_sshl, Add1ArgType),
3875 NEONMAP1(vshld_u64, aarch64_neon_ushl, Add1ArgType),
3876 NEONMAP1(vslid_n_s64, aarch64_neon_vsli, Vectorize1ArgType),
3877 NEONMAP1(vslid_n_u64, aarch64_neon_vsli, Vectorize1ArgType),
3878 NEONMAP1(vsqaddb_u8, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3879 NEONMAP1(vsqaddd_u64, aarch64_neon_usqadd, Add1ArgType),
3880 NEONMAP1(vsqaddh_u16, aarch64_neon_usqadd, Vectorize1ArgType | Use64BitVectors),
3881 NEONMAP1(vsqadds_u32, aarch64_neon_usqadd, Add1ArgType),
3882 NEONMAP1(vsrid_n_s64, aarch64_neon_vsri, Vectorize1ArgType),
3883 NEONMAP1(vsrid_n_u64, aarch64_neon_vsri, Vectorize1ArgType),
3884 NEONMAP1(vuqaddb_s8, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3885 NEONMAP1(vuqaddd_s64, aarch64_neon_suqadd, Add1ArgType),
3886 NEONMAP1(vuqaddh_s16, aarch64_neon_suqadd, Vectorize1ArgType | Use64BitVectors),
3887 NEONMAP1(vuqadds_s32, aarch64_neon_suqadd, Add1ArgType),
Tim Northovera2ee4332014-03-29 15:09:45 +00003888};
3889
Tim Northover8fe03d62014-02-21 11:57:24 +00003890#undef NEONMAP0
3891#undef NEONMAP1
3892#undef NEONMAP2
3893
3894static bool NEONSIMDIntrinsicsProvenSorted = false;
Tim Northover8fe03d62014-02-21 11:57:24 +00003895
Tim Northover573cbee2014-05-24 12:52:07 +00003896static bool AArch64SIMDIntrinsicsProvenSorted = false;
3897static bool AArch64SISDIntrinsicsProvenSorted = false;
Tim Northovera2ee4332014-03-29 15:09:45 +00003898
3899
Tim Northover8fe03d62014-02-21 11:57:24 +00003900static const NeonIntrinsicInfo *
Craig Topper00bbdcf2014-06-28 23:22:23 +00003901findNeonIntrinsicInMap(ArrayRef<NeonIntrinsicInfo> IntrinsicMap,
Tim Northover8fe03d62014-02-21 11:57:24 +00003902 unsigned BuiltinID, bool &MapProvenSorted) {
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003903
3904#ifndef NDEBUG
Tim Northover8fe03d62014-02-21 11:57:24 +00003905 if (!MapProvenSorted) {
Eric Christophered60b432015-11-11 02:04:08 +00003906 assert(std::is_sorted(std::begin(IntrinsicMap), std::end(IntrinsicMap)));
Tim Northover8fe03d62014-02-21 11:57:24 +00003907 MapProvenSorted = true;
3908 }
Tim Northoverdb3e5e22014-02-19 11:55:06 +00003909#endif
3910
Tim Northover8fe03d62014-02-21 11:57:24 +00003911 const NeonIntrinsicInfo *Builtin =
3912 std::lower_bound(IntrinsicMap.begin(), IntrinsicMap.end(), BuiltinID);
3913
3914 if (Builtin != IntrinsicMap.end() && Builtin->BuiltinID == BuiltinID)
3915 return Builtin;
3916
Craig Topper8a13c412014-05-21 05:09:00 +00003917 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00003918}
3919
3920Function *CodeGenFunction::LookupNeonLLVMIntrinsic(unsigned IntrinsicID,
3921 unsigned Modifier,
3922 llvm::Type *ArgType,
3923 const CallExpr *E) {
Tim Northovera2ee4332014-03-29 15:09:45 +00003924 int VectorSize = 0;
3925 if (Modifier & Use64BitVectors)
3926 VectorSize = 64;
3927 else if (Modifier & Use128BitVectors)
3928 VectorSize = 128;
3929
Tim Northover2d837962014-02-21 11:57:20 +00003930 // Return type.
3931 SmallVector<llvm::Type *, 3> Tys;
3932 if (Modifier & AddRetType) {
David Majnemerced8bdf2015-02-25 17:36:15 +00003933 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northover2d837962014-02-21 11:57:20 +00003934 if (Modifier & VectorizeRetType)
Tim Northovera2ee4332014-03-29 15:09:45 +00003935 Ty = llvm::VectorType::get(
3936 Ty, VectorSize ? VectorSize / Ty->getPrimitiveSizeInBits() : 1);
Tim Northover2d837962014-02-21 11:57:20 +00003937
3938 Tys.push_back(Ty);
3939 }
3940
3941 // Arguments.
Tim Northovera2ee4332014-03-29 15:09:45 +00003942 if (Modifier & VectorizeArgTypes) {
3943 int Elts = VectorSize ? VectorSize / ArgType->getPrimitiveSizeInBits() : 1;
3944 ArgType = llvm::VectorType::get(ArgType, Elts);
3945 }
Tim Northover2d837962014-02-21 11:57:20 +00003946
3947 if (Modifier & (Add1ArgType | Add2ArgTypes))
3948 Tys.push_back(ArgType);
3949
3950 if (Modifier & Add2ArgTypes)
3951 Tys.push_back(ArgType);
3952
3953 if (Modifier & InventFloatType)
3954 Tys.push_back(FloatTy);
3955
3956 return CGM.getIntrinsic(IntrinsicID, Tys);
3957}
3958
Tim Northovera2ee4332014-03-29 15:09:45 +00003959static Value *EmitCommonNeonSISDBuiltinExpr(CodeGenFunction &CGF,
3960 const NeonIntrinsicInfo &SISDInfo,
3961 SmallVectorImpl<Value *> &Ops,
3962 const CallExpr *E) {
Tim Northover0c68faa2014-03-31 15:47:09 +00003963 unsigned BuiltinID = SISDInfo.BuiltinID;
Tim Northovera2ee4332014-03-29 15:09:45 +00003964 unsigned int Int = SISDInfo.LLVMIntrinsic;
3965 unsigned Modifier = SISDInfo.TypeModifier;
3966 const char *s = SISDInfo.NameHint;
3967
Tim Northover0c68faa2014-03-31 15:47:09 +00003968 switch (BuiltinID) {
3969 case NEON::BI__builtin_neon_vcled_s64:
3970 case NEON::BI__builtin_neon_vcled_u64:
3971 case NEON::BI__builtin_neon_vcles_f32:
3972 case NEON::BI__builtin_neon_vcled_f64:
3973 case NEON::BI__builtin_neon_vcltd_s64:
3974 case NEON::BI__builtin_neon_vcltd_u64:
3975 case NEON::BI__builtin_neon_vclts_f32:
3976 case NEON::BI__builtin_neon_vcltd_f64:
3977 case NEON::BI__builtin_neon_vcales_f32:
3978 case NEON::BI__builtin_neon_vcaled_f64:
3979 case NEON::BI__builtin_neon_vcalts_f32:
3980 case NEON::BI__builtin_neon_vcaltd_f64:
3981 // Only one direction of comparisons actually exist, cmle is actually a cmge
3982 // with swapped operands. The table gives us the right intrinsic but we
3983 // still need to do the swap.
3984 std::swap(Ops[0], Ops[1]);
3985 break;
3986 }
3987
Tim Northovera2ee4332014-03-29 15:09:45 +00003988 assert(Int && "Generic code assumes a valid intrinsic");
3989
3990 // Determine the type(s) of this overloaded AArch64 intrinsic.
3991 const Expr *Arg = E->getArg(0);
3992 llvm::Type *ArgTy = CGF.ConvertType(Arg->getType());
3993 Function *F = CGF.LookupNeonLLVMIntrinsic(Int, Modifier, ArgTy, E);
3994
3995 int j = 0;
Michael J. Spencerdd597752014-05-31 00:22:12 +00003996 ConstantInt *C0 = ConstantInt::get(CGF.SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00003997 for (Function::const_arg_iterator ai = F->arg_begin(), ae = F->arg_end();
3998 ai != ae; ++ai, ++j) {
3999 llvm::Type *ArgTy = ai->getType();
4000 if (Ops[j]->getType()->getPrimitiveSizeInBits() ==
4001 ArgTy->getPrimitiveSizeInBits())
4002 continue;
4003
4004 assert(ArgTy->isVectorTy() && !Ops[j]->getType()->isVectorTy());
4005 // The constant argument to an _n_ intrinsic always has Int32Ty, so truncate
4006 // it before inserting.
4007 Ops[j] =
4008 CGF.Builder.CreateTruncOrBitCast(Ops[j], ArgTy->getVectorElementType());
4009 Ops[j] =
4010 CGF.Builder.CreateInsertElement(UndefValue::get(ArgTy), Ops[j], C0);
4011 }
4012
4013 Value *Result = CGF.EmitNeonCall(F, Ops, s);
4014 llvm::Type *ResultType = CGF.ConvertType(E->getType());
4015 if (ResultType->getPrimitiveSizeInBits() <
4016 Result->getType()->getPrimitiveSizeInBits())
4017 return CGF.Builder.CreateExtractElement(Result, C0);
4018
4019 return CGF.Builder.CreateBitCast(Result, ResultType, s);
4020}
Tim Northover8fe03d62014-02-21 11:57:24 +00004021
Tim Northover8fe03d62014-02-21 11:57:24 +00004022Value *CodeGenFunction::EmitCommonNeonBuiltinExpr(
4023 unsigned BuiltinID, unsigned LLVMIntrinsic, unsigned AltLLVMIntrinsic,
4024 const char *NameHint, unsigned Modifier, const CallExpr *E,
John McCall7f416cc2015-09-08 08:05:57 +00004025 SmallVectorImpl<llvm::Value *> &Ops, Address PtrOp0, Address PtrOp1) {
Tim Northover8fe03d62014-02-21 11:57:24 +00004026 // Get the last argument, which specifies the vector type.
4027 llvm::APSInt NeonTypeConst;
4028 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
4029 if (!Arg->isIntegerConstantExpr(NeonTypeConst, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00004030 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004031
4032 // Determine the type of this overloaded NEON intrinsic.
4033 NeonTypeFlags Type(NeonTypeConst.getZExtValue());
4034 bool Usgn = Type.isUnsigned();
4035 bool Quad = Type.isQuad();
4036
4037 llvm::VectorType *VTy = GetNeonType(this, Type);
4038 llvm::Type *Ty = VTy;
4039 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00004040 return nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004041
John McCall7f416cc2015-09-08 08:05:57 +00004042 auto getAlignmentValue32 = [&](Address addr) -> Value* {
4043 return Builder.getInt32(addr.getAlignment().getQuantity());
4044 };
4045
Tim Northover8fe03d62014-02-21 11:57:24 +00004046 unsigned Int = LLVMIntrinsic;
4047 if ((Modifier & UnsignedAlts) && !Usgn)
4048 Int = AltLLVMIntrinsic;
4049
4050 switch (BuiltinID) {
4051 default: break;
4052 case NEON::BI__builtin_neon_vabs_v:
4053 case NEON::BI__builtin_neon_vabsq_v:
4054 if (VTy->getElementType()->isFloatingPointTy())
4055 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::fabs, Ty), Ops, "vabs");
4056 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), Ops, "vabs");
4057 case NEON::BI__builtin_neon_vaddhn_v: {
4058 llvm::VectorType *SrcTy =
4059 llvm::VectorType::getExtendedElementVectorType(VTy);
4060
4061 // %sum = add <4 x i32> %lhs, %rhs
4062 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4063 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
4064 Ops[0] = Builder.CreateAdd(Ops[0], Ops[1], "vaddhn");
4065
4066 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00004067 Constant *ShiftAmt =
4068 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00004069 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vaddhn");
4070
4071 // %res = trunc <4 x i32> %high to <4 x i16>
4072 return Builder.CreateTrunc(Ops[0], VTy, "vaddhn");
4073 }
4074 case NEON::BI__builtin_neon_vcale_v:
4075 case NEON::BI__builtin_neon_vcaleq_v:
4076 case NEON::BI__builtin_neon_vcalt_v:
4077 case NEON::BI__builtin_neon_vcaltq_v:
4078 std::swap(Ops[0], Ops[1]);
Galina Kistanova0872d6c2017-06-03 06:30:46 +00004079 LLVM_FALLTHROUGH;
Tim Northover8fe03d62014-02-21 11:57:24 +00004080 case NEON::BI__builtin_neon_vcage_v:
4081 case NEON::BI__builtin_neon_vcageq_v:
4082 case NEON::BI__builtin_neon_vcagt_v:
4083 case NEON::BI__builtin_neon_vcagtq_v: {
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00004084 llvm::Type *VecFlt = llvm::VectorType::get(
4085 VTy->getScalarSizeInBits() == 32 ? FloatTy : DoubleTy,
4086 VTy->getNumElements());
Tim Northover8fe03d62014-02-21 11:57:24 +00004087 llvm::Type *Tys[] = { VTy, VecFlt };
4088 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
4089 return EmitNeonCall(F, Ops, NameHint);
4090 }
4091 case NEON::BI__builtin_neon_vclz_v:
4092 case NEON::BI__builtin_neon_vclzq_v:
4093 // We generate target-independent intrinsic, which needs a second argument
4094 // for whether or not clz of zero is undefined; on ARM it isn't.
4095 Ops.push_back(Builder.getInt1(getTarget().isCLZForZeroUndef()));
4096 break;
4097 case NEON::BI__builtin_neon_vcvt_f32_v:
4098 case NEON::BI__builtin_neon_vcvtq_f32_v:
4099 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4100 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float32, false, Quad));
4101 return Usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
4102 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
4103 case NEON::BI__builtin_neon_vcvt_n_f32_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00004104 case NEON::BI__builtin_neon_vcvt_n_f64_v:
4105 case NEON::BI__builtin_neon_vcvtq_n_f32_v:
4106 case NEON::BI__builtin_neon_vcvtq_n_f64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004107 llvm::Type *Tys[2] = { GetFloatNeonType(this, Type), Ty };
Tim Northover8fe03d62014-02-21 11:57:24 +00004108 Int = Usgn ? LLVMIntrinsic : AltLLVMIntrinsic;
4109 Function *F = CGM.getIntrinsic(Int, Tys);
4110 return EmitNeonCall(F, Ops, "vcvt_n");
4111 }
4112 case NEON::BI__builtin_neon_vcvt_n_s32_v:
4113 case NEON::BI__builtin_neon_vcvt_n_u32_v:
4114 case NEON::BI__builtin_neon_vcvt_n_s64_v:
4115 case NEON::BI__builtin_neon_vcvt_n_u64_v:
4116 case NEON::BI__builtin_neon_vcvtq_n_s32_v:
4117 case NEON::BI__builtin_neon_vcvtq_n_u32_v:
4118 case NEON::BI__builtin_neon_vcvtq_n_s64_v:
4119 case NEON::BI__builtin_neon_vcvtq_n_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004120 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00004121 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
4122 return EmitNeonCall(F, Ops, "vcvt_n");
4123 }
4124 case NEON::BI__builtin_neon_vcvt_s32_v:
4125 case NEON::BI__builtin_neon_vcvt_u32_v:
4126 case NEON::BI__builtin_neon_vcvt_s64_v:
4127 case NEON::BI__builtin_neon_vcvt_u64_v:
4128 case NEON::BI__builtin_neon_vcvtq_s32_v:
4129 case NEON::BI__builtin_neon_vcvtq_u32_v:
4130 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00004131 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004132 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northover8fe03d62014-02-21 11:57:24 +00004133 return Usgn ? Builder.CreateFPToUI(Ops[0], Ty, "vcvt")
4134 : Builder.CreateFPToSI(Ops[0], Ty, "vcvt");
4135 }
4136 case NEON::BI__builtin_neon_vcvta_s32_v:
4137 case NEON::BI__builtin_neon_vcvta_s64_v:
4138 case NEON::BI__builtin_neon_vcvta_u32_v:
4139 case NEON::BI__builtin_neon_vcvta_u64_v:
4140 case NEON::BI__builtin_neon_vcvtaq_s32_v:
4141 case NEON::BI__builtin_neon_vcvtaq_s64_v:
4142 case NEON::BI__builtin_neon_vcvtaq_u32_v:
4143 case NEON::BI__builtin_neon_vcvtaq_u64_v:
4144 case NEON::BI__builtin_neon_vcvtn_s32_v:
4145 case NEON::BI__builtin_neon_vcvtn_s64_v:
4146 case NEON::BI__builtin_neon_vcvtn_u32_v:
4147 case NEON::BI__builtin_neon_vcvtn_u64_v:
4148 case NEON::BI__builtin_neon_vcvtnq_s32_v:
4149 case NEON::BI__builtin_neon_vcvtnq_s64_v:
4150 case NEON::BI__builtin_neon_vcvtnq_u32_v:
4151 case NEON::BI__builtin_neon_vcvtnq_u64_v:
4152 case NEON::BI__builtin_neon_vcvtp_s32_v:
4153 case NEON::BI__builtin_neon_vcvtp_s64_v:
4154 case NEON::BI__builtin_neon_vcvtp_u32_v:
4155 case NEON::BI__builtin_neon_vcvtp_u64_v:
4156 case NEON::BI__builtin_neon_vcvtpq_s32_v:
4157 case NEON::BI__builtin_neon_vcvtpq_s64_v:
4158 case NEON::BI__builtin_neon_vcvtpq_u32_v:
4159 case NEON::BI__builtin_neon_vcvtpq_u64_v:
4160 case NEON::BI__builtin_neon_vcvtm_s32_v:
4161 case NEON::BI__builtin_neon_vcvtm_s64_v:
4162 case NEON::BI__builtin_neon_vcvtm_u32_v:
4163 case NEON::BI__builtin_neon_vcvtm_u64_v:
4164 case NEON::BI__builtin_neon_vcvtmq_s32_v:
4165 case NEON::BI__builtin_neon_vcvtmq_s64_v:
4166 case NEON::BI__builtin_neon_vcvtmq_u32_v:
4167 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00004168 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northover8fe03d62014-02-21 11:57:24 +00004169 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, NameHint);
4170 }
4171 case NEON::BI__builtin_neon_vext_v:
4172 case NEON::BI__builtin_neon_vextq_v: {
4173 int CV = cast<ConstantInt>(Ops[2])->getSExtValue();
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004174 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004175 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00004176 Indices.push_back(i+CV);
Tim Northover8fe03d62014-02-21 11:57:24 +00004177
4178 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4179 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Craig Topper832caf02016-05-29 02:39:30 +00004180 return Builder.CreateShuffleVector(Ops[0], Ops[1], Indices, "vext");
Tim Northover8fe03d62014-02-21 11:57:24 +00004181 }
4182 case NEON::BI__builtin_neon_vfma_v:
4183 case NEON::BI__builtin_neon_vfmaq_v: {
4184 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
4185 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4186 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4187 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
4188
4189 // NEON intrinsic puts accumulator first, unlike the LLVM fma.
David Blaikie43f9bb72015-05-18 22:14:03 +00004190 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northover8fe03d62014-02-21 11:57:24 +00004191 }
4192 case NEON::BI__builtin_neon_vld1_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004193 case NEON::BI__builtin_neon_vld1q_v: {
4194 llvm::Type *Tys[] = {Ty, Int8PtrTy};
John McCall7f416cc2015-09-08 08:05:57 +00004195 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004196 return EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Tys), Ops, "vld1");
4197 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004198 case NEON::BI__builtin_neon_vld2_v:
4199 case NEON::BI__builtin_neon_vld2q_v:
4200 case NEON::BI__builtin_neon_vld3_v:
4201 case NEON::BI__builtin_neon_vld3q_v:
4202 case NEON::BI__builtin_neon_vld4_v:
4203 case NEON::BI__builtin_neon_vld4q_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004204 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4205 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00004206 Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00004207 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004208 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4209 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004210 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004211 }
4212 case NEON::BI__builtin_neon_vld1_dup_v:
4213 case NEON::BI__builtin_neon_vld1q_dup_v: {
4214 Value *V = UndefValue::get(Ty);
4215 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00004216 PtrOp0 = Builder.CreateBitCast(PtrOp0, Ty);
4217 LoadInst *Ld = Builder.CreateLoad(PtrOp0);
Michael J. Spencerdd597752014-05-31 00:22:12 +00004218 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northover8fe03d62014-02-21 11:57:24 +00004219 Ops[0] = Builder.CreateInsertElement(V, Ld, CI);
4220 return EmitNeonSplat(Ops[0], CI);
4221 }
4222 case NEON::BI__builtin_neon_vld2_lane_v:
4223 case NEON::BI__builtin_neon_vld2q_lane_v:
4224 case NEON::BI__builtin_neon_vld3_lane_v:
4225 case NEON::BI__builtin_neon_vld3q_lane_v:
4226 case NEON::BI__builtin_neon_vld4_lane_v:
4227 case NEON::BI__builtin_neon_vld4q_lane_v: {
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004228 llvm::Type *Tys[] = {Ty, Int8PtrTy};
4229 Function *F = CGM.getIntrinsic(LLVMIntrinsic, Tys);
Tim Northover8fe03d62014-02-21 11:57:24 +00004230 for (unsigned I = 2; I < Ops.size() - 1; ++I)
4231 Ops[I] = Builder.CreateBitCast(Ops[I], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004232 Ops.push_back(getAlignmentValue32(PtrOp1));
Tim Northover8fe03d62014-02-21 11:57:24 +00004233 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), NameHint);
4234 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
4235 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00004236 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northover8fe03d62014-02-21 11:57:24 +00004237 }
4238 case NEON::BI__builtin_neon_vmovl_v: {
4239 llvm::Type *DTy =llvm::VectorType::getTruncatedElementVectorType(VTy);
4240 Ops[0] = Builder.CreateBitCast(Ops[0], DTy);
4241 if (Usgn)
4242 return Builder.CreateZExt(Ops[0], Ty, "vmovl");
4243 return Builder.CreateSExt(Ops[0], Ty, "vmovl");
4244 }
4245 case NEON::BI__builtin_neon_vmovn_v: {
4246 llvm::Type *QTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4247 Ops[0] = Builder.CreateBitCast(Ops[0], QTy);
4248 return Builder.CreateTrunc(Ops[0], Ty, "vmovn");
4249 }
4250 case NEON::BI__builtin_neon_vmull_v:
4251 // FIXME: the integer vmull operations could be emitted in terms of pure
4252 // LLVM IR (2 exts followed by a mul). Unfortunately LLVM has a habit of
4253 // hoisting the exts outside loops. Until global ISel comes along that can
4254 // see through such movement this leads to bad CodeGen. So we need an
4255 // intrinsic for now.
4256 Int = Usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
4257 Int = Type.isPoly() ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
4258 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
4259 case NEON::BI__builtin_neon_vpadal_v:
4260 case NEON::BI__builtin_neon_vpadalq_v: {
4261 // The source operand type has twice as many elements of half the size.
4262 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4263 llvm::Type *EltTy =
4264 llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4265 llvm::Type *NarrowTy =
4266 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4267 llvm::Type *Tys[2] = { Ty, NarrowTy };
4268 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, NameHint);
4269 }
4270 case NEON::BI__builtin_neon_vpaddl_v:
4271 case NEON::BI__builtin_neon_vpaddlq_v: {
4272 // The source operand type has twice as many elements of half the size.
4273 unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
4274 llvm::Type *EltTy = llvm::IntegerType::get(getLLVMContext(), EltBits / 2);
4275 llvm::Type *NarrowTy =
4276 llvm::VectorType::get(EltTy, VTy->getNumElements() * 2);
4277 llvm::Type *Tys[2] = { Ty, NarrowTy };
4278 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vpaddl");
4279 }
4280 case NEON::BI__builtin_neon_vqdmlal_v:
4281 case NEON::BI__builtin_neon_vqdmlsl_v: {
4282 SmallVector<Value *, 2> MulOps(Ops.begin() + 1, Ops.end());
Benjamin Kramerc385a802015-07-28 15:40:11 +00004283 Ops[1] =
4284 EmitNeonCall(CGM.getIntrinsic(LLVMIntrinsic, Ty), MulOps, "vqdmlal");
4285 Ops.resize(2);
4286 return EmitNeonCall(CGM.getIntrinsic(AltLLVMIntrinsic, Ty), Ops, NameHint);
Tim Northover8fe03d62014-02-21 11:57:24 +00004287 }
4288 case NEON::BI__builtin_neon_vqshl_n_v:
4289 case NEON::BI__builtin_neon_vqshlq_n_v:
4290 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshl_n",
4291 1, false);
Yi Kong1083eb52014-07-29 09:25:17 +00004292 case NEON::BI__builtin_neon_vqshlu_n_v:
4293 case NEON::BI__builtin_neon_vqshluq_n_v:
4294 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshlu_n",
4295 1, false);
Tim Northover8fe03d62014-02-21 11:57:24 +00004296 case NEON::BI__builtin_neon_vrecpe_v:
4297 case NEON::BI__builtin_neon_vrecpeq_v:
4298 case NEON::BI__builtin_neon_vrsqrte_v:
4299 case NEON::BI__builtin_neon_vrsqrteq_v:
4300 Int = Ty->isFPOrFPVectorTy() ? LLVMIntrinsic : AltLLVMIntrinsic;
4301 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, NameHint);
4302
Yi Kong1083eb52014-07-29 09:25:17 +00004303 case NEON::BI__builtin_neon_vrshr_n_v:
4304 case NEON::BI__builtin_neon_vrshrq_n_v:
4305 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshr_n",
4306 1, true);
Tim Northover8fe03d62014-02-21 11:57:24 +00004307 case NEON::BI__builtin_neon_vshl_n_v:
4308 case NEON::BI__builtin_neon_vshlq_n_v:
4309 Ops[1] = EmitNeonShiftVector(Ops[1], Ty, false);
4310 return Builder.CreateShl(Builder.CreateBitCast(Ops[0],Ty), Ops[1],
4311 "vshl_n");
4312 case NEON::BI__builtin_neon_vshll_n_v: {
4313 llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy);
4314 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4315 if (Usgn)
4316 Ops[0] = Builder.CreateZExt(Ops[0], VTy);
4317 else
4318 Ops[0] = Builder.CreateSExt(Ops[0], VTy);
4319 Ops[1] = EmitNeonShiftVector(Ops[1], VTy, false);
4320 return Builder.CreateShl(Ops[0], Ops[1], "vshll_n");
4321 }
4322 case NEON::BI__builtin_neon_vshrn_n_v: {
4323 llvm::Type *SrcTy = llvm::VectorType::getExtendedElementVectorType(VTy);
4324 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4325 Ops[1] = EmitNeonShiftVector(Ops[1], SrcTy, false);
4326 if (Usgn)
4327 Ops[0] = Builder.CreateLShr(Ops[0], Ops[1]);
4328 else
4329 Ops[0] = Builder.CreateAShr(Ops[0], Ops[1]);
4330 return Builder.CreateTrunc(Ops[0], Ty, "vshrn_n");
4331 }
4332 case NEON::BI__builtin_neon_vshr_n_v:
4333 case NEON::BI__builtin_neon_vshrq_n_v:
4334 return EmitNeonRShiftImm(Ops[0], Ops[1], Ty, Usgn, "vshr_n");
4335 case NEON::BI__builtin_neon_vst1_v:
4336 case NEON::BI__builtin_neon_vst1q_v:
4337 case NEON::BI__builtin_neon_vst2_v:
4338 case NEON::BI__builtin_neon_vst2q_v:
4339 case NEON::BI__builtin_neon_vst3_v:
4340 case NEON::BI__builtin_neon_vst3q_v:
4341 case NEON::BI__builtin_neon_vst4_v:
4342 case NEON::BI__builtin_neon_vst4q_v:
4343 case NEON::BI__builtin_neon_vst2_lane_v:
4344 case NEON::BI__builtin_neon_vst2q_lane_v:
4345 case NEON::BI__builtin_neon_vst3_lane_v:
4346 case NEON::BI__builtin_neon_vst3q_lane_v:
4347 case NEON::BI__builtin_neon_vst4_lane_v:
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004348 case NEON::BI__builtin_neon_vst4q_lane_v: {
4349 llvm::Type *Tys[] = {Int8PtrTy, Ty};
John McCall7f416cc2015-09-08 08:05:57 +00004350 Ops.push_back(getAlignmentValue32(PtrOp0));
Jeroen Ketema55a8e802015-09-30 10:56:56 +00004351 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
4352 }
Tim Northover8fe03d62014-02-21 11:57:24 +00004353 case NEON::BI__builtin_neon_vsubhn_v: {
4354 llvm::VectorType *SrcTy =
4355 llvm::VectorType::getExtendedElementVectorType(VTy);
4356
4357 // %sum = add <4 x i32> %lhs, %rhs
4358 Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
4359 Ops[1] = Builder.CreateBitCast(Ops[1], SrcTy);
4360 Ops[0] = Builder.CreateSub(Ops[0], Ops[1], "vsubhn");
4361
4362 // %high = lshr <4 x i32> %sum, <i32 16, i32 16, i32 16, i32 16>
Benjamin Kramerc385a802015-07-28 15:40:11 +00004363 Constant *ShiftAmt =
4364 ConstantInt::get(SrcTy, SrcTy->getScalarSizeInBits() / 2);
Tim Northover8fe03d62014-02-21 11:57:24 +00004365 Ops[0] = Builder.CreateLShr(Ops[0], ShiftAmt, "vsubhn");
4366
4367 // %res = trunc <4 x i32> %high to <4 x i16>
4368 return Builder.CreateTrunc(Ops[0], VTy, "vsubhn");
4369 }
4370 case NEON::BI__builtin_neon_vtrn_v:
4371 case NEON::BI__builtin_neon_vtrnq_v: {
4372 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4373 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4374 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004375 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004376
4377 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004378 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004379 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004380 Indices.push_back(i+vi);
4381 Indices.push_back(i+e+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004382 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004383 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004384 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00004385 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004386 }
4387 return SV;
4388 }
4389 case NEON::BI__builtin_neon_vtst_v:
4390 case NEON::BI__builtin_neon_vtstq_v: {
4391 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
4392 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4393 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
4394 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
4395 ConstantAggregateZero::get(Ty));
4396 return Builder.CreateSExt(Ops[0], Ty, "vtst");
4397 }
4398 case NEON::BI__builtin_neon_vuzp_v:
4399 case NEON::BI__builtin_neon_vuzpq_v: {
4400 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4401 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4402 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004403 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004404
4405 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004406 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004407 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00004408 Indices.push_back(2*i+vi);
Tim Northover8fe03d62014-02-21 11:57:24 +00004409
David Blaikiefb901c7a2015-04-04 15:12:29 +00004410 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004411 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00004412 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004413 }
4414 return SV;
4415 }
4416 case NEON::BI__builtin_neon_vzip_v:
4417 case NEON::BI__builtin_neon_vzipq_v: {
4418 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
4419 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
4420 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00004421 Value *SV = nullptr;
Tim Northover8fe03d62014-02-21 11:57:24 +00004422
4423 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00004424 SmallVector<uint32_t, 16> Indices;
Tim Northover8fe03d62014-02-21 11:57:24 +00004425 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00004426 Indices.push_back((i + vi*e) >> 1);
4427 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northover8fe03d62014-02-21 11:57:24 +00004428 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00004429 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00004430 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00004431 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northover8fe03d62014-02-21 11:57:24 +00004432 }
4433 return SV;
4434 }
4435 }
4436
4437 assert(Int && "Expected valid intrinsic number");
4438
4439 // Determine the type(s) of this overloaded AArch64 intrinsic.
4440 Function *F = LookupNeonLLVMIntrinsic(Int, Modifier, Ty, E);
4441
4442 Value *Result = EmitNeonCall(F, Ops, NameHint);
4443 llvm::Type *ResultType = ConvertType(E->getType());
4444 // AArch64 intrinsic one-element vector type cast to
4445 // scalar type expected by the builtin
4446 return Builder.CreateBitCast(Result, ResultType, NameHint);
4447}
4448
Kevin Qin1718af62013-11-14 02:45:18 +00004449Value *CodeGenFunction::EmitAArch64CompareBuiltinExpr(
4450 Value *Op, llvm::Type *Ty, const CmpInst::Predicate Fp,
4451 const CmpInst::Predicate Ip, const Twine &Name) {
Tim Northovera2ee4332014-03-29 15:09:45 +00004452 llvm::Type *OTy = Op->getType();
4453
4454 // FIXME: this is utterly horrific. We should not be looking at previous
4455 // codegen context to find out what needs doing. Unfortunately TableGen
4456 // currently gives us exactly the same calls for vceqz_f32 and vceqz_s32
4457 // (etc).
4458 if (BitCastInst *BI = dyn_cast<BitCastInst>(Op))
4459 OTy = BI->getOperand(0)->getType();
4460
Kevin Qin1718af62013-11-14 02:45:18 +00004461 Op = Builder.CreateBitCast(Op, OTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00004462 if (OTy->getScalarType()->isFloatingPointTy()) {
4463 Op = Builder.CreateFCmp(Fp, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004464 } else {
Tim Northovera2ee4332014-03-29 15:09:45 +00004465 Op = Builder.CreateICmp(Ip, Op, Constant::getNullValue(OTy));
Kevin Qin1718af62013-11-14 02:45:18 +00004466 }
Hao Liuf96fd372013-12-23 02:44:00 +00004467 return Builder.CreateSExt(Op, Ty, Name);
Kevin Qin1718af62013-11-14 02:45:18 +00004468}
4469
Jiangning Liu18b707c2013-11-14 01:57:55 +00004470static Value *packTBLDVectorList(CodeGenFunction &CGF, ArrayRef<Value *> Ops,
4471 Value *ExtOp, Value *IndexOp,
4472 llvm::Type *ResTy, unsigned IntID,
4473 const char *Name) {
4474 SmallVector<Value *, 2> TblOps;
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004475 if (ExtOp)
4476 TblOps.push_back(ExtOp);
4477
4478 // Build a vector containing sequential number like (0, 1, 2, ..., 15)
4479 SmallVector<uint32_t, 16> Indices;
4480 llvm::VectorType *TblTy = cast<llvm::VectorType>(Ops[0]->getType());
4481 for (unsigned i = 0, e = TblTy->getNumElements(); i != e; ++i) {
Craig Topper832caf02016-05-29 02:39:30 +00004482 Indices.push_back(2*i);
4483 Indices.push_back(2*i+1);
Jiangning Liu18b707c2013-11-14 01:57:55 +00004484 }
Jiangning Liu18b707c2013-11-14 01:57:55 +00004485
4486 int PairPos = 0, End = Ops.size() - 1;
4487 while (PairPos < End) {
4488 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004489 Ops[PairPos+1], Indices,
4490 Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004491 PairPos += 2;
4492 }
4493
4494 // If there's an odd number of 64-bit lookup table, fill the high 64-bit
4495 // of the 128-bit lookup table with zero.
4496 if (PairPos == End) {
4497 Value *ZeroTbl = ConstantAggregateZero::get(TblTy);
4498 TblOps.push_back(CGF.Builder.CreateShuffleVector(Ops[PairPos],
Craig Topper832caf02016-05-29 02:39:30 +00004499 ZeroTbl, Indices, Name));
Jiangning Liu18b707c2013-11-14 01:57:55 +00004500 }
4501
Simon Pilgrim532de1c2016-06-13 10:05:19 +00004502 Function *TblF;
4503 TblOps.push_back(IndexOp);
4504 TblF = CGF.CGM.getIntrinsic(IntID, ResTy);
4505
4506 return CGF.EmitNeonCall(TblF, TblOps, Name);
4507}
4508
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004509Value *CodeGenFunction::GetValueForARMHint(unsigned BuiltinID) {
Benjamin Kramerc385a802015-07-28 15:40:11 +00004510 unsigned Value;
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004511 switch (BuiltinID) {
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004512 default:
4513 return nullptr;
Yi Kong4d5e23f2014-07-14 15:20:09 +00004514 case ARM::BI__builtin_arm_nop:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004515 Value = 0;
4516 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004517 case ARM::BI__builtin_arm_yield:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004518 case ARM::BI__yield:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004519 Value = 1;
4520 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004521 case ARM::BI__builtin_arm_wfe:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004522 case ARM::BI__wfe:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004523 Value = 2;
4524 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004525 case ARM::BI__builtin_arm_wfi:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004526 case ARM::BI__wfi:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004527 Value = 3;
4528 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004529 case ARM::BI__builtin_arm_sev:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004530 case ARM::BI__sev:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004531 Value = 4;
4532 break;
Saleem Abdulrasoolece72172014-07-03 02:43:20 +00004533 case ARM::BI__builtin_arm_sevl:
Saleem Abdulrasool956c2ec2014-05-04 02:52:25 +00004534 case ARM::BI__sevl:
Benjamin Kramerc385a802015-07-28 15:40:11 +00004535 Value = 5;
4536 break;
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004537 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00004538
4539 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_hint),
4540 llvm::ConstantInt::get(Int32Ty, Value));
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004541}
Saleem Abdulrasoolb9f07e32014-04-25 21:13:29 +00004542
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004543// Generates the IR for the read/write special register builtin,
4544// ValueType is the type of the value that is to be written or read,
4545// RegisterType is the type of the register being written to or read from.
4546static Value *EmitSpecialRegisterBuiltin(CodeGenFunction &CGF,
4547 const CallExpr *E,
4548 llvm::Type *RegisterType,
Matt Arsenault64665bc2016-06-28 00:13:17 +00004549 llvm::Type *ValueType,
4550 bool IsRead,
4551 StringRef SysReg = "") {
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004552 // write and register intrinsics only support 32 and 64 bit operations.
4553 assert((RegisterType->isIntegerTy(32) || RegisterType->isIntegerTy(64))
4554 && "Unsupported size for register.");
4555
4556 CodeGen::CGBuilderTy &Builder = CGF.Builder;
4557 CodeGen::CodeGenModule &CGM = CGF.CGM;
4558 LLVMContext &Context = CGM.getLLVMContext();
4559
Matt Arsenault64665bc2016-06-28 00:13:17 +00004560 if (SysReg.empty()) {
4561 const Expr *SysRegStrExpr = E->getArg(0)->IgnoreParenCasts();
Zachary Turner26dab122016-12-13 17:10:16 +00004562 SysReg = cast<clang::StringLiteral>(SysRegStrExpr)->getString();
Matt Arsenault64665bc2016-06-28 00:13:17 +00004563 }
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004564
4565 llvm::Metadata *Ops[] = { llvm::MDString::get(Context, SysReg) };
4566 llvm::MDNode *RegName = llvm::MDNode::get(Context, Ops);
4567 llvm::Value *Metadata = llvm::MetadataAsValue::get(Context, RegName);
4568
4569 llvm::Type *Types[] = { RegisterType };
4570
4571 bool MixedTypes = RegisterType->isIntegerTy(64) && ValueType->isIntegerTy(32);
4572 assert(!(RegisterType->isIntegerTy(32) && ValueType->isIntegerTy(64))
4573 && "Can't fit 64-bit value in 32-bit register");
4574
4575 if (IsRead) {
4576 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
4577 llvm::Value *Call = Builder.CreateCall(F, Metadata);
4578
4579 if (MixedTypes)
4580 // Read into 64 bit register and then truncate result to 32 bit.
4581 return Builder.CreateTrunc(Call, ValueType);
4582
4583 if (ValueType->isPointerTy())
4584 // Have i32/i64 result (Call) but want to return a VoidPtrTy (i8*).
4585 return Builder.CreateIntToPtr(Call, ValueType);
4586
4587 return Call;
4588 }
4589
4590 llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
4591 llvm::Value *ArgValue = CGF.EmitScalarExpr(E->getArg(1));
4592 if (MixedTypes) {
4593 // Extend 32 bit write value to 64 bit to pass to write.
4594 ArgValue = Builder.CreateZExt(ArgValue, RegisterType);
4595 return Builder.CreateCall(F, { Metadata, ArgValue });
4596 }
4597
4598 if (ValueType->isPointerTy()) {
4599 // Have VoidPtrTy ArgValue but want to return an i32/i64.
4600 ArgValue = Builder.CreatePtrToInt(ArgValue, RegisterType);
4601 return Builder.CreateCall(F, { Metadata, ArgValue });
4602 }
4603
4604 return Builder.CreateCall(F, { Metadata, ArgValue });
4605}
4606
Bob Wilson63c93142015-06-24 06:05:20 +00004607/// Return true if BuiltinID is an overloaded Neon intrinsic with an extra
4608/// argument that specifies the vector type.
4609static bool HasExtraNeonArgument(unsigned BuiltinID) {
4610 switch (BuiltinID) {
4611 default: break;
4612 case NEON::BI__builtin_neon_vget_lane_i8:
4613 case NEON::BI__builtin_neon_vget_lane_i16:
4614 case NEON::BI__builtin_neon_vget_lane_i32:
4615 case NEON::BI__builtin_neon_vget_lane_i64:
4616 case NEON::BI__builtin_neon_vget_lane_f32:
4617 case NEON::BI__builtin_neon_vgetq_lane_i8:
4618 case NEON::BI__builtin_neon_vgetq_lane_i16:
4619 case NEON::BI__builtin_neon_vgetq_lane_i32:
4620 case NEON::BI__builtin_neon_vgetq_lane_i64:
4621 case NEON::BI__builtin_neon_vgetq_lane_f32:
4622 case NEON::BI__builtin_neon_vset_lane_i8:
4623 case NEON::BI__builtin_neon_vset_lane_i16:
4624 case NEON::BI__builtin_neon_vset_lane_i32:
4625 case NEON::BI__builtin_neon_vset_lane_i64:
4626 case NEON::BI__builtin_neon_vset_lane_f32:
4627 case NEON::BI__builtin_neon_vsetq_lane_i8:
4628 case NEON::BI__builtin_neon_vsetq_lane_i16:
4629 case NEON::BI__builtin_neon_vsetq_lane_i32:
4630 case NEON::BI__builtin_neon_vsetq_lane_i64:
4631 case NEON::BI__builtin_neon_vsetq_lane_f32:
4632 case NEON::BI__builtin_neon_vsha1h_u32:
4633 case NEON::BI__builtin_neon_vsha1cq_u32:
4634 case NEON::BI__builtin_neon_vsha1pq_u32:
4635 case NEON::BI__builtin_neon_vsha1mq_u32:
4636 case ARM::BI_MoveToCoprocessor:
4637 case ARM::BI_MoveToCoprocessor2:
4638 return false;
4639 }
4640 return true;
4641}
4642
Saleem Abdulrasoola14ac3f42014-12-04 04:52:37 +00004643Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
4644 const CallExpr *E) {
4645 if (auto Hint = GetValueForARMHint(BuiltinID))
4646 return Hint;
Saleem Abdulrasool38ed6de2014-05-02 06:53:57 +00004647
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004648 if (BuiltinID == ARM::BI__emit) {
4649 bool IsThumb = getTarget().getTriple().getArch() == llvm::Triple::thumb;
4650 llvm::FunctionType *FTy =
4651 llvm::FunctionType::get(VoidTy, /*Variadic=*/false);
4652
4653 APSInt Value;
4654 if (!E->getArg(0)->EvaluateAsInt(Value, CGM.getContext()))
4655 llvm_unreachable("Sema will ensure that the parameter is constant");
4656
4657 uint64_t ZExtValue = Value.zextOrTrunc(IsThumb ? 16 : 32).getZExtValue();
4658
4659 llvm::InlineAsm *Emit =
4660 IsThumb ? InlineAsm::get(FTy, ".inst.n 0x" + utohexstr(ZExtValue), "",
4661 /*SideEffects=*/true)
4662 : InlineAsm::get(FTy, ".inst 0x" + utohexstr(ZExtValue), "",
4663 /*SideEffects=*/true);
4664
David Blaikie4ba525b2015-07-14 17:27:39 +00004665 return Builder.CreateCall(Emit);
Saleem Abdulrasool86b881c2014-12-17 17:52:30 +00004666 }
4667
Yi Kong1d268af2014-08-26 12:48:06 +00004668 if (BuiltinID == ARM::BI__builtin_arm_dbg) {
4669 Value *Option = EmitScalarExpr(E->getArg(0));
4670 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_dbg), Option);
4671 }
4672
Yi Kong26d104a2014-08-13 19:18:14 +00004673 if (BuiltinID == ARM::BI__builtin_arm_prefetch) {
4674 Value *Address = EmitScalarExpr(E->getArg(0));
4675 Value *RW = EmitScalarExpr(E->getArg(1));
4676 Value *IsData = EmitScalarExpr(E->getArg(2));
4677
4678 // Locality is not supported on ARM target
4679 Value *Locality = llvm::ConstantInt::get(Int32Ty, 3);
4680
4681 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00004682 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Kong26d104a2014-08-13 19:18:14 +00004683 }
4684
Jim Grosbach171ec342014-06-16 21:55:58 +00004685 if (BuiltinID == ARM::BI__builtin_arm_rbit) {
Chad Rosierc22abb32017-01-10 18:55:11 +00004686 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
4687 return Builder.CreateCall(
4688 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach171ec342014-06-16 21:55:58 +00004689 }
4690
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004691 if (BuiltinID == ARM::BI__clear_cache) {
Rafael Espindola2219fc52013-05-14 12:45:47 +00004692 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
Rafael Espindolaa54062e2010-06-07 17:26:50 +00004693 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00004694 Value *Ops[2];
Rafael Espindola2219fc52013-05-14 12:45:47 +00004695 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00004696 Ops[i] = EmitScalarExpr(E->getArg(i));
Chris Lattner2192fe52011-07-18 04:24:23 +00004697 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
4698 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
Chris Lattner0e62c1c2011-07-23 10:55:15 +00004699 StringRef Name = FD->getName();
John McCall882987f2013-02-28 19:01:20 +00004700 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
Chris Lattner5cc15e02010-03-03 19:03:45 +00004701 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00004702
Ranjeet Singhca2b3e7b2016-06-17 00:59:41 +00004703 if (BuiltinID == ARM::BI__builtin_arm_mcrr ||
4704 BuiltinID == ARM::BI__builtin_arm_mcrr2) {
4705 Function *F;
4706
4707 switch (BuiltinID) {
4708 default: llvm_unreachable("unexpected builtin");
4709 case ARM::BI__builtin_arm_mcrr:
4710 F = CGM.getIntrinsic(Intrinsic::arm_mcrr);
4711 break;
4712 case ARM::BI__builtin_arm_mcrr2:
4713 F = CGM.getIntrinsic(Intrinsic::arm_mcrr2);
4714 break;
4715 }
4716
4717 // MCRR{2} instruction has 5 operands but
4718 // the intrinsic has 4 because Rt and Rt2
4719 // are represented as a single unsigned 64
4720 // bit integer in the intrinsic definition
4721 // but internally it's represented as 2 32
4722 // bit integers.
4723
4724 Value *Coproc = EmitScalarExpr(E->getArg(0));
4725 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4726 Value *RtAndRt2 = EmitScalarExpr(E->getArg(2));
4727 Value *CRm = EmitScalarExpr(E->getArg(3));
4728
4729 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4730 Value *Rt = Builder.CreateTruncOrBitCast(RtAndRt2, Int32Ty);
4731 Value *Rt2 = Builder.CreateLShr(RtAndRt2, C1);
4732 Rt2 = Builder.CreateTruncOrBitCast(Rt2, Int32Ty);
4733
4734 return Builder.CreateCall(F, {Coproc, Opc1, Rt, Rt2, CRm});
4735 }
4736
4737 if (BuiltinID == ARM::BI__builtin_arm_mrrc ||
4738 BuiltinID == ARM::BI__builtin_arm_mrrc2) {
4739 Function *F;
4740
4741 switch (BuiltinID) {
4742 default: llvm_unreachable("unexpected builtin");
4743 case ARM::BI__builtin_arm_mrrc:
4744 F = CGM.getIntrinsic(Intrinsic::arm_mrrc);
4745 break;
4746 case ARM::BI__builtin_arm_mrrc2:
4747 F = CGM.getIntrinsic(Intrinsic::arm_mrrc2);
4748 break;
4749 }
4750
4751 Value *Coproc = EmitScalarExpr(E->getArg(0));
4752 Value *Opc1 = EmitScalarExpr(E->getArg(1));
4753 Value *CRm = EmitScalarExpr(E->getArg(2));
4754 Value *RtAndRt2 = Builder.CreateCall(F, {Coproc, Opc1, CRm});
4755
4756 // Returns an unsigned 64 bit integer, represented
4757 // as two 32 bit integers.
4758
4759 Value *Rt = Builder.CreateExtractValue(RtAndRt2, 1);
4760 Value *Rt1 = Builder.CreateExtractValue(RtAndRt2, 0);
4761 Rt = Builder.CreateZExt(Rt, Int64Ty);
4762 Rt1 = Builder.CreateZExt(Rt1, Int64Ty);
4763
4764 Value *ShiftCast = llvm::ConstantInt::get(Int64Ty, 32);
4765 RtAndRt2 = Builder.CreateShl(Rt, ShiftCast, "shl", true);
4766 RtAndRt2 = Builder.CreateOr(RtAndRt2, Rt1);
4767
4768 return Builder.CreateBitCast(RtAndRt2, ConvertType(E->getType()));
4769 }
4770
Tim Northover6aacd492013-07-16 09:47:53 +00004771 if (BuiltinID == ARM::BI__builtin_arm_ldrexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004772 ((BuiltinID == ARM::BI__builtin_arm_ldrex ||
4773 BuiltinID == ARM::BI__builtin_arm_ldaex) &&
Saleem Abdulrasoole700cab2014-07-05 20:10:05 +00004774 getContext().getTypeSize(E->getType()) == 64) ||
4775 BuiltinID == ARM::BI__ldrexd) {
4776 Function *F;
4777
4778 switch (BuiltinID) {
4779 default: llvm_unreachable("unexpected builtin");
4780 case ARM::BI__builtin_arm_ldaex:
4781 F = CGM.getIntrinsic(Intrinsic::arm_ldaexd);
4782 break;
4783 case ARM::BI__builtin_arm_ldrexd:
4784 case ARM::BI__builtin_arm_ldrex:
4785 case ARM::BI__ldrexd:
4786 F = CGM.getIntrinsic(Intrinsic::arm_ldrexd);
4787 break;
4788 }
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004789
4790 Value *LdPtr = EmitScalarExpr(E->getArg(0));
Tim Northover6aacd492013-07-16 09:47:53 +00004791 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
4792 "ldrexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004793
4794 Value *Val0 = Builder.CreateExtractValue(Val, 1);
4795 Value *Val1 = Builder.CreateExtractValue(Val, 0);
4796 Val0 = Builder.CreateZExt(Val0, Int64Ty);
4797 Val1 = Builder.CreateZExt(Val1, Int64Ty);
4798
4799 Value *ShiftCst = llvm::ConstantInt::get(Int64Ty, 32);
4800 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
Tim Northover6aacd492013-07-16 09:47:53 +00004801 Val = Builder.CreateOr(Val, Val1);
4802 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004803 }
4804
Tim Northover3acd6bd2014-07-02 12:56:02 +00004805 if (BuiltinID == ARM::BI__builtin_arm_ldrex ||
4806 BuiltinID == ARM::BI__builtin_arm_ldaex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004807 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
4808
4809 QualType Ty = E->getType();
4810 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004811 llvm::Type *PtrTy = llvm::IntegerType::get(
4812 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
4813 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004814
Tim Northover3acd6bd2014-07-02 12:56:02 +00004815 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_ldaex
4816 ? Intrinsic::arm_ldaex
4817 : Intrinsic::arm_ldrex,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004818 PtrTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004819 Value *Val = Builder.CreateCall(F, LoadAddr, "ldrex");
4820
4821 if (RealResTy->isPointerTy())
4822 return Builder.CreateIntToPtr(Val, RealResTy);
4823 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004824 llvm::Type *IntResTy = llvm::IntegerType::get(
4825 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northover6aacd492013-07-16 09:47:53 +00004826 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
4827 return Builder.CreateBitCast(Val, RealResTy);
4828 }
4829 }
4830
4831 if (BuiltinID == ARM::BI__builtin_arm_strexd ||
Tim Northover3acd6bd2014-07-02 12:56:02 +00004832 ((BuiltinID == ARM::BI__builtin_arm_stlex ||
4833 BuiltinID == ARM::BI__builtin_arm_strex) &&
Tim Northover6aacd492013-07-16 09:47:53 +00004834 getContext().getTypeSize(E->getArg(0)->getType()) == 64)) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00004835 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4836 ? Intrinsic::arm_stlexd
4837 : Intrinsic::arm_strexd);
Serge Guelton1d993272017-05-09 19:31:30 +00004838 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty);
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004839
John McCall7f416cc2015-09-08 08:05:57 +00004840 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004841 Value *Val = EmitScalarExpr(E->getArg(0));
4842 Builder.CreateStore(Val, Tmp);
4843
John McCall7f416cc2015-09-08 08:05:57 +00004844 Address LdPtr = Builder.CreateBitCast(Tmp,llvm::PointerType::getUnqual(STy));
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004845 Val = Builder.CreateLoad(LdPtr);
4846
4847 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
4848 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
Tim Northover6aacd492013-07-16 09:47:53 +00004849 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00004850 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "strexd");
Bruno Cardoso Lopesfe733742011-05-28 04:11:33 +00004851 }
4852
Tim Northover3acd6bd2014-07-02 12:56:02 +00004853 if (BuiltinID == ARM::BI__builtin_arm_strex ||
4854 BuiltinID == ARM::BI__builtin_arm_stlex) {
Tim Northover6aacd492013-07-16 09:47:53 +00004855 Value *StoreVal = EmitScalarExpr(E->getArg(0));
4856 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
4857
4858 QualType Ty = E->getArg(0)->getType();
4859 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
4860 getContext().getTypeSize(Ty));
4861 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
4862
4863 if (StoreVal->getType()->isPointerTy())
4864 StoreVal = Builder.CreatePtrToInt(StoreVal, Int32Ty);
4865 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00004866 llvm::Type *IntTy = llvm::IntegerType::get(
4867 getLLVMContext(),
4868 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
4869 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northover6aacd492013-07-16 09:47:53 +00004870 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int32Ty);
4871 }
4872
Tim Northover3acd6bd2014-07-02 12:56:02 +00004873 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
4874 ? Intrinsic::arm_stlex
4875 : Intrinsic::arm_strex,
4876 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00004877 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "strex");
Tim Northover6aacd492013-07-16 09:47:53 +00004878 }
4879
Martin Storsjoed95a082016-09-30 19:13:46 +00004880 switch (BuiltinID) {
4881 case ARM::BI__iso_volatile_load8:
4882 case ARM::BI__iso_volatile_load16:
4883 case ARM::BI__iso_volatile_load32:
4884 case ARM::BI__iso_volatile_load64: {
4885 Value *Ptr = EmitScalarExpr(E->getArg(0));
4886 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4887 CharUnits LoadSize = getContext().getTypeSizeInChars(ElTy);
4888 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4889 LoadSize.getQuantity() * 8);
4890 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4891 llvm::LoadInst *Load =
4892 Builder.CreateAlignedLoad(Ptr, LoadSize);
4893 Load->setVolatile(true);
4894 return Load;
4895 }
4896 case ARM::BI__iso_volatile_store8:
4897 case ARM::BI__iso_volatile_store16:
4898 case ARM::BI__iso_volatile_store32:
4899 case ARM::BI__iso_volatile_store64: {
4900 Value *Ptr = EmitScalarExpr(E->getArg(0));
4901 Value *Value = EmitScalarExpr(E->getArg(1));
4902 QualType ElTy = E->getArg(0)->getType()->getPointeeType();
4903 CharUnits StoreSize = getContext().getTypeSizeInChars(ElTy);
4904 llvm::Type *ITy = llvm::IntegerType::get(getLLVMContext(),
4905 StoreSize.getQuantity() * 8);
4906 Ptr = Builder.CreateBitCast(Ptr, ITy->getPointerTo());
4907 llvm::StoreInst *Store =
4908 Builder.CreateAlignedStore(Value, Ptr,
4909 StoreSize);
4910 Store->setVolatile(true);
4911 return Store;
4912 }
4913 }
4914
Tim Northover6aacd492013-07-16 09:47:53 +00004915 if (BuiltinID == ARM::BI__builtin_arm_clrex) {
4916 Function *F = CGM.getIntrinsic(Intrinsic::arm_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00004917 return Builder.CreateCall(F);
Tim Northover6aacd492013-07-16 09:47:53 +00004918 }
4919
Joey Gouly1e8637b2013-09-18 10:07:09 +00004920 // CRC32
4921 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
4922 switch (BuiltinID) {
4923 case ARM::BI__builtin_arm_crc32b:
4924 CRCIntrinsicID = Intrinsic::arm_crc32b; break;
4925 case ARM::BI__builtin_arm_crc32cb:
4926 CRCIntrinsicID = Intrinsic::arm_crc32cb; break;
4927 case ARM::BI__builtin_arm_crc32h:
4928 CRCIntrinsicID = Intrinsic::arm_crc32h; break;
4929 case ARM::BI__builtin_arm_crc32ch:
4930 CRCIntrinsicID = Intrinsic::arm_crc32ch; break;
4931 case ARM::BI__builtin_arm_crc32w:
4932 case ARM::BI__builtin_arm_crc32d:
4933 CRCIntrinsicID = Intrinsic::arm_crc32w; break;
4934 case ARM::BI__builtin_arm_crc32cw:
4935 case ARM::BI__builtin_arm_crc32cd:
4936 CRCIntrinsicID = Intrinsic::arm_crc32cw; break;
4937 }
4938
4939 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
4940 Value *Arg0 = EmitScalarExpr(E->getArg(0));
4941 Value *Arg1 = EmitScalarExpr(E->getArg(1));
4942
4943 // crc32{c,}d intrinsics are implemnted as two calls to crc32{c,}w
4944 // intrinsics, hence we need different codegen for these cases.
4945 if (BuiltinID == ARM::BI__builtin_arm_crc32d ||
4946 BuiltinID == ARM::BI__builtin_arm_crc32cd) {
4947 Value *C1 = llvm::ConstantInt::get(Int64Ty, 32);
4948 Value *Arg1a = Builder.CreateTruncOrBitCast(Arg1, Int32Ty);
4949 Value *Arg1b = Builder.CreateLShr(Arg1, C1);
4950 Arg1b = Builder.CreateTruncOrBitCast(Arg1b, Int32Ty);
4951
4952 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004953 Value *Res = Builder.CreateCall(F, {Arg0, Arg1a});
4954 return Builder.CreateCall(F, {Res, Arg1b});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004955 } else {
4956 Arg1 = Builder.CreateZExtOrBitCast(Arg1, Int32Ty);
4957
4958 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
David Blaikie43f9bb72015-05-18 22:14:03 +00004959 return Builder.CreateCall(F, {Arg0, Arg1});
Joey Gouly1e8637b2013-09-18 10:07:09 +00004960 }
4961 }
4962
Luke Cheeseman59b2d832015-06-15 17:51:01 +00004963 if (BuiltinID == ARM::BI__builtin_arm_rsr ||
4964 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4965 BuiltinID == ARM::BI__builtin_arm_rsrp ||
4966 BuiltinID == ARM::BI__builtin_arm_wsr ||
4967 BuiltinID == ARM::BI__builtin_arm_wsr64 ||
4968 BuiltinID == ARM::BI__builtin_arm_wsrp) {
4969
4970 bool IsRead = BuiltinID == ARM::BI__builtin_arm_rsr ||
4971 BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4972 BuiltinID == ARM::BI__builtin_arm_rsrp;
4973
4974 bool IsPointerBuiltin = BuiltinID == ARM::BI__builtin_arm_rsrp ||
4975 BuiltinID == ARM::BI__builtin_arm_wsrp;
4976
4977 bool Is64Bit = BuiltinID == ARM::BI__builtin_arm_rsr64 ||
4978 BuiltinID == ARM::BI__builtin_arm_wsr64;
4979
4980 llvm::Type *ValueType;
4981 llvm::Type *RegisterType;
4982 if (IsPointerBuiltin) {
4983 ValueType = VoidPtrTy;
4984 RegisterType = Int32Ty;
4985 } else if (Is64Bit) {
4986 ValueType = RegisterType = Int64Ty;
4987 } else {
4988 ValueType = RegisterType = Int32Ty;
4989 }
4990
4991 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
4992 }
4993
Ahmed Bougacha94df7302015-06-04 01:43:41 +00004994 // Find out if any arguments are required to be integer constant
4995 // expressions.
4996 unsigned ICEArguments = 0;
4997 ASTContext::GetBuiltinTypeError Error;
4998 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
4999 assert(Error == ASTContext::GE_None && "Should not codegen an error");
5000
John McCall7f416cc2015-09-08 08:05:57 +00005001 auto getAlignmentValue32 = [&](Address addr) -> Value* {
5002 return Builder.getInt32(addr.getAlignment().getQuantity());
5003 };
5004
5005 Address PtrOp0 = Address::invalid();
5006 Address PtrOp1 = Address::invalid();
Chris Lattner0e62c1c2011-07-23 10:55:15 +00005007 SmallVector<Value*, 4> Ops;
Bob Wilson63c93142015-06-24 06:05:20 +00005008 bool HasExtraArg = HasExtraNeonArgument(BuiltinID);
5009 unsigned NumArgs = E->getNumArgs() - (HasExtraArg ? 1 : 0);
5010 for (unsigned i = 0, e = NumArgs; i != e; i++) {
Eli Friedmana5dd5682012-08-23 03:10:17 +00005011 if (i == 0) {
5012 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005013 case NEON::BI__builtin_neon_vld1_v:
5014 case NEON::BI__builtin_neon_vld1q_v:
5015 case NEON::BI__builtin_neon_vld1q_lane_v:
5016 case NEON::BI__builtin_neon_vld1_lane_v:
5017 case NEON::BI__builtin_neon_vld1_dup_v:
5018 case NEON::BI__builtin_neon_vld1q_dup_v:
5019 case NEON::BI__builtin_neon_vst1_v:
5020 case NEON::BI__builtin_neon_vst1q_v:
5021 case NEON::BI__builtin_neon_vst1q_lane_v:
5022 case NEON::BI__builtin_neon_vst1_lane_v:
5023 case NEON::BI__builtin_neon_vst2_v:
5024 case NEON::BI__builtin_neon_vst2q_v:
5025 case NEON::BI__builtin_neon_vst2_lane_v:
5026 case NEON::BI__builtin_neon_vst2q_lane_v:
5027 case NEON::BI__builtin_neon_vst3_v:
5028 case NEON::BI__builtin_neon_vst3q_v:
5029 case NEON::BI__builtin_neon_vst3_lane_v:
5030 case NEON::BI__builtin_neon_vst3q_lane_v:
5031 case NEON::BI__builtin_neon_vst4_v:
5032 case NEON::BI__builtin_neon_vst4q_v:
5033 case NEON::BI__builtin_neon_vst4_lane_v:
5034 case NEON::BI__builtin_neon_vst4q_lane_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00005035 // Get the alignment for the argument in addition to the value;
5036 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00005037 PtrOp0 = EmitPointerWithAlignment(E->getArg(0));
5038 Ops.push_back(PtrOp0.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00005039 continue;
5040 }
5041 }
5042 if (i == 1) {
5043 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005044 case NEON::BI__builtin_neon_vld2_v:
5045 case NEON::BI__builtin_neon_vld2q_v:
5046 case NEON::BI__builtin_neon_vld3_v:
5047 case NEON::BI__builtin_neon_vld3q_v:
5048 case NEON::BI__builtin_neon_vld4_v:
5049 case NEON::BI__builtin_neon_vld4q_v:
5050 case NEON::BI__builtin_neon_vld2_lane_v:
5051 case NEON::BI__builtin_neon_vld2q_lane_v:
5052 case NEON::BI__builtin_neon_vld3_lane_v:
5053 case NEON::BI__builtin_neon_vld3q_lane_v:
5054 case NEON::BI__builtin_neon_vld4_lane_v:
5055 case NEON::BI__builtin_neon_vld4q_lane_v:
5056 case NEON::BI__builtin_neon_vld2_dup_v:
5057 case NEON::BI__builtin_neon_vld3_dup_v:
5058 case NEON::BI__builtin_neon_vld4_dup_v:
Eli Friedmana5dd5682012-08-23 03:10:17 +00005059 // Get the alignment for the argument in addition to the value;
5060 // we'll use it later.
John McCall7f416cc2015-09-08 08:05:57 +00005061 PtrOp1 = EmitPointerWithAlignment(E->getArg(1));
5062 Ops.push_back(PtrOp1.getPointer());
Eli Friedmana5dd5682012-08-23 03:10:17 +00005063 continue;
5064 }
5065 }
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005066
5067 if ((ICEArguments & (1 << i)) == 0) {
5068 Ops.push_back(EmitScalarExpr(E->getArg(i)));
5069 } else {
5070 // If this is required to be a constant, constant fold it so that we know
5071 // that the generated intrinsic gets a ConstantInt.
5072 llvm::APSInt Result;
5073 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
5074 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
5075 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
5076 }
Eli Friedmana5dd5682012-08-23 03:10:17 +00005077 }
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005078
Bob Wilson445c24f2011-08-13 05:03:46 +00005079 switch (BuiltinID) {
5080 default: break;
Bob Wilson63c93142015-06-24 06:05:20 +00005081
Tim Northoverc322f832014-01-30 14:47:51 +00005082 case NEON::BI__builtin_neon_vget_lane_i8:
5083 case NEON::BI__builtin_neon_vget_lane_i16:
5084 case NEON::BI__builtin_neon_vget_lane_i32:
5085 case NEON::BI__builtin_neon_vget_lane_i64:
5086 case NEON::BI__builtin_neon_vget_lane_f32:
5087 case NEON::BI__builtin_neon_vgetq_lane_i8:
5088 case NEON::BI__builtin_neon_vgetq_lane_i16:
5089 case NEON::BI__builtin_neon_vgetq_lane_i32:
5090 case NEON::BI__builtin_neon_vgetq_lane_i64:
5091 case NEON::BI__builtin_neon_vgetq_lane_f32:
Bob Wilson63c93142015-06-24 06:05:20 +00005092 return Builder.CreateExtractElement(Ops[0], Ops[1], "vget_lane");
5093
Tim Northoverc322f832014-01-30 14:47:51 +00005094 case NEON::BI__builtin_neon_vset_lane_i8:
5095 case NEON::BI__builtin_neon_vset_lane_i16:
5096 case NEON::BI__builtin_neon_vset_lane_i32:
5097 case NEON::BI__builtin_neon_vset_lane_i64:
5098 case NEON::BI__builtin_neon_vset_lane_f32:
5099 case NEON::BI__builtin_neon_vsetq_lane_i8:
5100 case NEON::BI__builtin_neon_vsetq_lane_i16:
5101 case NEON::BI__builtin_neon_vsetq_lane_i32:
5102 case NEON::BI__builtin_neon_vsetq_lane_i64:
5103 case NEON::BI__builtin_neon_vsetq_lane_f32:
Bob Wilson445c24f2011-08-13 05:03:46 +00005104 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
Tim Northover02e38602014-02-03 17:28:04 +00005105
Tim Northover02e38602014-02-03 17:28:04 +00005106 case NEON::BI__builtin_neon_vsha1h_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005107 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1h), Ops,
5108 "vsha1h");
5109 case NEON::BI__builtin_neon_vsha1cq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005110 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1c), Ops,
5111 "vsha1h");
5112 case NEON::BI__builtin_neon_vsha1pq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005113 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1p), Ops,
5114 "vsha1h");
5115 case NEON::BI__builtin_neon_vsha1mq_u32:
Tim Northover02e38602014-02-03 17:28:04 +00005116 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_sha1m), Ops,
5117 "vsha1h");
Bob Wilson63c93142015-06-24 06:05:20 +00005118
5119 // The ARM _MoveToCoprocessor builtins put the input register value as
Simon Pilgrim532de1c2016-06-13 10:05:19 +00005120 // the first argument, but the LLVM intrinsic expects it as the third one.
5121 case ARM::BI_MoveToCoprocessor:
5122 case ARM::BI_MoveToCoprocessor2: {
5123 Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI_MoveToCoprocessor ?
5124 Intrinsic::arm_mcr : Intrinsic::arm_mcr2);
5125 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0],
5126 Ops[3], Ops[4], Ops[5]});
Bob Wilson63c93142015-06-24 06:05:20 +00005127 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00005128 case ARM::BI_BitScanForward:
5129 case ARM::BI_BitScanForward64:
5130 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
5131 case ARM::BI_BitScanReverse:
5132 case ARM::BI_BitScanReverse64:
5133 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00005134
5135 case ARM::BI_InterlockedAnd64:
5136 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
5137 case ARM::BI_InterlockedExchange64:
5138 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
5139 case ARM::BI_InterlockedExchangeAdd64:
5140 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
5141 case ARM::BI_InterlockedExchangeSub64:
5142 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
5143 case ARM::BI_InterlockedOr64:
5144 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
5145 case ARM::BI_InterlockedXor64:
5146 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
5147 case ARM::BI_InterlockedDecrement64:
5148 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
5149 case ARM::BI_InterlockedIncrement64:
5150 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
Bob Wilson445c24f2011-08-13 05:03:46 +00005151 }
5152
5153 // Get the last argument, which specifies the vector type.
Bob Wilson63c93142015-06-24 06:05:20 +00005154 assert(HasExtraArg);
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005155 llvm::APSInt Result;
5156 const Expr *Arg = E->getArg(E->getNumArgs()-1);
5157 if (!Arg->isIntegerConstantExpr(Result, getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00005158 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005159
Nate Begemanf568b072010-08-03 21:32:34 +00005160 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f ||
5161 BuiltinID == ARM::BI__builtin_arm_vcvtr_d) {
5162 // Determine the overloaded type of this builtin.
Chris Lattnera5f58b02011-07-09 17:41:47 +00005163 llvm::Type *Ty;
Nate Begemanf568b072010-08-03 21:32:34 +00005164 if (BuiltinID == ARM::BI__builtin_arm_vcvtr_f)
Chris Lattnerece04092012-02-07 00:39:47 +00005165 Ty = FloatTy;
Nate Begemanf568b072010-08-03 21:32:34 +00005166 else
Chris Lattnerece04092012-02-07 00:39:47 +00005167 Ty = DoubleTy;
Jim Grosbachd3608f42012-09-21 00:18:27 +00005168
Nate Begemanf568b072010-08-03 21:32:34 +00005169 // Determine whether this is an unsigned conversion or not.
5170 bool usgn = Result.getZExtValue() == 1;
5171 unsigned Int = usgn ? Intrinsic::arm_vcvtru : Intrinsic::arm_vcvtr;
5172
5173 // Call the appropriate intrinsic.
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005174 Function *F = CGM.getIntrinsic(Int, Ty);
Jay Foad5bd375a2011-07-15 08:37:34 +00005175 return Builder.CreateCall(F, Ops, "vcvtr");
Nate Begemanf568b072010-08-03 21:32:34 +00005176 }
Jim Grosbachd3608f42012-09-21 00:18:27 +00005177
Nate Begemanf568b072010-08-03 21:32:34 +00005178 // Determine the type of this overloaded NEON intrinsic.
Bob Wilson98bc98c2011-11-08 01:16:11 +00005179 NeonTypeFlags Type(Result.getZExtValue());
5180 bool usgn = Type.isUnsigned();
Bob Wilson4fa993f2010-12-03 17:10:22 +00005181 bool rightShift = false;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005182
Chris Lattnerece04092012-02-07 00:39:47 +00005183 llvm::VectorType *VTy = GetNeonType(this, Type);
Chris Lattnera5f58b02011-07-09 17:41:47 +00005184 llvm::Type *Ty = VTy;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005185 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00005186 return nullptr;
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005187
Tim Northoverac85c342014-01-30 14:47:57 +00005188 // Many NEON builtins have identical semantics and uses in ARM and
5189 // AArch64. Emit these in a single function.
Craig Topper5fc8fc22014-08-27 06:28:36 +00005190 auto IntrinsicMap = makeArrayRef(ARMSIMDIntrinsicMap);
Tim Northover8fe03d62014-02-21 11:57:24 +00005191 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
5192 IntrinsicMap, BuiltinID, NEONSIMDIntrinsicsProvenSorted);
5193 if (Builtin)
5194 return EmitCommonNeonBuiltinExpr(
5195 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00005196 Builtin->NameHint, Builtin->TypeModifier, E, Ops, PtrOp0, PtrOp1);
Tim Northoverac85c342014-01-30 14:47:57 +00005197
Rafael Espindola6bb986d2010-06-09 03:48:40 +00005198 unsigned Int;
5199 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00005200 default: return nullptr;
Tim Northoverc322f832014-01-30 14:47:51 +00005201 case NEON::BI__builtin_neon_vld1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005202 // Handle 64-bit integer elements as a special case. Use shuffles of
5203 // one-element vectors to avoid poor code for i64 in the backend.
5204 if (VTy->getElementType()->isIntegerTy(64)) {
5205 // Extract the other lane.
5206 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00005207 uint32_t Lane = cast<ConstantInt>(Ops[2])->getZExtValue();
Bob Wilson2605fef2012-08-14 17:27:04 +00005208 Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane));
5209 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
5210 // Load the value as a one-element vector.
5211 Ty = llvm::VectorType::get(VTy->getElementType(), 1);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005212 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5213 Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005214 Value *Align = getAlignmentValue32(PtrOp0);
David Blaikie43f9bb72015-05-18 22:14:03 +00005215 Value *Ld = Builder.CreateCall(F, {Ops[0], Align});
Bob Wilson2605fef2012-08-14 17:27:04 +00005216 // Combine them.
Benjamin Kramerc385a802015-07-28 15:40:11 +00005217 uint32_t Indices[] = {1 - Lane, Lane};
5218 SV = llvm::ConstantDataVector::get(getLLVMContext(), Indices);
Bob Wilson2605fef2012-08-14 17:27:04 +00005219 return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane");
5220 }
5221 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005222 case NEON::BI__builtin_neon_vld1_lane_v: {
Nate Begemaned48c852010-06-20 23:05:28 +00005223 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
Steven Wu0d22f2d2015-09-09 01:37:18 +00005224 PtrOp0 = Builder.CreateElementBitCast(PtrOp0, VTy->getElementType());
John McCall7f416cc2015-09-08 08:05:57 +00005225 Value *Ld = Builder.CreateLoad(PtrOp0);
Bob Wilson49708d42012-02-04 23:58:08 +00005226 return Builder.CreateInsertElement(Ops[1], Ld, Ops[2], "vld1_lane");
5227 }
Tim Northoverc322f832014-01-30 14:47:51 +00005228 case NEON::BI__builtin_neon_vld2_dup_v:
5229 case NEON::BI__builtin_neon_vld3_dup_v:
5230 case NEON::BI__builtin_neon_vld4_dup_v: {
Bob Wilson0348af62010-12-10 22:54:58 +00005231 // Handle 64-bit elements as a special-case. There is no "dup" needed.
5232 if (VTy->getElementType()->getPrimitiveSizeInBits() == 64) {
5233 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005234 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005235 Int = Intrinsic::arm_neon_vld2;
Bob Wilson0348af62010-12-10 22:54:58 +00005236 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005237 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005238 Int = Intrinsic::arm_neon_vld3;
Bob Wilson0348af62010-12-10 22:54:58 +00005239 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005240 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005241 Int = Intrinsic::arm_neon_vld4;
Bob Wilson0348af62010-12-10 22:54:58 +00005242 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005243 default: llvm_unreachable("unknown vld_dup intrinsic?");
Bob Wilson0348af62010-12-10 22:54:58 +00005244 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005245 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5246 Function *F = CGM.getIntrinsic(Int, Tys);
John McCall7f416cc2015-09-08 08:05:57 +00005247 llvm::Value *Align = getAlignmentValue32(PtrOp1);
David Blaikie43f9bb72015-05-18 22:14:03 +00005248 Ops[1] = Builder.CreateCall(F, {Ops[1], Align}, "vld_dup");
Bob Wilson0348af62010-12-10 22:54:58 +00005249 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5250 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005251 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Bob Wilson0348af62010-12-10 22:54:58 +00005252 }
Nate Begemaned48c852010-06-20 23:05:28 +00005253 switch (BuiltinID) {
Tim Northoverc322f832014-01-30 14:47:51 +00005254 case NEON::BI__builtin_neon_vld2_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005255 Int = Intrinsic::arm_neon_vld2lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005256 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005257 case NEON::BI__builtin_neon_vld3_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005258 Int = Intrinsic::arm_neon_vld3lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005259 break;
Tim Northoverc322f832014-01-30 14:47:51 +00005260 case NEON::BI__builtin_neon_vld4_dup_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005261 Int = Intrinsic::arm_neon_vld4lane;
Nate Begemaned48c852010-06-20 23:05:28 +00005262 break;
David Blaikie83d382b2011-09-23 05:06:16 +00005263 default: llvm_unreachable("unknown vld_dup intrinsic?");
Nate Begemaned48c852010-06-20 23:05:28 +00005264 }
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005265 llvm::Type *Tys[] = {Ty, Int8PtrTy};
5266 Function *F = CGM.getIntrinsic(Int, Tys);
Chris Lattner2192fe52011-07-18 04:24:23 +00005267 llvm::StructType *STy = cast<llvm::StructType>(F->getReturnType());
Jim Grosbachd3608f42012-09-21 00:18:27 +00005268
Nate Begemaned48c852010-06-20 23:05:28 +00005269 SmallVector<Value*, 6> Args;
5270 Args.push_back(Ops[1]);
5271 Args.append(STy->getNumElements(), UndefValue::get(Ty));
5272
Chris Lattner5e016ae2010-06-27 07:15:29 +00005273 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Nate Begemaned48c852010-06-20 23:05:28 +00005274 Args.push_back(CI);
John McCall7f416cc2015-09-08 08:05:57 +00005275 Args.push_back(getAlignmentValue32(PtrOp1));
Jim Grosbachd3608f42012-09-21 00:18:27 +00005276
Jay Foad5bd375a2011-07-15 08:37:34 +00005277 Ops[1] = Builder.CreateCall(F, Args, "vld_dup");
Nate Begemaned48c852010-06-20 23:05:28 +00005278 // splat lane 0 to all elts in each vector of the result.
5279 for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
5280 Value *Val = Builder.CreateExtractValue(Ops[1], i);
5281 Value *Elt = Builder.CreateBitCast(Val, Ty);
5282 Elt = EmitNeonSplat(Elt, CI);
5283 Elt = Builder.CreateBitCast(Elt, Val->getType());
5284 Ops[1] = Builder.CreateInsertValue(Ops[1], Elt, i);
5285 }
5286 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
5287 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00005288 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begemaned48c852010-06-20 23:05:28 +00005289 }
Tim Northoverc322f832014-01-30 14:47:51 +00005290 case NEON::BI__builtin_neon_vqrshrn_n_v:
Jim Grosbachd3608f42012-09-21 00:18:27 +00005291 Int =
5292 usgn ? Intrinsic::arm_neon_vqrshiftnu : Intrinsic::arm_neon_vqrshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005293 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005294 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005295 case NEON::BI__builtin_neon_vqrshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005296 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqrshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005297 Ops, "vqrshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005298 case NEON::BI__builtin_neon_vqshrn_n_v:
Nate Begeman91e1fea2010-06-14 05:21:25 +00005299 Int = usgn ? Intrinsic::arm_neon_vqshiftnu : Intrinsic::arm_neon_vqshiftns;
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005300 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n",
Nate Begeman91e1fea2010-06-14 05:21:25 +00005301 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005302 case NEON::BI__builtin_neon_vqshrun_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005303 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vqshiftnsu, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005304 Ops, "vqshrun_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005305 case NEON::BI__builtin_neon_vrecpe_v:
5306 case NEON::BI__builtin_neon_vrecpeq_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005307 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrecpe, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005308 Ops, "vrecpe");
Tim Northoverc322f832014-01-30 14:47:51 +00005309 case NEON::BI__builtin_neon_vrshrn_n_v:
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005310 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vrshiftn, Ty),
Bob Wilson482afae2010-12-08 22:37:56 +00005311 Ops, "vrshrn_n", 1, true);
Tim Northoverc322f832014-01-30 14:47:51 +00005312 case NEON::BI__builtin_neon_vrsra_n_v:
5313 case NEON::BI__builtin_neon_vrsraq_n_v:
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005314 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
5315 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5316 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, true);
5317 Int = usgn ? Intrinsic::arm_neon_vrshiftu : Intrinsic::arm_neon_vrshifts;
David Blaikie43f9bb72015-05-18 22:14:03 +00005318 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Ty), {Ops[1], Ops[2]});
Nate Begemanc6ac0ce2010-06-12 06:06:07 +00005319 return Builder.CreateAdd(Ops[0], Ops[1], "vrsra_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005320 case NEON::BI__builtin_neon_vsri_n_v:
5321 case NEON::BI__builtin_neon_vsriq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005322 rightShift = true;
Galina Kistanova0872d6c2017-06-03 06:30:46 +00005323 LLVM_FALLTHROUGH;
Tim Northoverc322f832014-01-30 14:47:51 +00005324 case NEON::BI__builtin_neon_vsli_n_v:
5325 case NEON::BI__builtin_neon_vsliq_n_v:
Bob Wilson4fa993f2010-12-03 17:10:22 +00005326 Ops[2] = EmitNeonShiftVector(Ops[2], Ty, rightShift);
Benjamin Kramer8d375ce2011-07-14 17:45:50 +00005327 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vshiftins, Ty),
Nate Begeman8ed060b2010-06-11 22:57:12 +00005328 Ops, "vsli_n");
Tim Northoverc322f832014-01-30 14:47:51 +00005329 case NEON::BI__builtin_neon_vsra_n_v:
5330 case NEON::BI__builtin_neon_vsraq_n_v:
Nate Begeman8ed060b2010-06-11 22:57:12 +00005331 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Amaury de la Vieuville21bf6ed2013-10-04 13:13:15 +00005332 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
Nate Begeman8ed060b2010-06-11 22:57:12 +00005333 return Builder.CreateAdd(Ops[0], Ops[1]);
Tim Northoverc322f832014-01-30 14:47:51 +00005334 case NEON::BI__builtin_neon_vst1q_lane_v:
Bob Wilson2605fef2012-08-14 17:27:04 +00005335 // Handle 64-bit integer elements as a special case. Use a shuffle to get
5336 // a one-element vector and avoid poor code for i64 in the backend.
5337 if (VTy->getElementType()->isIntegerTy(64)) {
5338 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5339 Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2]));
5340 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV);
John McCall7f416cc2015-09-08 08:05:57 +00005341 Ops[2] = getAlignmentValue32(PtrOp0);
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005342 llvm::Type *Tys[] = {Int8PtrTy, Ops[1]->getType()};
Bob Wilson2605fef2012-08-14 17:27:04 +00005343 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1,
Jeroen Ketema55a8e802015-09-30 10:56:56 +00005344 Tys), Ops);
Bob Wilson2605fef2012-08-14 17:27:04 +00005345 }
5346 // fall through
Tim Northoverc322f832014-01-30 14:47:51 +00005347 case NEON::BI__builtin_neon_vst1_lane_v: {
Nate Begeman8ed060b2010-06-11 22:57:12 +00005348 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
5349 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
5350 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00005351 auto St = Builder.CreateStore(Ops[1], Builder.CreateBitCast(PtrOp0, Ty));
Bob Wilson49708d42012-02-04 23:58:08 +00005352 return St;
5353 }
Tim Northoverc322f832014-01-30 14:47:51 +00005354 case NEON::BI__builtin_neon_vtbl1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005355 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),
5356 Ops, "vtbl1");
Tim Northoverc322f832014-01-30 14:47:51 +00005357 case NEON::BI__builtin_neon_vtbl2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005358 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl2),
5359 Ops, "vtbl2");
Tim Northoverc322f832014-01-30 14:47:51 +00005360 case NEON::BI__builtin_neon_vtbl3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005361 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl3),
5362 Ops, "vtbl3");
Tim Northoverc322f832014-01-30 14:47:51 +00005363 case NEON::BI__builtin_neon_vtbl4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005364 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl4),
5365 Ops, "vtbl4");
Tim Northoverc322f832014-01-30 14:47:51 +00005366 case NEON::BI__builtin_neon_vtbx1_v:
Nate Begeman55483092010-06-09 01:10:23 +00005367 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx1),
5368 Ops, "vtbx1");
Tim Northoverc322f832014-01-30 14:47:51 +00005369 case NEON::BI__builtin_neon_vtbx2_v:
Nate Begeman55483092010-06-09 01:10:23 +00005370 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx2),
5371 Ops, "vtbx2");
Tim Northoverc322f832014-01-30 14:47:51 +00005372 case NEON::BI__builtin_neon_vtbx3_v:
Nate Begeman55483092010-06-09 01:10:23 +00005373 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx3),
5374 Ops, "vtbx3");
Tim Northoverc322f832014-01-30 14:47:51 +00005375 case NEON::BI__builtin_neon_vtbx4_v:
Nate Begeman55483092010-06-09 01:10:23 +00005376 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbx4),
5377 Ops, "vtbx4");
Chris Lattner5cc15e02010-03-03 19:03:45 +00005378 }
5379}
5380
Tim Northover573cbee2014-05-24 12:52:07 +00005381static Value *EmitAArch64TblBuiltinExpr(CodeGenFunction &CGF, unsigned BuiltinID,
Tim Northovera2ee4332014-03-29 15:09:45 +00005382 const CallExpr *E,
5383 SmallVectorImpl<Value *> &Ops) {
5384 unsigned int Int = 0;
Craig Topper8a13c412014-05-21 05:09:00 +00005385 const char *s = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005386
Tim Northovera2ee4332014-03-29 15:09:45 +00005387 switch (BuiltinID) {
5388 default:
Craig Topper8a13c412014-05-21 05:09:00 +00005389 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005390 case NEON::BI__builtin_neon_vtbl1_v:
5391 case NEON::BI__builtin_neon_vqtbl1_v:
5392 case NEON::BI__builtin_neon_vqtbl1q_v:
5393 case NEON::BI__builtin_neon_vtbl2_v:
5394 case NEON::BI__builtin_neon_vqtbl2_v:
5395 case NEON::BI__builtin_neon_vqtbl2q_v:
5396 case NEON::BI__builtin_neon_vtbl3_v:
5397 case NEON::BI__builtin_neon_vqtbl3_v:
5398 case NEON::BI__builtin_neon_vqtbl3q_v:
5399 case NEON::BI__builtin_neon_vtbl4_v:
5400 case NEON::BI__builtin_neon_vqtbl4_v:
5401 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005402 break;
5403 case NEON::BI__builtin_neon_vtbx1_v:
5404 case NEON::BI__builtin_neon_vqtbx1_v:
5405 case NEON::BI__builtin_neon_vqtbx1q_v:
5406 case NEON::BI__builtin_neon_vtbx2_v:
5407 case NEON::BI__builtin_neon_vqtbx2_v:
5408 case NEON::BI__builtin_neon_vqtbx2q_v:
5409 case NEON::BI__builtin_neon_vtbx3_v:
5410 case NEON::BI__builtin_neon_vqtbx3_v:
5411 case NEON::BI__builtin_neon_vqtbx3q_v:
5412 case NEON::BI__builtin_neon_vtbx4_v:
5413 case NEON::BI__builtin_neon_vqtbx4_v:
5414 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northovera2ee4332014-03-29 15:09:45 +00005415 break;
5416 }
5417
5418 assert(E->getNumArgs() >= 3);
5419
5420 // Get the last argument, which specifies the vector type.
5421 llvm::APSInt Result;
5422 const Expr *Arg = E->getArg(E->getNumArgs() - 1);
5423 if (!Arg->isIntegerConstantExpr(Result, CGF.getContext()))
Craig Topper8a13c412014-05-21 05:09:00 +00005424 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005425
5426 // Determine the type of this overloaded NEON intrinsic.
5427 NeonTypeFlags Type(Result.getZExtValue());
Benjamin Kramerc385a802015-07-28 15:40:11 +00005428 llvm::VectorType *Ty = GetNeonType(&CGF, Type);
Tim Northovera2ee4332014-03-29 15:09:45 +00005429 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00005430 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005431
Tim Northovera2ee4332014-03-29 15:09:45 +00005432 CodeGen::CGBuilderTy &Builder = CGF.Builder;
5433
5434 // AArch64 scalar builtins are not overloaded, they do not have an extra
5435 // argument that specifies the vector type, need to handle each case.
Tim Northovera2ee4332014-03-29 15:09:45 +00005436 switch (BuiltinID) {
5437 case NEON::BI__builtin_neon_vtbl1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005438 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 1), nullptr,
5439 Ops[1], Ty, Intrinsic::aarch64_neon_tbl1,
5440 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005441 }
5442 case NEON::BI__builtin_neon_vtbl2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005443 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 2), nullptr,
5444 Ops[2], Ty, Intrinsic::aarch64_neon_tbl1,
5445 "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005446 }
5447 case NEON::BI__builtin_neon_vtbl3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005448 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 3), nullptr,
5449 Ops[3], Ty, Intrinsic::aarch64_neon_tbl2,
5450 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005451 }
5452 case NEON::BI__builtin_neon_vtbl4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005453 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(0, 4), nullptr,
5454 Ops[4], Ty, Intrinsic::aarch64_neon_tbl2,
5455 "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005456 }
5457 case NEON::BI__builtin_neon_vtbx1_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005458 Value *TblRes =
5459 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 1), nullptr, Ops[2],
5460 Ty, Intrinsic::aarch64_neon_tbl1, "vtbl1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005461
Benjamin Kramerc385a802015-07-28 15:40:11 +00005462 llvm::Constant *EightV = ConstantInt::get(Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00005463 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[2], EightV);
5464 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5465
5466 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5467 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5468 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5469 }
5470 case NEON::BI__builtin_neon_vtbx2_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005471 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 2), Ops[0],
5472 Ops[3], Ty, Intrinsic::aarch64_neon_tbx1,
5473 "vtbx1");
Tim Northovera2ee4332014-03-29 15:09:45 +00005474 }
5475 case NEON::BI__builtin_neon_vtbx3_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005476 Value *TblRes =
5477 packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 3), nullptr, Ops[4],
5478 Ty, Intrinsic::aarch64_neon_tbl2, "vtbl2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005479
Benjamin Kramerc385a802015-07-28 15:40:11 +00005480 llvm::Constant *TwentyFourV = ConstantInt::get(Ty, 24);
Tim Northovera2ee4332014-03-29 15:09:45 +00005481 Value *CmpRes = Builder.CreateICmp(ICmpInst::ICMP_UGE, Ops[4],
5482 TwentyFourV);
5483 CmpRes = Builder.CreateSExt(CmpRes, Ty);
5484
5485 Value *EltsFromInput = Builder.CreateAnd(CmpRes, Ops[0]);
5486 Value *EltsFromTbl = Builder.CreateAnd(Builder.CreateNot(CmpRes), TblRes);
5487 return Builder.CreateOr(EltsFromInput, EltsFromTbl, "vtbx");
5488 }
5489 case NEON::BI__builtin_neon_vtbx4_v: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005490 return packTBLDVectorList(CGF, makeArrayRef(Ops).slice(1, 4), Ops[0],
5491 Ops[5], Ty, Intrinsic::aarch64_neon_tbx2,
5492 "vtbx2");
Tim Northovera2ee4332014-03-29 15:09:45 +00005493 }
5494 case NEON::BI__builtin_neon_vqtbl1_v:
5495 case NEON::BI__builtin_neon_vqtbl1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005496 Int = Intrinsic::aarch64_neon_tbl1; s = "vtbl1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005497 case NEON::BI__builtin_neon_vqtbl2_v:
5498 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00005499 Int = Intrinsic::aarch64_neon_tbl2; s = "vtbl2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005500 case NEON::BI__builtin_neon_vqtbl3_v:
5501 case NEON::BI__builtin_neon_vqtbl3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005502 Int = Intrinsic::aarch64_neon_tbl3; s = "vtbl3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005503 case NEON::BI__builtin_neon_vqtbl4_v:
5504 case NEON::BI__builtin_neon_vqtbl4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005505 Int = Intrinsic::aarch64_neon_tbl4; s = "vtbl4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005506 case NEON::BI__builtin_neon_vqtbx1_v:
5507 case NEON::BI__builtin_neon_vqtbx1q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005508 Int = Intrinsic::aarch64_neon_tbx1; s = "vtbx1"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005509 case NEON::BI__builtin_neon_vqtbx2_v:
5510 case NEON::BI__builtin_neon_vqtbx2q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005511 Int = Intrinsic::aarch64_neon_tbx2; s = "vtbx2"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005512 case NEON::BI__builtin_neon_vqtbx3_v:
5513 case NEON::BI__builtin_neon_vqtbx3q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005514 Int = Intrinsic::aarch64_neon_tbx3; s = "vtbx3"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005515 case NEON::BI__builtin_neon_vqtbx4_v:
5516 case NEON::BI__builtin_neon_vqtbx4q_v:
Tim Northover573cbee2014-05-24 12:52:07 +00005517 Int = Intrinsic::aarch64_neon_tbx4; s = "vtbx4"; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005518 }
5519 }
5520
5521 if (!Int)
Craig Topper8a13c412014-05-21 05:09:00 +00005522 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00005523
5524 Function *F = CGF.CGM.getIntrinsic(Int, Ty);
5525 return CGF.EmitNeonCall(F, Ops, s);
5526}
5527
5528Value *CodeGenFunction::vectorWrapScalar16(Value *Op) {
5529 llvm::Type *VTy = llvm::VectorType::get(Int16Ty, 4);
5530 Op = Builder.CreateBitCast(Op, Int16Ty);
5531 Value *V = UndefValue::get(VTy);
Michael J. Spencerdd597752014-05-31 00:22:12 +00005532 llvm::Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00005533 Op = Builder.CreateInsertElement(V, Op, CI);
5534 return Op;
5535}
5536
Tim Northover573cbee2014-05-24 12:52:07 +00005537Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
5538 const CallExpr *E) {
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005539 unsigned HintID = static_cast<unsigned>(-1);
5540 switch (BuiltinID) {
5541 default: break;
Yi Kong4d5e23f2014-07-14 15:20:09 +00005542 case AArch64::BI__builtin_arm_nop:
5543 HintID = 0;
5544 break;
Saleem Abdulrasool572250d2014-07-12 23:27:22 +00005545 case AArch64::BI__builtin_arm_yield:
5546 HintID = 1;
5547 break;
5548 case AArch64::BI__builtin_arm_wfe:
5549 HintID = 2;
5550 break;
5551 case AArch64::BI__builtin_arm_wfi:
5552 HintID = 3;
5553 break;
5554 case AArch64::BI__builtin_arm_sev:
5555 HintID = 4;
5556 break;
5557 case AArch64::BI__builtin_arm_sevl:
5558 HintID = 5;
5559 break;
5560 }
5561
5562 if (HintID != static_cast<unsigned>(-1)) {
5563 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_hint);
5564 return Builder.CreateCall(F, llvm::ConstantInt::get(Int32Ty, HintID));
5565 }
5566
Yi Konga5548432014-08-13 19:18:20 +00005567 if (BuiltinID == AArch64::BI__builtin_arm_prefetch) {
5568 Value *Address = EmitScalarExpr(E->getArg(0));
5569 Value *RW = EmitScalarExpr(E->getArg(1));
5570 Value *CacheLevel = EmitScalarExpr(E->getArg(2));
5571 Value *RetentionPolicy = EmitScalarExpr(E->getArg(3));
5572 Value *IsData = EmitScalarExpr(E->getArg(4));
5573
5574 Value *Locality = nullptr;
5575 if (cast<llvm::ConstantInt>(RetentionPolicy)->isZero()) {
5576 // Temporal fetch, needs to convert cache level to locality.
5577 Locality = llvm::ConstantInt::get(Int32Ty,
5578 -cast<llvm::ConstantInt>(CacheLevel)->getValue() + 3);
5579 } else {
5580 // Streaming fetch.
5581 Locality = llvm::ConstantInt::get(Int32Ty, 0);
5582 }
5583
5584 // FIXME: We need AArch64 specific LLVM intrinsic if we want to specify
5585 // PLDL3STRM or PLDL2STRM.
5586 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00005587 return Builder.CreateCall(F, {Address, RW, Locality, IsData});
Yi Konga5548432014-08-13 19:18:20 +00005588 }
5589
Jim Grosbach79140822014-06-16 21:56:02 +00005590 if (BuiltinID == AArch64::BI__builtin_arm_rbit) {
5591 assert((getContext().getTypeSize(E->getType()) == 32) &&
5592 "rbit of unusual size!");
5593 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5594 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005595 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005596 }
5597 if (BuiltinID == AArch64::BI__builtin_arm_rbit64) {
5598 assert((getContext().getTypeSize(E->getType()) == 64) &&
5599 "rbit of unusual size!");
5600 llvm::Value *Arg = EmitScalarExpr(E->getArg(0));
5601 return Builder.CreateCall(
Chad Rosier5a4a1be2017-01-10 17:20:28 +00005602 CGM.getIntrinsic(Intrinsic::bitreverse, Arg->getType()), Arg, "rbit");
Jim Grosbach79140822014-06-16 21:56:02 +00005603 }
5604
Tim Northover573cbee2014-05-24 12:52:07 +00005605 if (BuiltinID == AArch64::BI__clear_cache) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005606 assert(E->getNumArgs() == 2 && "__clear_cache takes 2 arguments");
5607 const FunctionDecl *FD = E->getDirectCallee();
Benjamin Kramerc385a802015-07-28 15:40:11 +00005608 Value *Ops[2];
Tim Northovera2ee4332014-03-29 15:09:45 +00005609 for (unsigned i = 0; i < 2; i++)
Benjamin Kramerc385a802015-07-28 15:40:11 +00005610 Ops[i] = EmitScalarExpr(E->getArg(i));
Tim Northovera2ee4332014-03-29 15:09:45 +00005611 llvm::Type *Ty = CGM.getTypes().ConvertType(FD->getType());
5612 llvm::FunctionType *FTy = cast<llvm::FunctionType>(Ty);
5613 StringRef Name = FD->getName();
5614 return EmitNounwindRuntimeCall(CGM.CreateRuntimeFunction(FTy, Name), Ops);
5615 }
5616
Tim Northover3acd6bd2014-07-02 12:56:02 +00005617 if ((BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5618 BuiltinID == AArch64::BI__builtin_arm_ldaex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005619 getContext().getTypeSize(E->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005620 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5621 ? Intrinsic::aarch64_ldaxp
5622 : Intrinsic::aarch64_ldxp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005623
5624 Value *LdPtr = EmitScalarExpr(E->getArg(0));
5625 Value *Val = Builder.CreateCall(F, Builder.CreateBitCast(LdPtr, Int8PtrTy),
5626 "ldxp");
5627
5628 Value *Val0 = Builder.CreateExtractValue(Val, 1);
5629 Value *Val1 = Builder.CreateExtractValue(Val, 0);
5630 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
5631 Val0 = Builder.CreateZExt(Val0, Int128Ty);
5632 Val1 = Builder.CreateZExt(Val1, Int128Ty);
5633
5634 Value *ShiftCst = llvm::ConstantInt::get(Int128Ty, 64);
5635 Val = Builder.CreateShl(Val0, ShiftCst, "shl", true /* nuw */);
5636 Val = Builder.CreateOr(Val, Val1);
5637 return Builder.CreateBitCast(Val, ConvertType(E->getType()));
Tim Northover3acd6bd2014-07-02 12:56:02 +00005638 } else if (BuiltinID == AArch64::BI__builtin_arm_ldrex ||
5639 BuiltinID == AArch64::BI__builtin_arm_ldaex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005640 Value *LoadAddr = EmitScalarExpr(E->getArg(0));
5641
5642 QualType Ty = E->getType();
5643 llvm::Type *RealResTy = ConvertType(Ty);
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005644 llvm::Type *PtrTy = llvm::IntegerType::get(
5645 getLLVMContext(), getContext().getTypeSize(Ty))->getPointerTo();
5646 LoadAddr = Builder.CreateBitCast(LoadAddr, PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005647
Tim Northover3acd6bd2014-07-02 12:56:02 +00005648 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_ldaex
5649 ? Intrinsic::aarch64_ldaxr
5650 : Intrinsic::aarch64_ldxr,
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005651 PtrTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005652 Value *Val = Builder.CreateCall(F, LoadAddr, "ldxr");
5653
5654 if (RealResTy->isPointerTy())
5655 return Builder.CreateIntToPtr(Val, RealResTy);
5656
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005657 llvm::Type *IntResTy = llvm::IntegerType::get(
5658 getLLVMContext(), CGM.getDataLayout().getTypeSizeInBits(RealResTy));
Tim Northovera2ee4332014-03-29 15:09:45 +00005659 Val = Builder.CreateTruncOrBitCast(Val, IntResTy);
5660 return Builder.CreateBitCast(Val, RealResTy);
5661 }
5662
Tim Northover3acd6bd2014-07-02 12:56:02 +00005663 if ((BuiltinID == AArch64::BI__builtin_arm_strex ||
5664 BuiltinID == AArch64::BI__builtin_arm_stlex) &&
Tim Northovera2ee4332014-03-29 15:09:45 +00005665 getContext().getTypeSize(E->getArg(0)->getType()) == 128) {
Tim Northover3acd6bd2014-07-02 12:56:02 +00005666 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5667 ? Intrinsic::aarch64_stlxp
5668 : Intrinsic::aarch64_stxp);
Serge Guelton1d993272017-05-09 19:31:30 +00005669 llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00005670
John McCall7f416cc2015-09-08 08:05:57 +00005671 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
5672 EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true);
Tim Northovera2ee4332014-03-29 15:09:45 +00005673
John McCall7f416cc2015-09-08 08:05:57 +00005674 Tmp = Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(STy));
5675 llvm::Value *Val = Builder.CreateLoad(Tmp);
Tim Northovera2ee4332014-03-29 15:09:45 +00005676
5677 Value *Arg0 = Builder.CreateExtractValue(Val, 0);
5678 Value *Arg1 = Builder.CreateExtractValue(Val, 1);
5679 Value *StPtr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)),
5680 Int8PtrTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00005681 return Builder.CreateCall(F, {Arg0, Arg1, StPtr}, "stxp");
5682 }
5683
5684 if (BuiltinID == AArch64::BI__builtin_arm_strex ||
5685 BuiltinID == AArch64::BI__builtin_arm_stlex) {
Tim Northovera2ee4332014-03-29 15:09:45 +00005686 Value *StoreVal = EmitScalarExpr(E->getArg(0));
5687 Value *StoreAddr = EmitScalarExpr(E->getArg(1));
5688
5689 QualType Ty = E->getArg(0)->getType();
5690 llvm::Type *StoreTy = llvm::IntegerType::get(getLLVMContext(),
5691 getContext().getTypeSize(Ty));
5692 StoreAddr = Builder.CreateBitCast(StoreAddr, StoreTy->getPointerTo());
5693
5694 if (StoreVal->getType()->isPointerTy())
5695 StoreVal = Builder.CreatePtrToInt(StoreVal, Int64Ty);
5696 else {
Akira Hatanaka6c299ca2016-12-01 19:25:14 +00005697 llvm::Type *IntTy = llvm::IntegerType::get(
5698 getLLVMContext(),
5699 CGM.getDataLayout().getTypeSizeInBits(StoreVal->getType()));
5700 StoreVal = Builder.CreateBitCast(StoreVal, IntTy);
Tim Northovera2ee4332014-03-29 15:09:45 +00005701 StoreVal = Builder.CreateZExtOrBitCast(StoreVal, Int64Ty);
5702 }
5703
Tim Northover3acd6bd2014-07-02 12:56:02 +00005704 Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
5705 ? Intrinsic::aarch64_stlxr
5706 : Intrinsic::aarch64_stxr,
5707 StoreAddr->getType());
David Blaikie43f9bb72015-05-18 22:14:03 +00005708 return Builder.CreateCall(F, {StoreVal, StoreAddr}, "stxr");
Tim Northovera2ee4332014-03-29 15:09:45 +00005709 }
5710
Tim Northover573cbee2014-05-24 12:52:07 +00005711 if (BuiltinID == AArch64::BI__builtin_arm_clrex) {
5712 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_clrex);
David Blaikie4ba525b2015-07-14 17:27:39 +00005713 return Builder.CreateCall(F);
Tim Northovera2ee4332014-03-29 15:09:45 +00005714 }
5715
5716 // CRC32
5717 Intrinsic::ID CRCIntrinsicID = Intrinsic::not_intrinsic;
5718 switch (BuiltinID) {
Tim Northover573cbee2014-05-24 12:52:07 +00005719 case AArch64::BI__builtin_arm_crc32b:
5720 CRCIntrinsicID = Intrinsic::aarch64_crc32b; break;
5721 case AArch64::BI__builtin_arm_crc32cb:
5722 CRCIntrinsicID = Intrinsic::aarch64_crc32cb; break;
5723 case AArch64::BI__builtin_arm_crc32h:
5724 CRCIntrinsicID = Intrinsic::aarch64_crc32h; break;
5725 case AArch64::BI__builtin_arm_crc32ch:
5726 CRCIntrinsicID = Intrinsic::aarch64_crc32ch; break;
5727 case AArch64::BI__builtin_arm_crc32w:
5728 CRCIntrinsicID = Intrinsic::aarch64_crc32w; break;
5729 case AArch64::BI__builtin_arm_crc32cw:
5730 CRCIntrinsicID = Intrinsic::aarch64_crc32cw; break;
5731 case AArch64::BI__builtin_arm_crc32d:
5732 CRCIntrinsicID = Intrinsic::aarch64_crc32x; break;
5733 case AArch64::BI__builtin_arm_crc32cd:
5734 CRCIntrinsicID = Intrinsic::aarch64_crc32cx; break;
Tim Northovera2ee4332014-03-29 15:09:45 +00005735 }
5736
5737 if (CRCIntrinsicID != Intrinsic::not_intrinsic) {
5738 Value *Arg0 = EmitScalarExpr(E->getArg(0));
5739 Value *Arg1 = EmitScalarExpr(E->getArg(1));
5740 Function *F = CGM.getIntrinsic(CRCIntrinsicID);
5741
5742 llvm::Type *DataTy = F->getFunctionType()->getParamType(1);
5743 Arg1 = Builder.CreateZExtOrBitCast(Arg1, DataTy);
5744
David Blaikie43f9bb72015-05-18 22:14:03 +00005745 return Builder.CreateCall(F, {Arg0, Arg1});
Tim Northovera2ee4332014-03-29 15:09:45 +00005746 }
5747
Luke Cheeseman59b2d832015-06-15 17:51:01 +00005748 if (BuiltinID == AArch64::BI__builtin_arm_rsr ||
5749 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5750 BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5751 BuiltinID == AArch64::BI__builtin_arm_wsr ||
5752 BuiltinID == AArch64::BI__builtin_arm_wsr64 ||
5753 BuiltinID == AArch64::BI__builtin_arm_wsrp) {
5754
5755 bool IsRead = BuiltinID == AArch64::BI__builtin_arm_rsr ||
5756 BuiltinID == AArch64::BI__builtin_arm_rsr64 ||
5757 BuiltinID == AArch64::BI__builtin_arm_rsrp;
5758
5759 bool IsPointerBuiltin = BuiltinID == AArch64::BI__builtin_arm_rsrp ||
5760 BuiltinID == AArch64::BI__builtin_arm_wsrp;
5761
5762 bool Is64Bit = BuiltinID != AArch64::BI__builtin_arm_rsr &&
5763 BuiltinID != AArch64::BI__builtin_arm_wsr;
5764
5765 llvm::Type *ValueType;
5766 llvm::Type *RegisterType = Int64Ty;
5767 if (IsPointerBuiltin) {
5768 ValueType = VoidPtrTy;
5769 } else if (Is64Bit) {
5770 ValueType = Int64Ty;
5771 } else {
5772 ValueType = Int32Ty;
5773 }
5774
5775 return EmitSpecialRegisterBuiltin(*this, E, RegisterType, ValueType, IsRead);
5776 }
5777
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005778 // Find out if any arguments are required to be integer constant
5779 // expressions.
5780 unsigned ICEArguments = 0;
5781 ASTContext::GetBuiltinTypeError Error;
5782 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
5783 assert(Error == ASTContext::GE_None && "Should not codegen an error");
5784
Tim Northovera2ee4332014-03-29 15:09:45 +00005785 llvm::SmallVector<Value*, 4> Ops;
Ahmed Bougacha94df7302015-06-04 01:43:41 +00005786 for (unsigned i = 0, e = E->getNumArgs() - 1; i != e; i++) {
5787 if ((ICEArguments & (1 << i)) == 0) {
5788 Ops.push_back(EmitScalarExpr(E->getArg(i)));
5789 } else {
5790 // If this is required to be a constant, constant fold it so that we know
5791 // that the generated intrinsic gets a ConstantInt.
5792 llvm::APSInt Result;
5793 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
5794 assert(IsConst && "Constant arg isn't actually constant?");
5795 (void)IsConst;
5796 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
5797 }
5798 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005799
Craig Topper5fc8fc22014-08-27 06:28:36 +00005800 auto SISDMap = makeArrayRef(AArch64SISDIntrinsicMap);
Tim Northovera2ee4332014-03-29 15:09:45 +00005801 const NeonIntrinsicInfo *Builtin = findNeonIntrinsicInMap(
Tim Northover573cbee2014-05-24 12:52:07 +00005802 SISDMap, BuiltinID, AArch64SISDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00005803
5804 if (Builtin) {
5805 Ops.push_back(EmitScalarExpr(E->getArg(E->getNumArgs() - 1)));
5806 Value *Result = EmitCommonNeonSISDBuiltinExpr(*this, *Builtin, Ops, E);
5807 assert(Result && "SISD intrinsic should have been handled");
5808 return Result;
5809 }
5810
5811 llvm::APSInt Result;
5812 const Expr *Arg = E->getArg(E->getNumArgs()-1);
5813 NeonTypeFlags Type(0);
5814 if (Arg->isIntegerConstantExpr(Result, getContext()))
5815 // Determine the type of this overloaded NEON intrinsic.
5816 Type = NeonTypeFlags(Result.getZExtValue());
5817
5818 bool usgn = Type.isUnsigned();
5819 bool quad = Type.isQuad();
5820
5821 // Handle non-overloaded intrinsics first.
5822 switch (BuiltinID) {
5823 default: break;
Tim Northoverb17f9a42014-04-01 12:23:08 +00005824 case NEON::BI__builtin_neon_vldrq_p128: {
Peter Collingbourneb367c562016-11-28 22:30:21 +00005825 llvm::Type *Int128Ty = llvm::Type::getIntNTy(getLLVMContext(), 128);
5826 llvm::Type *Int128PTy = llvm::PointerType::get(Int128Ty, 0);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005827 Value *Ptr = Builder.CreateBitCast(EmitScalarExpr(E->getArg(0)), Int128PTy);
Peter Collingbourneb367c562016-11-28 22:30:21 +00005828 return Builder.CreateAlignedLoad(Int128Ty, Ptr,
5829 CharUnits::fromQuantity(16));
Tim Northoverb17f9a42014-04-01 12:23:08 +00005830 }
5831 case NEON::BI__builtin_neon_vstrq_p128: {
5832 llvm::Type *Int128PTy = llvm::Type::getIntNPtrTy(getLLVMContext(), 128);
5833 Value *Ptr = Builder.CreateBitCast(Ops[0], Int128PTy);
John McCall7f416cc2015-09-08 08:05:57 +00005834 return Builder.CreateDefaultAlignedStore(EmitScalarExpr(E->getArg(1)), Ptr);
Tim Northoverb17f9a42014-04-01 12:23:08 +00005835 }
Tim Northovera2ee4332014-03-29 15:09:45 +00005836 case NEON::BI__builtin_neon_vcvts_u32_f32:
5837 case NEON::BI__builtin_neon_vcvtd_u64_f64:
5838 usgn = true;
5839 // FALL THROUGH
5840 case NEON::BI__builtin_neon_vcvts_s32_f32:
5841 case NEON::BI__builtin_neon_vcvtd_s64_f64: {
5842 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5843 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5844 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5845 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5846 Ops[0] = Builder.CreateBitCast(Ops[0], FTy);
5847 if (usgn)
5848 return Builder.CreateFPToUI(Ops[0], InTy);
5849 return Builder.CreateFPToSI(Ops[0], InTy);
5850 }
5851 case NEON::BI__builtin_neon_vcvts_f32_u32:
5852 case NEON::BI__builtin_neon_vcvtd_f64_u64:
5853 usgn = true;
5854 // FALL THROUGH
5855 case NEON::BI__builtin_neon_vcvts_f32_s32:
5856 case NEON::BI__builtin_neon_vcvtd_f64_s64: {
5857 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5858 bool Is64 = Ops[0]->getType()->getPrimitiveSizeInBits() == 64;
5859 llvm::Type *InTy = Is64 ? Int64Ty : Int32Ty;
5860 llvm::Type *FTy = Is64 ? DoubleTy : FloatTy;
5861 Ops[0] = Builder.CreateBitCast(Ops[0], InTy);
5862 if (usgn)
5863 return Builder.CreateUIToFP(Ops[0], FTy);
5864 return Builder.CreateSIToFP(Ops[0], FTy);
5865 }
5866 case NEON::BI__builtin_neon_vpaddd_s64: {
Benjamin Kramerc385a802015-07-28 15:40:11 +00005867 llvm::Type *Ty = llvm::VectorType::get(Int64Ty, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005868 Value *Vec = EmitScalarExpr(E->getArg(0));
5869 // The vector is v2f64, so make sure it's bitcast to that.
5870 Vec = Builder.CreateBitCast(Vec, Ty, "v2i64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005871 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5872 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005873 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5874 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5875 // Pairwise addition of a v2f64 into a scalar f64.
5876 return Builder.CreateAdd(Op0, Op1, "vpaddd");
5877 }
5878 case NEON::BI__builtin_neon_vpaddd_f64: {
5879 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005880 llvm::VectorType::get(DoubleTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005881 Value *Vec = EmitScalarExpr(E->getArg(0));
5882 // The vector is v2f64, so make sure it's bitcast to that.
5883 Vec = Builder.CreateBitCast(Vec, Ty, "v2f64");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005884 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5885 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005886 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5887 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5888 // Pairwise addition of a v2f64 into a scalar f64.
5889 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5890 }
5891 case NEON::BI__builtin_neon_vpadds_f32: {
5892 llvm::Type *Ty =
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00005893 llvm::VectorType::get(FloatTy, 2);
Tim Northovera2ee4332014-03-29 15:09:45 +00005894 Value *Vec = EmitScalarExpr(E->getArg(0));
5895 // The vector is v2f32, so make sure it's bitcast to that.
5896 Vec = Builder.CreateBitCast(Vec, Ty, "v2f32");
Michael J. Spencerdd597752014-05-31 00:22:12 +00005897 llvm::Value *Idx0 = llvm::ConstantInt::get(SizeTy, 0);
5898 llvm::Value *Idx1 = llvm::ConstantInt::get(SizeTy, 1);
Tim Northovera2ee4332014-03-29 15:09:45 +00005899 Value *Op0 = Builder.CreateExtractElement(Vec, Idx0, "lane0");
5900 Value *Op1 = Builder.CreateExtractElement(Vec, Idx1, "lane1");
5901 // Pairwise addition of a v2f32 into a scalar f32.
5902 return Builder.CreateFAdd(Op0, Op1, "vpaddd");
5903 }
5904 case NEON::BI__builtin_neon_vceqzd_s64:
5905 case NEON::BI__builtin_neon_vceqzd_f64:
5906 case NEON::BI__builtin_neon_vceqzs_f32:
5907 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5908 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005909 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5910 ICmpInst::FCMP_OEQ, ICmpInst::ICMP_EQ, "vceqz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005911 case NEON::BI__builtin_neon_vcgezd_s64:
5912 case NEON::BI__builtin_neon_vcgezd_f64:
5913 case NEON::BI__builtin_neon_vcgezs_f32:
5914 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5915 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005916 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5917 ICmpInst::FCMP_OGE, ICmpInst::ICMP_SGE, "vcgez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005918 case NEON::BI__builtin_neon_vclezd_s64:
5919 case NEON::BI__builtin_neon_vclezd_f64:
5920 case NEON::BI__builtin_neon_vclezs_f32:
5921 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5922 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005923 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5924 ICmpInst::FCMP_OLE, ICmpInst::ICMP_SLE, "vclez");
Tim Northovera2ee4332014-03-29 15:09:45 +00005925 case NEON::BI__builtin_neon_vcgtzd_s64:
5926 case NEON::BI__builtin_neon_vcgtzd_f64:
5927 case NEON::BI__builtin_neon_vcgtzs_f32:
5928 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5929 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005930 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5931 ICmpInst::FCMP_OGT, ICmpInst::ICMP_SGT, "vcgtz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005932 case NEON::BI__builtin_neon_vcltzd_s64:
5933 case NEON::BI__builtin_neon_vcltzd_f64:
5934 case NEON::BI__builtin_neon_vcltzs_f32:
5935 Ops.push_back(EmitScalarExpr(E->getArg(0)));
5936 return EmitAArch64CompareBuiltinExpr(
David Majnemerced8bdf2015-02-25 17:36:15 +00005937 Ops[0], ConvertType(E->getCallReturnType(getContext())),
5938 ICmpInst::FCMP_OLT, ICmpInst::ICMP_SLT, "vcltz");
Tim Northovera2ee4332014-03-29 15:09:45 +00005939
5940 case NEON::BI__builtin_neon_vceqzd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00005941 Ops.push_back(EmitScalarExpr(E->getArg(0)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00005942 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
5943 Ops[0] =
5944 Builder.CreateICmpEQ(Ops[0], llvm::Constant::getNullValue(Int64Ty));
5945 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqzd");
Tim Northovera2ee4332014-03-29 15:09:45 +00005946 }
5947 case NEON::BI__builtin_neon_vceqd_f64:
5948 case NEON::BI__builtin_neon_vcled_f64:
5949 case NEON::BI__builtin_neon_vcltd_f64:
5950 case NEON::BI__builtin_neon_vcged_f64:
5951 case NEON::BI__builtin_neon_vcgtd_f64: {
5952 llvm::CmpInst::Predicate P;
5953 switch (BuiltinID) {
5954 default: llvm_unreachable("missing builtin ID in switch!");
5955 case NEON::BI__builtin_neon_vceqd_f64: P = llvm::FCmpInst::FCMP_OEQ; break;
5956 case NEON::BI__builtin_neon_vcled_f64: P = llvm::FCmpInst::FCMP_OLE; break;
5957 case NEON::BI__builtin_neon_vcltd_f64: P = llvm::FCmpInst::FCMP_OLT; break;
5958 case NEON::BI__builtin_neon_vcged_f64: P = llvm::FCmpInst::FCMP_OGE; break;
5959 case NEON::BI__builtin_neon_vcgtd_f64: P = llvm::FCmpInst::FCMP_OGT; break;
5960 }
5961 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5962 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
5963 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
5964 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5965 return Builder.CreateSExt(Ops[0], Int64Ty, "vcmpd");
5966 }
5967 case NEON::BI__builtin_neon_vceqs_f32:
5968 case NEON::BI__builtin_neon_vcles_f32:
5969 case NEON::BI__builtin_neon_vclts_f32:
5970 case NEON::BI__builtin_neon_vcges_f32:
5971 case NEON::BI__builtin_neon_vcgts_f32: {
5972 llvm::CmpInst::Predicate P;
5973 switch (BuiltinID) {
5974 default: llvm_unreachable("missing builtin ID in switch!");
5975 case NEON::BI__builtin_neon_vceqs_f32: P = llvm::FCmpInst::FCMP_OEQ; break;
5976 case NEON::BI__builtin_neon_vcles_f32: P = llvm::FCmpInst::FCMP_OLE; break;
5977 case NEON::BI__builtin_neon_vclts_f32: P = llvm::FCmpInst::FCMP_OLT; break;
5978 case NEON::BI__builtin_neon_vcges_f32: P = llvm::FCmpInst::FCMP_OGE; break;
5979 case NEON::BI__builtin_neon_vcgts_f32: P = llvm::FCmpInst::FCMP_OGT; break;
5980 }
5981 Ops.push_back(EmitScalarExpr(E->getArg(1)));
5982 Ops[0] = Builder.CreateBitCast(Ops[0], FloatTy);
5983 Ops[1] = Builder.CreateBitCast(Ops[1], FloatTy);
5984 Ops[0] = Builder.CreateFCmp(P, Ops[0], Ops[1]);
5985 return Builder.CreateSExt(Ops[0], Int32Ty, "vcmpd");
5986 }
5987 case NEON::BI__builtin_neon_vceqd_s64:
5988 case NEON::BI__builtin_neon_vceqd_u64:
5989 case NEON::BI__builtin_neon_vcgtd_s64:
5990 case NEON::BI__builtin_neon_vcgtd_u64:
5991 case NEON::BI__builtin_neon_vcltd_s64:
5992 case NEON::BI__builtin_neon_vcltd_u64:
5993 case NEON::BI__builtin_neon_vcged_u64:
5994 case NEON::BI__builtin_neon_vcged_s64:
5995 case NEON::BI__builtin_neon_vcled_u64:
5996 case NEON::BI__builtin_neon_vcled_s64: {
5997 llvm::CmpInst::Predicate P;
5998 switch (BuiltinID) {
5999 default: llvm_unreachable("missing builtin ID in switch!");
6000 case NEON::BI__builtin_neon_vceqd_s64:
6001 case NEON::BI__builtin_neon_vceqd_u64:P = llvm::ICmpInst::ICMP_EQ;break;
6002 case NEON::BI__builtin_neon_vcgtd_s64:P = llvm::ICmpInst::ICMP_SGT;break;
6003 case NEON::BI__builtin_neon_vcgtd_u64:P = llvm::ICmpInst::ICMP_UGT;break;
6004 case NEON::BI__builtin_neon_vcltd_s64:P = llvm::ICmpInst::ICMP_SLT;break;
6005 case NEON::BI__builtin_neon_vcltd_u64:P = llvm::ICmpInst::ICMP_ULT;break;
6006 case NEON::BI__builtin_neon_vcged_u64:P = llvm::ICmpInst::ICMP_UGE;break;
6007 case NEON::BI__builtin_neon_vcged_s64:P = llvm::ICmpInst::ICMP_SGE;break;
6008 case NEON::BI__builtin_neon_vcled_u64:P = llvm::ICmpInst::ICMP_ULE;break;
6009 case NEON::BI__builtin_neon_vcled_s64:P = llvm::ICmpInst::ICMP_SLE;break;
6010 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006011 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Tim Northover0c68faa2014-03-31 15:47:09 +00006012 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
6013 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006014 Ops[0] = Builder.CreateICmp(P, Ops[0], Ops[1]);
Tim Northover0c68faa2014-03-31 15:47:09 +00006015 return Builder.CreateSExt(Ops[0], Int64Ty, "vceqd");
Tim Northovera2ee4332014-03-29 15:09:45 +00006016 }
6017 case NEON::BI__builtin_neon_vtstd_s64:
6018 case NEON::BI__builtin_neon_vtstd_u64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006019 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Benjamin Kramerc385a802015-07-28 15:40:11 +00006020 Ops[0] = Builder.CreateBitCast(Ops[0], Int64Ty);
6021 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006022 Ops[0] = Builder.CreateAnd(Ops[0], Ops[1]);
6023 Ops[0] = Builder.CreateICmp(ICmpInst::ICMP_NE, Ops[0],
Benjamin Kramerc385a802015-07-28 15:40:11 +00006024 llvm::Constant::getNullValue(Int64Ty));
6025 return Builder.CreateSExt(Ops[0], Int64Ty, "vtstd");
Tim Northovera2ee4332014-03-29 15:09:45 +00006026 }
6027 case NEON::BI__builtin_neon_vset_lane_i8:
6028 case NEON::BI__builtin_neon_vset_lane_i16:
6029 case NEON::BI__builtin_neon_vset_lane_i32:
6030 case NEON::BI__builtin_neon_vset_lane_i64:
6031 case NEON::BI__builtin_neon_vset_lane_f32:
6032 case NEON::BI__builtin_neon_vsetq_lane_i8:
6033 case NEON::BI__builtin_neon_vsetq_lane_i16:
6034 case NEON::BI__builtin_neon_vsetq_lane_i32:
6035 case NEON::BI__builtin_neon_vsetq_lane_i64:
6036 case NEON::BI__builtin_neon_vsetq_lane_f32:
6037 Ops.push_back(EmitScalarExpr(E->getArg(2)));
6038 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
6039 case NEON::BI__builtin_neon_vset_lane_f64:
6040 // The vector type needs a cast for the v1f64 variant.
6041 Ops[1] = Builder.CreateBitCast(Ops[1],
6042 llvm::VectorType::get(DoubleTy, 1));
6043 Ops.push_back(EmitScalarExpr(E->getArg(2)));
6044 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
6045 case NEON::BI__builtin_neon_vsetq_lane_f64:
6046 // The vector type needs a cast for the v2f64 variant.
6047 Ops[1] = Builder.CreateBitCast(Ops[1],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006048 llvm::VectorType::get(DoubleTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006049 Ops.push_back(EmitScalarExpr(E->getArg(2)));
6050 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vset_lane");
6051
6052 case NEON::BI__builtin_neon_vget_lane_i8:
6053 case NEON::BI__builtin_neon_vdupb_lane_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006054 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00006055 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6056 "vget_lane");
6057 case NEON::BI__builtin_neon_vgetq_lane_i8:
6058 case NEON::BI__builtin_neon_vdupb_laneq_i8:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006059 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int8Ty, 16));
Tim Northovera2ee4332014-03-29 15:09:45 +00006060 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6061 "vgetq_lane");
6062 case NEON::BI__builtin_neon_vget_lane_i16:
6063 case NEON::BI__builtin_neon_vduph_lane_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006064 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00006065 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6066 "vget_lane");
6067 case NEON::BI__builtin_neon_vgetq_lane_i16:
6068 case NEON::BI__builtin_neon_vduph_laneq_i16:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006069 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int16Ty, 8));
Tim Northovera2ee4332014-03-29 15:09:45 +00006070 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6071 "vgetq_lane");
6072 case NEON::BI__builtin_neon_vget_lane_i32:
6073 case NEON::BI__builtin_neon_vdups_lane_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006074 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006075 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6076 "vget_lane");
6077 case NEON::BI__builtin_neon_vdups_lane_f32:
6078 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006079 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006080 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6081 "vdups_lane");
6082 case NEON::BI__builtin_neon_vgetq_lane_i32:
6083 case NEON::BI__builtin_neon_vdups_laneq_i32:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006084 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00006085 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6086 "vgetq_lane");
6087 case NEON::BI__builtin_neon_vget_lane_i64:
6088 case NEON::BI__builtin_neon_vdupd_lane_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006089 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00006090 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6091 "vget_lane");
6092 case NEON::BI__builtin_neon_vdupd_lane_f64:
6093 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006094 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00006095 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6096 "vdupd_lane");
6097 case NEON::BI__builtin_neon_vgetq_lane_i64:
6098 case NEON::BI__builtin_neon_vdupd_laneq_i64:
Benjamin Kramerc385a802015-07-28 15:40:11 +00006099 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006100 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6101 "vgetq_lane");
6102 case NEON::BI__builtin_neon_vget_lane_f32:
6103 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006104 llvm::VectorType::get(FloatTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006105 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6106 "vget_lane");
6107 case NEON::BI__builtin_neon_vget_lane_f64:
6108 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006109 llvm::VectorType::get(DoubleTy, 1));
Tim Northovera2ee4332014-03-29 15:09:45 +00006110 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6111 "vget_lane");
6112 case NEON::BI__builtin_neon_vgetq_lane_f32:
6113 case NEON::BI__builtin_neon_vdups_laneq_f32:
6114 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006115 llvm::VectorType::get(FloatTy, 4));
Tim Northovera2ee4332014-03-29 15:09:45 +00006116 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6117 "vgetq_lane");
6118 case NEON::BI__builtin_neon_vgetq_lane_f64:
6119 case NEON::BI__builtin_neon_vdupd_laneq_f64:
6120 Ops[0] = Builder.CreateBitCast(Ops[0],
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006121 llvm::VectorType::get(DoubleTy, 2));
Tim Northovera2ee4332014-03-29 15:09:45 +00006122 return Builder.CreateExtractElement(Ops[0], EmitScalarExpr(E->getArg(1)),
6123 "vgetq_lane");
6124 case NEON::BI__builtin_neon_vaddd_s64:
6125 case NEON::BI__builtin_neon_vaddd_u64:
6126 return Builder.CreateAdd(Ops[0], EmitScalarExpr(E->getArg(1)), "vaddd");
6127 case NEON::BI__builtin_neon_vsubd_s64:
6128 case NEON::BI__builtin_neon_vsubd_u64:
6129 return Builder.CreateSub(Ops[0], EmitScalarExpr(E->getArg(1)), "vsubd");
6130 case NEON::BI__builtin_neon_vqdmlalh_s16:
6131 case NEON::BI__builtin_neon_vqdmlslh_s16: {
6132 SmallVector<Value *, 2> ProductOps;
6133 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
6134 ProductOps.push_back(vectorWrapScalar16(EmitScalarExpr(E->getArg(2))));
6135 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00006136 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006137 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00006138 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006139 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
6140
6141 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlalh_s16
Tim Northover573cbee2014-05-24 12:52:07 +00006142 ? Intrinsic::aarch64_neon_sqadd
6143 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006144 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int32Ty), Ops, "vqdmlXl");
6145 }
6146 case NEON::BI__builtin_neon_vqshlud_n_s64: {
6147 Ops.push_back(EmitScalarExpr(E->getArg(1)));
6148 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Tim Northover573cbee2014-05-24 12:52:07 +00006149 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqshlu, Int64Ty),
Hao Liua19a2e22014-04-28 07:36:12 +00006150 Ops, "vqshlu_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006151 }
6152 case NEON::BI__builtin_neon_vqshld_n_u64:
6153 case NEON::BI__builtin_neon_vqshld_n_s64: {
6154 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vqshld_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006155 ? Intrinsic::aarch64_neon_uqshl
6156 : Intrinsic::aarch64_neon_sqshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006157 Ops.push_back(EmitScalarExpr(E->getArg(1)));
6158 Ops[1] = Builder.CreateZExt(Ops[1], Int64Ty);
Hao Liua19a2e22014-04-28 07:36:12 +00006159 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vqshl_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006160 }
6161 case NEON::BI__builtin_neon_vrshrd_n_u64:
6162 case NEON::BI__builtin_neon_vrshrd_n_s64: {
6163 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrshrd_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006164 ? Intrinsic::aarch64_neon_urshl
6165 : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006166 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Hao Liua19a2e22014-04-28 07:36:12 +00006167 int SV = cast<ConstantInt>(Ops[1])->getSExtValue();
6168 Ops[1] = ConstantInt::get(Int64Ty, -SV);
6169 return EmitNeonCall(CGM.getIntrinsic(Int, Int64Ty), Ops, "vrshr_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006170 }
6171 case NEON::BI__builtin_neon_vrsrad_n_u64:
6172 case NEON::BI__builtin_neon_vrsrad_n_s64: {
6173 unsigned Int = BuiltinID == NEON::BI__builtin_neon_vrsrad_n_u64
Tim Northover573cbee2014-05-24 12:52:07 +00006174 ? Intrinsic::aarch64_neon_urshl
6175 : Intrinsic::aarch64_neon_srshl;
Tim Northover0c68faa2014-03-31 15:47:09 +00006176 Ops[1] = Builder.CreateBitCast(Ops[1], Int64Ty);
6177 Ops.push_back(Builder.CreateNeg(EmitScalarExpr(E->getArg(2))));
David Blaikie43f9bb72015-05-18 22:14:03 +00006178 Ops[1] = Builder.CreateCall(CGM.getIntrinsic(Int, Int64Ty),
6179 {Ops[1], Builder.CreateSExt(Ops[2], Int64Ty)});
Tim Northover0c68faa2014-03-31 15:47:09 +00006180 return Builder.CreateAdd(Ops[0], Builder.CreateBitCast(Ops[1], Int64Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00006181 }
6182 case NEON::BI__builtin_neon_vshld_n_s64:
6183 case NEON::BI__builtin_neon_vshld_n_u64: {
6184 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
6185 return Builder.CreateShl(
Hao Liu9f9492b2014-05-14 08:59:30 +00006186 Ops[0], ConstantInt::get(Int64Ty, Amt->getZExtValue()), "shld_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006187 }
6188 case NEON::BI__builtin_neon_vshrd_n_s64: {
6189 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
6190 return Builder.CreateAShr(
6191 Ops[0], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
6192 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00006193 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006194 }
6195 case NEON::BI__builtin_neon_vshrd_n_u64: {
6196 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006197 uint64_t ShiftAmt = Amt->getZExtValue();
6198 // Right-shifting an unsigned value by its size yields 0.
6199 if (ShiftAmt == 64)
6200 return ConstantInt::get(Int64Ty, 0);
6201 return Builder.CreateLShr(Ops[0], ConstantInt::get(Int64Ty, ShiftAmt),
6202 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006203 }
6204 case NEON::BI__builtin_neon_vsrad_n_s64: {
6205 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
6206 Ops[1] = Builder.CreateAShr(
6207 Ops[1], ConstantInt::get(Int64Ty, std::min(static_cast<uint64_t>(63),
6208 Amt->getZExtValue())),
Hao Liu9f9492b2014-05-14 08:59:30 +00006209 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006210 return Builder.CreateAdd(Ops[0], Ops[1]);
6211 }
6212 case NEON::BI__builtin_neon_vsrad_n_u64: {
6213 llvm::ConstantInt *Amt = cast<ConstantInt>(EmitScalarExpr(E->getArg(2)));
Hao Liu9f9492b2014-05-14 08:59:30 +00006214 uint64_t ShiftAmt = Amt->getZExtValue();
6215 // Right-shifting an unsigned value by its size yields 0.
6216 // As Op + 0 = Op, return Ops[0] directly.
6217 if (ShiftAmt == 64)
6218 return Ops[0];
6219 Ops[1] = Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, ShiftAmt),
6220 "shrd_n");
Tim Northovera2ee4332014-03-29 15:09:45 +00006221 return Builder.CreateAdd(Ops[0], Ops[1]);
6222 }
6223 case NEON::BI__builtin_neon_vqdmlalh_lane_s16:
6224 case NEON::BI__builtin_neon_vqdmlalh_laneq_s16:
6225 case NEON::BI__builtin_neon_vqdmlslh_lane_s16:
6226 case NEON::BI__builtin_neon_vqdmlslh_laneq_s16: {
6227 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6228 "lane");
6229 SmallVector<Value *, 2> ProductOps;
6230 ProductOps.push_back(vectorWrapScalar16(Ops[1]));
6231 ProductOps.push_back(vectorWrapScalar16(Ops[2]));
6232 llvm::Type *VTy = llvm::VectorType::get(Int32Ty, 4);
Tim Northover573cbee2014-05-24 12:52:07 +00006233 Ops[1] = EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmull, VTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006234 ProductOps, "vqdmlXl");
Michael J. Spencerdd597752014-05-31 00:22:12 +00006235 Constant *CI = ConstantInt::get(SizeTy, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00006236 Ops[1] = Builder.CreateExtractElement(Ops[1], CI, "lane0");
6237 Ops.pop_back();
6238
6239 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlalh_lane_s16 ||
6240 BuiltinID == NEON::BI__builtin_neon_vqdmlalh_laneq_s16)
Tim Northover573cbee2014-05-24 12:52:07 +00006241 ? Intrinsic::aarch64_neon_sqadd
6242 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006243 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int32Ty), Ops, "vqdmlXl");
6244 }
6245 case NEON::BI__builtin_neon_vqdmlals_s32:
6246 case NEON::BI__builtin_neon_vqdmlsls_s32: {
6247 SmallVector<Value *, 2> ProductOps;
6248 ProductOps.push_back(Ops[1]);
6249 ProductOps.push_back(EmitScalarExpr(E->getArg(2)));
6250 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006251 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006252 ProductOps, "vqdmlXl");
6253
6254 unsigned AccumInt = BuiltinID == NEON::BI__builtin_neon_vqdmlals_s32
Tim Northover573cbee2014-05-24 12:52:07 +00006255 ? Intrinsic::aarch64_neon_sqadd
6256 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006257 return EmitNeonCall(CGM.getIntrinsic(AccumInt, Int64Ty), Ops, "vqdmlXl");
6258 }
6259 case NEON::BI__builtin_neon_vqdmlals_lane_s32:
6260 case NEON::BI__builtin_neon_vqdmlals_laneq_s32:
6261 case NEON::BI__builtin_neon_vqdmlsls_lane_s32:
6262 case NEON::BI__builtin_neon_vqdmlsls_laneq_s32: {
6263 Ops[2] = Builder.CreateExtractElement(Ops[2], EmitScalarExpr(E->getArg(3)),
6264 "lane");
6265 SmallVector<Value *, 2> ProductOps;
6266 ProductOps.push_back(Ops[1]);
6267 ProductOps.push_back(Ops[2]);
6268 Ops[1] =
Tim Northover573cbee2014-05-24 12:52:07 +00006269 EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_sqdmulls_scalar),
Tim Northovera2ee4332014-03-29 15:09:45 +00006270 ProductOps, "vqdmlXl");
6271 Ops.pop_back();
6272
6273 unsigned AccInt = (BuiltinID == NEON::BI__builtin_neon_vqdmlals_lane_s32 ||
6274 BuiltinID == NEON::BI__builtin_neon_vqdmlals_laneq_s32)
Tim Northover573cbee2014-05-24 12:52:07 +00006275 ? Intrinsic::aarch64_neon_sqadd
6276 : Intrinsic::aarch64_neon_sqsub;
Tim Northovera2ee4332014-03-29 15:09:45 +00006277 return EmitNeonCall(CGM.getIntrinsic(AccInt, Int64Ty), Ops, "vqdmlXl");
6278 }
6279 }
6280
6281 llvm::VectorType *VTy = GetNeonType(this, Type);
6282 llvm::Type *Ty = VTy;
6283 if (!Ty)
Craig Topper8a13c412014-05-21 05:09:00 +00006284 return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006285
Tim Northover573cbee2014-05-24 12:52:07 +00006286 // Not all intrinsics handled by the common case work for AArch64 yet, so only
Tim Northovera2ee4332014-03-29 15:09:45 +00006287 // defer to common code if it's been added to our special map.
Tim Northover573cbee2014-05-24 12:52:07 +00006288 Builtin = findNeonIntrinsicInMap(AArch64SIMDIntrinsicMap, BuiltinID,
6289 AArch64SIMDIntrinsicsProvenSorted);
Tim Northovera2ee4332014-03-29 15:09:45 +00006290
6291 if (Builtin)
6292 return EmitCommonNeonBuiltinExpr(
6293 Builtin->BuiltinID, Builtin->LLVMIntrinsic, Builtin->AltLLVMIntrinsic,
John McCall7f416cc2015-09-08 08:05:57 +00006294 Builtin->NameHint, Builtin->TypeModifier, E, Ops,
6295 /*never use addresses*/ Address::invalid(), Address::invalid());
Tim Northovera2ee4332014-03-29 15:09:45 +00006296
Tim Northover573cbee2014-05-24 12:52:07 +00006297 if (Value *V = EmitAArch64TblBuiltinExpr(*this, BuiltinID, E, Ops))
Tim Northovera2ee4332014-03-29 15:09:45 +00006298 return V;
6299
6300 unsigned Int;
6301 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00006302 default: return nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00006303 case NEON::BI__builtin_neon_vbsl_v:
6304 case NEON::BI__builtin_neon_vbslq_v: {
6305 llvm::Type *BitTy = llvm::VectorType::getInteger(VTy);
6306 Ops[0] = Builder.CreateBitCast(Ops[0], BitTy, "vbsl");
6307 Ops[1] = Builder.CreateBitCast(Ops[1], BitTy, "vbsl");
6308 Ops[2] = Builder.CreateBitCast(Ops[2], BitTy, "vbsl");
6309
6310 Ops[1] = Builder.CreateAnd(Ops[0], Ops[1], "vbsl");
6311 Ops[2] = Builder.CreateAnd(Builder.CreateNot(Ops[0]), Ops[2], "vbsl");
6312 Ops[0] = Builder.CreateOr(Ops[1], Ops[2], "vbsl");
6313 return Builder.CreateBitCast(Ops[0], Ty);
6314 }
6315 case NEON::BI__builtin_neon_vfma_lane_v:
6316 case NEON::BI__builtin_neon_vfmaq_lane_v: { // Only used for FP types
6317 // The ARM builtins (and instructions) have the addend as the first
6318 // operand, but the 'fma' intrinsics have it last. Swap it around here.
6319 Value *Addend = Ops[0];
6320 Value *Multiplicand = Ops[1];
6321 Value *LaneSource = Ops[2];
6322 Ops[0] = Multiplicand;
6323 Ops[1] = LaneSource;
6324 Ops[2] = Addend;
6325
6326 // Now adjust things to handle the lane access.
6327 llvm::Type *SourceTy = BuiltinID == NEON::BI__builtin_neon_vfmaq_lane_v ?
6328 llvm::VectorType::get(VTy->getElementType(), VTy->getNumElements() / 2) :
6329 VTy;
6330 llvm::Constant *cst = cast<Constant>(Ops[3]);
6331 Value *SV = llvm::ConstantVector::getSplat(VTy->getNumElements(), cst);
6332 Ops[1] = Builder.CreateBitCast(Ops[1], SourceTy);
6333 Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV, "lane");
6334
6335 Ops.pop_back();
6336 Int = Intrinsic::fma;
6337 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "fmla");
6338 }
6339 case NEON::BI__builtin_neon_vfma_laneq_v: {
6340 llvm::VectorType *VTy = cast<llvm::VectorType>(Ty);
6341 // v1f64 fma should be mapped to Neon scalar f64 fma
6342 if (VTy && VTy->getElementType() == DoubleTy) {
6343 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6344 Ops[1] = Builder.CreateBitCast(Ops[1], DoubleTy);
6345 llvm::Type *VTy = GetNeonType(this,
6346 NeonTypeFlags(NeonTypeFlags::Float64, false, true));
6347 Ops[2] = Builder.CreateBitCast(Ops[2], VTy);
6348 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
6349 Value *F = CGM.getIntrinsic(Intrinsic::fma, DoubleTy);
David Blaikie43f9bb72015-05-18 22:14:03 +00006350 Value *Result = Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006351 return Builder.CreateBitCast(Result, Ty);
6352 }
6353 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6354 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6355 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6356
6357 llvm::Type *STy = llvm::VectorType::get(VTy->getElementType(),
6358 VTy->getNumElements() * 2);
6359 Ops[2] = Builder.CreateBitCast(Ops[2], STy);
6360 Value* SV = llvm::ConstantVector::getSplat(VTy->getNumElements(),
6361 cast<ConstantInt>(Ops[3]));
6362 Ops[2] = Builder.CreateShuffleVector(Ops[2], Ops[2], SV, "lane");
6363
David Blaikie43f9bb72015-05-18 22:14:03 +00006364 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006365 }
6366 case NEON::BI__builtin_neon_vfmaq_laneq_v: {
6367 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6368 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6369 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
6370
6371 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
6372 Ops[2] = EmitNeonSplat(Ops[2], cast<ConstantInt>(Ops[3]));
David Blaikie43f9bb72015-05-18 22:14:03 +00006373 return Builder.CreateCall(F, {Ops[2], Ops[1], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006374 }
6375 case NEON::BI__builtin_neon_vfmas_lane_f32:
6376 case NEON::BI__builtin_neon_vfmas_laneq_f32:
6377 case NEON::BI__builtin_neon_vfmad_lane_f64:
6378 case NEON::BI__builtin_neon_vfmad_laneq_f64: {
6379 Ops.push_back(EmitScalarExpr(E->getArg(3)));
David Majnemerced8bdf2015-02-25 17:36:15 +00006380 llvm::Type *Ty = ConvertType(E->getCallReturnType(getContext()));
Tim Northovera2ee4332014-03-29 15:09:45 +00006381 Value *F = CGM.getIntrinsic(Intrinsic::fma, Ty);
6382 Ops[2] = Builder.CreateExtractElement(Ops[2], Ops[3], "extract");
David Blaikie43f9bb72015-05-18 22:14:03 +00006383 return Builder.CreateCall(F, {Ops[1], Ops[2], Ops[0]});
Tim Northovera2ee4332014-03-29 15:09:45 +00006384 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006385 case NEON::BI__builtin_neon_vmull_v:
6386 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006387 Int = usgn ? Intrinsic::aarch64_neon_umull : Intrinsic::aarch64_neon_smull;
6388 if (Type.isPoly()) Int = Intrinsic::aarch64_neon_pmull;
Tim Northovera2ee4332014-03-29 15:09:45 +00006389 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmull");
6390 case NEON::BI__builtin_neon_vmax_v:
6391 case NEON::BI__builtin_neon_vmaxq_v:
6392 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006393 Int = usgn ? Intrinsic::aarch64_neon_umax : Intrinsic::aarch64_neon_smax;
6394 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmax;
Tim Northovera2ee4332014-03-29 15:09:45 +00006395 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmax");
6396 case NEON::BI__builtin_neon_vmin_v:
6397 case NEON::BI__builtin_neon_vminq_v:
6398 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006399 Int = usgn ? Intrinsic::aarch64_neon_umin : Intrinsic::aarch64_neon_smin;
6400 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmin;
Tim Northovera2ee4332014-03-29 15:09:45 +00006401 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmin");
6402 case NEON::BI__builtin_neon_vabd_v:
6403 case NEON::BI__builtin_neon_vabdq_v:
6404 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006405 Int = usgn ? Intrinsic::aarch64_neon_uabd : Intrinsic::aarch64_neon_sabd;
6406 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fabd;
Tim Northovera2ee4332014-03-29 15:09:45 +00006407 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vabd");
6408 case NEON::BI__builtin_neon_vpadal_v:
6409 case NEON::BI__builtin_neon_vpadalq_v: {
6410 unsigned ArgElts = VTy->getNumElements();
6411 llvm::IntegerType *EltTy = cast<IntegerType>(VTy->getElementType());
6412 unsigned BitWidth = EltTy->getBitWidth();
6413 llvm::Type *ArgTy = llvm::VectorType::get(
6414 llvm::IntegerType::get(getLLVMContext(), BitWidth/2), 2*ArgElts);
6415 llvm::Type* Tys[2] = { VTy, ArgTy };
Tim Northover573cbee2014-05-24 12:52:07 +00006416 Int = usgn ? Intrinsic::aarch64_neon_uaddlp : Intrinsic::aarch64_neon_saddlp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006417 SmallVector<llvm::Value*, 1> TmpOps;
6418 TmpOps.push_back(Ops[1]);
6419 Function *F = CGM.getIntrinsic(Int, Tys);
6420 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vpadal");
6421 llvm::Value *addend = Builder.CreateBitCast(Ops[0], tmp->getType());
6422 return Builder.CreateAdd(tmp, addend);
6423 }
6424 case NEON::BI__builtin_neon_vpmin_v:
6425 case NEON::BI__builtin_neon_vpminq_v:
6426 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006427 Int = usgn ? Intrinsic::aarch64_neon_uminp : Intrinsic::aarch64_neon_sminp;
6428 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fminp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006429 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmin");
6430 case NEON::BI__builtin_neon_vpmax_v:
6431 case NEON::BI__builtin_neon_vpmaxq_v:
6432 // FIXME: improve sharing scheme to cope with 3 alternative LLVM intrinsics.
Tim Northover573cbee2014-05-24 12:52:07 +00006433 Int = usgn ? Intrinsic::aarch64_neon_umaxp : Intrinsic::aarch64_neon_smaxp;
6434 if (Ty->isFPOrFPVectorTy()) Int = Intrinsic::aarch64_neon_fmaxp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006435 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmax");
6436 case NEON::BI__builtin_neon_vminnm_v:
6437 case NEON::BI__builtin_neon_vminnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006438 Int = Intrinsic::aarch64_neon_fminnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006439 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vminnm");
6440 case NEON::BI__builtin_neon_vmaxnm_v:
6441 case NEON::BI__builtin_neon_vmaxnmq_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006442 Int = Intrinsic::aarch64_neon_fmaxnm;
Tim Northovera2ee4332014-03-29 15:09:45 +00006443 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmaxnm");
6444 case NEON::BI__builtin_neon_vrecpss_f32: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006445 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006446 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, FloatTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006447 Ops, "vrecps");
6448 }
6449 case NEON::BI__builtin_neon_vrecpsd_f64: {
Tim Northovera2ee4332014-03-29 15:09:45 +00006450 Ops.push_back(EmitScalarExpr(E->getArg(1)));
Ahmed Bougacha40882bb2015-08-24 23:47:29 +00006451 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_frecps, DoubleTy),
Tim Northovera2ee4332014-03-29 15:09:45 +00006452 Ops, "vrecps");
6453 }
Tim Northovera2ee4332014-03-29 15:09:45 +00006454 case NEON::BI__builtin_neon_vqshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006455 Int = Intrinsic::aarch64_neon_sqshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006456 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrun_n");
6457 case NEON::BI__builtin_neon_vqrshrun_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006458 Int = Intrinsic::aarch64_neon_sqrshrun;
Tim Northovera2ee4332014-03-29 15:09:45 +00006459 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrun_n");
6460 case NEON::BI__builtin_neon_vqshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006461 Int = usgn ? Intrinsic::aarch64_neon_uqshrn : Intrinsic::aarch64_neon_sqshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006462 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqshrn_n");
6463 case NEON::BI__builtin_neon_vrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006464 Int = Intrinsic::aarch64_neon_rshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006465 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrshrn_n");
6466 case NEON::BI__builtin_neon_vqrshrn_n_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006467 Int = usgn ? Intrinsic::aarch64_neon_uqrshrn : Intrinsic::aarch64_neon_sqrshrn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006468 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vqrshrn_n");
6469 case NEON::BI__builtin_neon_vrnda_v:
6470 case NEON::BI__builtin_neon_vrndaq_v: {
6471 Int = Intrinsic::round;
6472 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrnda");
6473 }
6474 case NEON::BI__builtin_neon_vrndi_v:
6475 case NEON::BI__builtin_neon_vrndiq_v: {
6476 Int = Intrinsic::nearbyint;
6477 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndi");
6478 }
6479 case NEON::BI__builtin_neon_vrndm_v:
6480 case NEON::BI__builtin_neon_vrndmq_v: {
6481 Int = Intrinsic::floor;
6482 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndm");
6483 }
6484 case NEON::BI__builtin_neon_vrndn_v:
6485 case NEON::BI__builtin_neon_vrndnq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006486 Int = Intrinsic::aarch64_neon_frintn;
Tim Northovera2ee4332014-03-29 15:09:45 +00006487 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndn");
6488 }
6489 case NEON::BI__builtin_neon_vrndp_v:
6490 case NEON::BI__builtin_neon_vrndpq_v: {
6491 Int = Intrinsic::ceil;
6492 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndp");
6493 }
6494 case NEON::BI__builtin_neon_vrndx_v:
6495 case NEON::BI__builtin_neon_vrndxq_v: {
6496 Int = Intrinsic::rint;
6497 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndx");
6498 }
6499 case NEON::BI__builtin_neon_vrnd_v:
6500 case NEON::BI__builtin_neon_vrndq_v: {
6501 Int = Intrinsic::trunc;
6502 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrndz");
6503 }
6504 case NEON::BI__builtin_neon_vceqz_v:
6505 case NEON::BI__builtin_neon_vceqzq_v:
6506 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OEQ,
6507 ICmpInst::ICMP_EQ, "vceqz");
6508 case NEON::BI__builtin_neon_vcgez_v:
6509 case NEON::BI__builtin_neon_vcgezq_v:
6510 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGE,
6511 ICmpInst::ICMP_SGE, "vcgez");
6512 case NEON::BI__builtin_neon_vclez_v:
6513 case NEON::BI__builtin_neon_vclezq_v:
6514 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLE,
6515 ICmpInst::ICMP_SLE, "vclez");
6516 case NEON::BI__builtin_neon_vcgtz_v:
6517 case NEON::BI__builtin_neon_vcgtzq_v:
6518 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OGT,
6519 ICmpInst::ICMP_SGT, "vcgtz");
6520 case NEON::BI__builtin_neon_vcltz_v:
6521 case NEON::BI__builtin_neon_vcltzq_v:
6522 return EmitAArch64CompareBuiltinExpr(Ops[0], Ty, ICmpInst::FCMP_OLT,
6523 ICmpInst::ICMP_SLT, "vcltz");
6524 case NEON::BI__builtin_neon_vcvt_f64_v:
6525 case NEON::BI__builtin_neon_vcvtq_f64_v:
6526 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6527 Ty = GetNeonType(this, NeonTypeFlags(NeonTypeFlags::Float64, false, quad));
6528 return usgn ? Builder.CreateUIToFP(Ops[0], Ty, "vcvt")
6529 : Builder.CreateSIToFP(Ops[0], Ty, "vcvt");
6530 case NEON::BI__builtin_neon_vcvt_f64_f32: {
6531 assert(Type.getEltType() == NeonTypeFlags::Float64 && quad &&
6532 "unexpected vcvt_f64_f32 builtin");
6533 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float32, false, false);
6534 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6535
6536 return Builder.CreateFPExt(Ops[0], Ty, "vcvt");
6537 }
6538 case NEON::BI__builtin_neon_vcvt_f32_f64: {
6539 assert(Type.getEltType() == NeonTypeFlags::Float32 &&
6540 "unexpected vcvt_f32_f64 builtin");
6541 NeonTypeFlags SrcFlag = NeonTypeFlags(NeonTypeFlags::Float64, false, true);
6542 Ops[0] = Builder.CreateBitCast(Ops[0], GetNeonType(this, SrcFlag));
6543
6544 return Builder.CreateFPTrunc(Ops[0], Ty, "vcvt");
6545 }
6546 case NEON::BI__builtin_neon_vcvt_s32_v:
6547 case NEON::BI__builtin_neon_vcvt_u32_v:
6548 case NEON::BI__builtin_neon_vcvt_s64_v:
6549 case NEON::BI__builtin_neon_vcvt_u64_v:
6550 case NEON::BI__builtin_neon_vcvtq_s32_v:
6551 case NEON::BI__builtin_neon_vcvtq_u32_v:
6552 case NEON::BI__builtin_neon_vcvtq_s64_v:
Sjoerd Meijer98ee7852017-07-06 16:37:31 +00006553 case NEON::BI__builtin_neon_vcvtq_u64_v: {
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006554 Ops[0] = Builder.CreateBitCast(Ops[0], GetFloatNeonType(this, Type));
Tim Northovera2ee4332014-03-29 15:09:45 +00006555 if (usgn)
6556 return Builder.CreateFPToUI(Ops[0], Ty);
6557 return Builder.CreateFPToSI(Ops[0], Ty);
6558 }
6559 case NEON::BI__builtin_neon_vcvta_s32_v:
6560 case NEON::BI__builtin_neon_vcvtaq_s32_v:
6561 case NEON::BI__builtin_neon_vcvta_u32_v:
6562 case NEON::BI__builtin_neon_vcvtaq_u32_v:
6563 case NEON::BI__builtin_neon_vcvta_s64_v:
6564 case NEON::BI__builtin_neon_vcvtaq_s64_v:
6565 case NEON::BI__builtin_neon_vcvta_u64_v:
6566 case NEON::BI__builtin_neon_vcvtaq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006567 Int = usgn ? Intrinsic::aarch64_neon_fcvtau : Intrinsic::aarch64_neon_fcvtas;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006568 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006569 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvta");
6570 }
6571 case NEON::BI__builtin_neon_vcvtm_s32_v:
6572 case NEON::BI__builtin_neon_vcvtmq_s32_v:
6573 case NEON::BI__builtin_neon_vcvtm_u32_v:
6574 case NEON::BI__builtin_neon_vcvtmq_u32_v:
6575 case NEON::BI__builtin_neon_vcvtm_s64_v:
6576 case NEON::BI__builtin_neon_vcvtmq_s64_v:
6577 case NEON::BI__builtin_neon_vcvtm_u64_v:
6578 case NEON::BI__builtin_neon_vcvtmq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006579 Int = usgn ? Intrinsic::aarch64_neon_fcvtmu : Intrinsic::aarch64_neon_fcvtms;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006580 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006581 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtm");
6582 }
6583 case NEON::BI__builtin_neon_vcvtn_s32_v:
6584 case NEON::BI__builtin_neon_vcvtnq_s32_v:
6585 case NEON::BI__builtin_neon_vcvtn_u32_v:
6586 case NEON::BI__builtin_neon_vcvtnq_u32_v:
6587 case NEON::BI__builtin_neon_vcvtn_s64_v:
6588 case NEON::BI__builtin_neon_vcvtnq_s64_v:
6589 case NEON::BI__builtin_neon_vcvtn_u64_v:
6590 case NEON::BI__builtin_neon_vcvtnq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006591 Int = usgn ? Intrinsic::aarch64_neon_fcvtnu : Intrinsic::aarch64_neon_fcvtns;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006592 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006593 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtn");
6594 }
6595 case NEON::BI__builtin_neon_vcvtp_s32_v:
6596 case NEON::BI__builtin_neon_vcvtpq_s32_v:
6597 case NEON::BI__builtin_neon_vcvtp_u32_v:
6598 case NEON::BI__builtin_neon_vcvtpq_u32_v:
6599 case NEON::BI__builtin_neon_vcvtp_s64_v:
6600 case NEON::BI__builtin_neon_vcvtpq_s64_v:
6601 case NEON::BI__builtin_neon_vcvtp_u64_v:
6602 case NEON::BI__builtin_neon_vcvtpq_u64_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006603 Int = usgn ? Intrinsic::aarch64_neon_fcvtpu : Intrinsic::aarch64_neon_fcvtps;
Ahmed Bougacha774b5e22015-08-24 23:41:31 +00006604 llvm::Type *Tys[2] = { Ty, GetFloatNeonType(this, Type) };
Tim Northovera2ee4332014-03-29 15:09:45 +00006605 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vcvtp");
6606 }
6607 case NEON::BI__builtin_neon_vmulx_v:
6608 case NEON::BI__builtin_neon_vmulxq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006609 Int = Intrinsic::aarch64_neon_fmulx;
Tim Northovera2ee4332014-03-29 15:09:45 +00006610 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vmulx");
6611 }
6612 case NEON::BI__builtin_neon_vmul_lane_v:
6613 case NEON::BI__builtin_neon_vmul_laneq_v: {
6614 // v1f64 vmul_lane should be mapped to Neon scalar mul lane
6615 bool Quad = false;
6616 if (BuiltinID == NEON::BI__builtin_neon_vmul_laneq_v)
6617 Quad = true;
6618 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6619 llvm::Type *VTy = GetNeonType(this,
6620 NeonTypeFlags(NeonTypeFlags::Float64, false, Quad));
6621 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
6622 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2], "extract");
6623 Value *Result = Builder.CreateFMul(Ops[0], Ops[1]);
6624 return Builder.CreateBitCast(Result, Ty);
6625 }
Tim Northover0c68faa2014-03-31 15:47:09 +00006626 case NEON::BI__builtin_neon_vnegd_s64:
6627 return Builder.CreateNeg(EmitScalarExpr(E->getArg(0)), "vnegd");
Tim Northovera2ee4332014-03-29 15:09:45 +00006628 case NEON::BI__builtin_neon_vpmaxnm_v:
6629 case NEON::BI__builtin_neon_vpmaxnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006630 Int = Intrinsic::aarch64_neon_fmaxnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006631 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpmaxnm");
6632 }
6633 case NEON::BI__builtin_neon_vpminnm_v:
6634 case NEON::BI__builtin_neon_vpminnmq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006635 Int = Intrinsic::aarch64_neon_fminnmp;
Tim Northovera2ee4332014-03-29 15:09:45 +00006636 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vpminnm");
6637 }
6638 case NEON::BI__builtin_neon_vsqrt_v:
6639 case NEON::BI__builtin_neon_vsqrtq_v: {
6640 Int = Intrinsic::sqrt;
6641 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6642 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqrt");
6643 }
6644 case NEON::BI__builtin_neon_vrbit_v:
6645 case NEON::BI__builtin_neon_vrbitq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006646 Int = Intrinsic::aarch64_neon_rbit;
Tim Northovera2ee4332014-03-29 15:09:45 +00006647 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vrbit");
6648 }
6649 case NEON::BI__builtin_neon_vaddv_u8:
6650 // FIXME: These are handled by the AArch64 scalar code.
6651 usgn = true;
6652 // FALLTHROUGH
6653 case NEON::BI__builtin_neon_vaddv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006654 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006655 Ty = Int32Ty;
6656 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006657 llvm::Type *Tys[2] = { Ty, VTy };
6658 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6659 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006660 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006661 }
6662 case NEON::BI__builtin_neon_vaddv_u16:
6663 usgn = true;
6664 // FALLTHROUGH
6665 case NEON::BI__builtin_neon_vaddv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006666 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006667 Ty = Int32Ty;
6668 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006669 llvm::Type *Tys[2] = { Ty, VTy };
6670 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6671 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006672 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006673 }
6674 case NEON::BI__builtin_neon_vaddvq_u8:
6675 usgn = true;
6676 // FALLTHROUGH
6677 case NEON::BI__builtin_neon_vaddvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006678 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006679 Ty = Int32Ty;
6680 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006681 llvm::Type *Tys[2] = { Ty, VTy };
6682 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6683 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006684 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006685 }
6686 case NEON::BI__builtin_neon_vaddvq_u16:
6687 usgn = true;
6688 // FALLTHROUGH
6689 case NEON::BI__builtin_neon_vaddvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006690 Int = usgn ? Intrinsic::aarch64_neon_uaddv : Intrinsic::aarch64_neon_saddv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006691 Ty = Int32Ty;
6692 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006693 llvm::Type *Tys[2] = { Ty, VTy };
6694 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6695 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006696 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006697 }
6698 case NEON::BI__builtin_neon_vmaxv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006699 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006700 Ty = Int32Ty;
6701 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006702 llvm::Type *Tys[2] = { Ty, VTy };
6703 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6704 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006705 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006706 }
6707 case NEON::BI__builtin_neon_vmaxv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006708 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006709 Ty = Int32Ty;
6710 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006711 llvm::Type *Tys[2] = { Ty, VTy };
6712 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6713 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006714 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006715 }
6716 case NEON::BI__builtin_neon_vmaxvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006717 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006718 Ty = Int32Ty;
6719 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006720 llvm::Type *Tys[2] = { Ty, VTy };
6721 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6722 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006723 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006724 }
6725 case NEON::BI__builtin_neon_vmaxvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006726 Int = Intrinsic::aarch64_neon_umaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006727 Ty = Int32Ty;
6728 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006729 llvm::Type *Tys[2] = { Ty, VTy };
6730 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6731 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006732 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006733 }
6734 case NEON::BI__builtin_neon_vmaxv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006735 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006736 Ty = Int32Ty;
6737 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006738 llvm::Type *Tys[2] = { Ty, VTy };
6739 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6740 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006741 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006742 }
6743 case NEON::BI__builtin_neon_vmaxv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006744 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006745 Ty = Int32Ty;
6746 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006747 llvm::Type *Tys[2] = { Ty, VTy };
6748 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6749 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006750 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006751 }
6752 case NEON::BI__builtin_neon_vmaxvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006753 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006754 Ty = Int32Ty;
6755 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006756 llvm::Type *Tys[2] = { Ty, VTy };
6757 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6758 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006759 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006760 }
6761 case NEON::BI__builtin_neon_vmaxvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006762 Int = Intrinsic::aarch64_neon_smaxv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006763 Ty = Int32Ty;
6764 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006765 llvm::Type *Tys[2] = { Ty, VTy };
6766 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6767 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vmaxv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006768 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006769 }
6770 case NEON::BI__builtin_neon_vminv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006771 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006772 Ty = Int32Ty;
6773 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006774 llvm::Type *Tys[2] = { Ty, VTy };
6775 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6776 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006777 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006778 }
6779 case NEON::BI__builtin_neon_vminv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006780 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006781 Ty = Int32Ty;
6782 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006783 llvm::Type *Tys[2] = { Ty, VTy };
6784 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6785 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006786 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006787 }
6788 case NEON::BI__builtin_neon_vminvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006789 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006790 Ty = Int32Ty;
6791 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006792 llvm::Type *Tys[2] = { Ty, VTy };
6793 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6794 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006795 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006796 }
6797 case NEON::BI__builtin_neon_vminvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006798 Int = Intrinsic::aarch64_neon_uminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006799 Ty = Int32Ty;
6800 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006801 llvm::Type *Tys[2] = { Ty, VTy };
6802 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6803 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006804 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006805 }
6806 case NEON::BI__builtin_neon_vminv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006807 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006808 Ty = Int32Ty;
6809 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006810 llvm::Type *Tys[2] = { Ty, VTy };
6811 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6812 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006813 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006814 }
6815 case NEON::BI__builtin_neon_vminv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006816 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006817 Ty = Int32Ty;
6818 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006819 llvm::Type *Tys[2] = { Ty, VTy };
6820 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6821 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006822 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006823 }
6824 case NEON::BI__builtin_neon_vminvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006825 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006826 Ty = Int32Ty;
6827 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006828 llvm::Type *Tys[2] = { Ty, VTy };
6829 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6830 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006831 return Builder.CreateTrunc(Ops[0], Int8Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006832 }
6833 case NEON::BI__builtin_neon_vminvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006834 Int = Intrinsic::aarch64_neon_sminv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006835 Ty = Int32Ty;
6836 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006837 llvm::Type *Tys[2] = { Ty, VTy };
6838 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6839 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vminv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006840 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006841 }
6842 case NEON::BI__builtin_neon_vmul_n_f64: {
6843 Ops[0] = Builder.CreateBitCast(Ops[0], DoubleTy);
6844 Value *RHS = Builder.CreateBitCast(EmitScalarExpr(E->getArg(1)), DoubleTy);
6845 return Builder.CreateFMul(Ops[0], RHS);
6846 }
6847 case NEON::BI__builtin_neon_vaddlv_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006848 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006849 Ty = Int32Ty;
6850 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006851 llvm::Type *Tys[2] = { Ty, VTy };
6852 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6853 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006854 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006855 }
6856 case NEON::BI__builtin_neon_vaddlv_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006857 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006858 Ty = Int32Ty;
6859 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006860 llvm::Type *Tys[2] = { Ty, VTy };
6861 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6862 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6863 }
6864 case NEON::BI__builtin_neon_vaddlvq_u8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006865 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006866 Ty = Int32Ty;
6867 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006868 llvm::Type *Tys[2] = { Ty, VTy };
6869 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6870 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006871 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006872 }
6873 case NEON::BI__builtin_neon_vaddlvq_u16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006874 Int = Intrinsic::aarch64_neon_uaddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006875 Ty = Int32Ty;
6876 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006877 llvm::Type *Tys[2] = { Ty, VTy };
6878 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6879 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6880 }
6881 case NEON::BI__builtin_neon_vaddlv_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006882 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006883 Ty = Int32Ty;
6884 VTy = llvm::VectorType::get(Int8Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006885 llvm::Type *Tys[2] = { Ty, VTy };
6886 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6887 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006888 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006889 }
6890 case NEON::BI__builtin_neon_vaddlv_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006891 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006892 Ty = Int32Ty;
6893 VTy = llvm::VectorType::get(Int16Ty, 4);
Tim Northovera2ee4332014-03-29 15:09:45 +00006894 llvm::Type *Tys[2] = { Ty, VTy };
6895 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6896 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6897 }
6898 case NEON::BI__builtin_neon_vaddlvq_s8: {
Tim Northover573cbee2014-05-24 12:52:07 +00006899 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006900 Ty = Int32Ty;
6901 VTy = llvm::VectorType::get(Int8Ty, 16);
Tim Northovera2ee4332014-03-29 15:09:45 +00006902 llvm::Type *Tys[2] = { Ty, VTy };
6903 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6904 Ops[0] = EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
Benjamin Kramerc385a802015-07-28 15:40:11 +00006905 return Builder.CreateTrunc(Ops[0], Int16Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00006906 }
6907 case NEON::BI__builtin_neon_vaddlvq_s16: {
Tim Northover573cbee2014-05-24 12:52:07 +00006908 Int = Intrinsic::aarch64_neon_saddlv;
Benjamin Kramerc385a802015-07-28 15:40:11 +00006909 Ty = Int32Ty;
6910 VTy = llvm::VectorType::get(Int16Ty, 8);
Tim Northovera2ee4332014-03-29 15:09:45 +00006911 llvm::Type *Tys[2] = { Ty, VTy };
6912 Ops.push_back(EmitScalarExpr(E->getArg(0)));
6913 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "vaddlv");
6914 }
6915 case NEON::BI__builtin_neon_vsri_n_v:
6916 case NEON::BI__builtin_neon_vsriq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006917 Int = Intrinsic::aarch64_neon_vsri;
Tim Northovera2ee4332014-03-29 15:09:45 +00006918 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6919 return EmitNeonCall(Intrin, Ops, "vsri_n");
6920 }
6921 case NEON::BI__builtin_neon_vsli_n_v:
6922 case NEON::BI__builtin_neon_vsliq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006923 Int = Intrinsic::aarch64_neon_vsli;
Tim Northovera2ee4332014-03-29 15:09:45 +00006924 llvm::Function *Intrin = CGM.getIntrinsic(Int, Ty);
6925 return EmitNeonCall(Intrin, Ops, "vsli_n");
6926 }
6927 case NEON::BI__builtin_neon_vsra_n_v:
6928 case NEON::BI__builtin_neon_vsraq_n_v:
6929 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
6930 Ops[1] = EmitNeonRShiftImm(Ops[1], Ops[2], Ty, usgn, "vsra_n");
6931 return Builder.CreateAdd(Ops[0], Ops[1]);
6932 case NEON::BI__builtin_neon_vrsra_n_v:
6933 case NEON::BI__builtin_neon_vrsraq_n_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00006934 Int = usgn ? Intrinsic::aarch64_neon_urshl : Intrinsic::aarch64_neon_srshl;
Tim Northovera2ee4332014-03-29 15:09:45 +00006935 SmallVector<llvm::Value*,2> TmpOps;
6936 TmpOps.push_back(Ops[1]);
6937 TmpOps.push_back(Ops[2]);
6938 Function* F = CGM.getIntrinsic(Int, Ty);
6939 llvm::Value *tmp = EmitNeonCall(F, TmpOps, "vrshr_n", 1, true);
6940 Ops[0] = Builder.CreateBitCast(Ops[0], VTy);
6941 return Builder.CreateAdd(Ops[0], tmp);
6942 }
6943 // FIXME: Sharing loads & stores with 32-bit is complicated by the absence
6944 // of an Align parameter here.
6945 case NEON::BI__builtin_neon_vld1_x2_v:
6946 case NEON::BI__builtin_neon_vld1q_x2_v:
6947 case NEON::BI__builtin_neon_vld1_x3_v:
6948 case NEON::BI__builtin_neon_vld1q_x3_v:
6949 case NEON::BI__builtin_neon_vld1_x4_v:
6950 case NEON::BI__builtin_neon_vld1q_x4_v: {
6951 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6952 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
6953 llvm::Type *Tys[2] = { VTy, PTy };
6954 unsigned Int;
6955 switch (BuiltinID) {
6956 case NEON::BI__builtin_neon_vld1_x2_v:
6957 case NEON::BI__builtin_neon_vld1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006958 Int = Intrinsic::aarch64_neon_ld1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006959 break;
6960 case NEON::BI__builtin_neon_vld1_x3_v:
6961 case NEON::BI__builtin_neon_vld1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006962 Int = Intrinsic::aarch64_neon_ld1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006963 break;
6964 case NEON::BI__builtin_neon_vld1_x4_v:
6965 case NEON::BI__builtin_neon_vld1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006966 Int = Intrinsic::aarch64_neon_ld1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006967 break;
6968 }
6969 Function *F = CGM.getIntrinsic(Int, Tys);
6970 Ops[1] = Builder.CreateCall(F, Ops[1], "vld1xN");
6971 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
6972 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00006973 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00006974 }
6975 case NEON::BI__builtin_neon_vst1_x2_v:
6976 case NEON::BI__builtin_neon_vst1q_x2_v:
6977 case NEON::BI__builtin_neon_vst1_x3_v:
6978 case NEON::BI__builtin_neon_vst1q_x3_v:
6979 case NEON::BI__builtin_neon_vst1_x4_v:
6980 case NEON::BI__builtin_neon_vst1q_x4_v: {
6981 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy->getVectorElementType());
6982 llvm::Type *Tys[2] = { VTy, PTy };
6983 unsigned Int;
6984 switch (BuiltinID) {
6985 case NEON::BI__builtin_neon_vst1_x2_v:
6986 case NEON::BI__builtin_neon_vst1q_x2_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006987 Int = Intrinsic::aarch64_neon_st1x2;
Tim Northovera2ee4332014-03-29 15:09:45 +00006988 break;
6989 case NEON::BI__builtin_neon_vst1_x3_v:
6990 case NEON::BI__builtin_neon_vst1q_x3_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006991 Int = Intrinsic::aarch64_neon_st1x3;
Tim Northovera2ee4332014-03-29 15:09:45 +00006992 break;
6993 case NEON::BI__builtin_neon_vst1_x4_v:
6994 case NEON::BI__builtin_neon_vst1q_x4_v:
Tim Northover573cbee2014-05-24 12:52:07 +00006995 Int = Intrinsic::aarch64_neon_st1x4;
Tim Northovera2ee4332014-03-29 15:09:45 +00006996 break;
6997 }
Benjamin Kramerc385a802015-07-28 15:40:11 +00006998 std::rotate(Ops.begin(), Ops.begin() + 1, Ops.end());
6999 return EmitNeonCall(CGM.getIntrinsic(Int, Tys), Ops, "");
Tim Northovera2ee4332014-03-29 15:09:45 +00007000 }
7001 case NEON::BI__builtin_neon_vld1_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00007002 case NEON::BI__builtin_neon_vld1q_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007003 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
Peter Collingbourneb367c562016-11-28 22:30:21 +00007004 auto Alignment = CharUnits::fromQuantity(
7005 BuiltinID == NEON::BI__builtin_neon_vld1_v ? 8 : 16);
7006 return Builder.CreateAlignedLoad(VTy, Ops[0], Alignment);
7007 }
Tim Northovera2ee4332014-03-29 15:09:45 +00007008 case NEON::BI__builtin_neon_vst1_v:
7009 case NEON::BI__builtin_neon_vst1q_v:
7010 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(VTy));
7011 Ops[1] = Builder.CreateBitCast(Ops[1], VTy);
John McCall7f416cc2015-09-08 08:05:57 +00007012 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007013 case NEON::BI__builtin_neon_vld1_lane_v:
Peter Collingbourneb367c562016-11-28 22:30:21 +00007014 case NEON::BI__builtin_neon_vld1q_lane_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007015 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7016 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
7017 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00007018 auto Alignment = CharUnits::fromQuantity(
7019 BuiltinID == NEON::BI__builtin_neon_vld1_lane_v ? 8 : 16);
7020 Ops[0] =
7021 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Tim Northovera2ee4332014-03-29 15:09:45 +00007022 return Builder.CreateInsertElement(Ops[1], Ops[0], Ops[2], "vld1_lane");
Peter Collingbourneb367c562016-11-28 22:30:21 +00007023 }
Tim Northovera2ee4332014-03-29 15:09:45 +00007024 case NEON::BI__builtin_neon_vld1_dup_v:
7025 case NEON::BI__builtin_neon_vld1q_dup_v: {
7026 Value *V = UndefValue::get(Ty);
7027 Ty = llvm::PointerType::getUnqual(VTy->getElementType());
7028 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
Peter Collingbourneb367c562016-11-28 22:30:21 +00007029 auto Alignment = CharUnits::fromQuantity(
7030 BuiltinID == NEON::BI__builtin_neon_vld1_dup_v ? 8 : 16);
7031 Ops[0] =
7032 Builder.CreateAlignedLoad(VTy->getElementType(), Ops[0], Alignment);
Michael J. Spencer5ce26682014-06-02 19:48:59 +00007033 llvm::Constant *CI = ConstantInt::get(Int32Ty, 0);
Tim Northovera2ee4332014-03-29 15:09:45 +00007034 Ops[0] = Builder.CreateInsertElement(V, Ops[0], CI);
7035 return EmitNeonSplat(Ops[0], CI);
7036 }
7037 case NEON::BI__builtin_neon_vst1_lane_v:
7038 case NEON::BI__builtin_neon_vst1q_lane_v:
7039 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7040 Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]);
7041 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
John McCall7f416cc2015-09-08 08:05:57 +00007042 return Builder.CreateDefaultAlignedStore(Ops[1],
7043 Builder.CreateBitCast(Ops[0], Ty));
Tim Northovera2ee4332014-03-29 15:09:45 +00007044 case NEON::BI__builtin_neon_vld2_v:
7045 case NEON::BI__builtin_neon_vld2q_v: {
7046 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
7047 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7048 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007049 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007050 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
7051 Ops[0] = Builder.CreateBitCast(Ops[0],
7052 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007053 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007054 }
7055 case NEON::BI__builtin_neon_vld3_v:
7056 case NEON::BI__builtin_neon_vld3q_v: {
7057 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
7058 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7059 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007060 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007061 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
7062 Ops[0] = Builder.CreateBitCast(Ops[0],
7063 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007064 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007065 }
7066 case NEON::BI__builtin_neon_vld4_v:
7067 case NEON::BI__builtin_neon_vld4q_v: {
7068 llvm::Type *PTy = llvm::PointerType::getUnqual(VTy);
7069 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7070 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007071 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007072 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
7073 Ops[0] = Builder.CreateBitCast(Ops[0],
7074 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007075 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007076 }
Tim Northover74b2def2014-04-01 10:37:47 +00007077 case NEON::BI__builtin_neon_vld2_dup_v:
7078 case NEON::BI__builtin_neon_vld2q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007079 llvm::Type *PTy =
7080 llvm::PointerType::getUnqual(VTy->getElementType());
7081 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7082 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007083 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007084 Ops[1] = Builder.CreateCall(F, Ops[1], "vld2");
7085 Ops[0] = Builder.CreateBitCast(Ops[0],
7086 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007087 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007088 }
Tim Northover74b2def2014-04-01 10:37:47 +00007089 case NEON::BI__builtin_neon_vld3_dup_v:
7090 case NEON::BI__builtin_neon_vld3q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007091 llvm::Type *PTy =
7092 llvm::PointerType::getUnqual(VTy->getElementType());
7093 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7094 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007095 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007096 Ops[1] = Builder.CreateCall(F, Ops[1], "vld3");
7097 Ops[0] = Builder.CreateBitCast(Ops[0],
7098 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007099 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007100 }
Tim Northover74b2def2014-04-01 10:37:47 +00007101 case NEON::BI__builtin_neon_vld4_dup_v:
7102 case NEON::BI__builtin_neon_vld4q_dup_v: {
Tim Northovera2ee4332014-03-29 15:09:45 +00007103 llvm::Type *PTy =
7104 llvm::PointerType::getUnqual(VTy->getElementType());
7105 Ops[1] = Builder.CreateBitCast(Ops[1], PTy);
7106 llvm::Type *Tys[2] = { VTy, PTy };
Tim Northover573cbee2014-05-24 12:52:07 +00007107 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4r, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007108 Ops[1] = Builder.CreateCall(F, Ops[1], "vld4");
7109 Ops[0] = Builder.CreateBitCast(Ops[0],
7110 llvm::PointerType::getUnqual(Ops[1]->getType()));
John McCall7f416cc2015-09-08 08:05:57 +00007111 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007112 }
7113 case NEON::BI__builtin_neon_vld2_lane_v:
7114 case NEON::BI__builtin_neon_vld2q_lane_v: {
7115 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007116 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld2lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007117 Ops.push_back(Ops[1]);
7118 Ops.erase(Ops.begin()+1);
7119 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7120 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007121 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007122 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld2_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007123 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7124 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007125 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007126 }
7127 case NEON::BI__builtin_neon_vld3_lane_v:
7128 case NEON::BI__builtin_neon_vld3q_lane_v: {
7129 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007130 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld3lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007131 Ops.push_back(Ops[1]);
7132 Ops.erase(Ops.begin()+1);
7133 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7134 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
7135 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007136 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007137 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld3_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007138 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7139 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007140 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007141 }
7142 case NEON::BI__builtin_neon_vld4_lane_v:
7143 case NEON::BI__builtin_neon_vld4q_lane_v: {
7144 llvm::Type *Tys[2] = { VTy, Ops[1]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007145 Function *F = CGM.getIntrinsic(Intrinsic::aarch64_neon_ld4lane, Tys);
Tim Northovera2ee4332014-03-29 15:09:45 +00007146 Ops.push_back(Ops[1]);
7147 Ops.erase(Ops.begin()+1);
7148 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7149 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
7150 Ops[3] = Builder.CreateBitCast(Ops[3], Ty);
7151 Ops[4] = Builder.CreateBitCast(Ops[4], Ty);
Benjamin Kramerc385a802015-07-28 15:40:11 +00007152 Ops[5] = Builder.CreateZExt(Ops[5], Int64Ty);
Craig Topper5fc8fc22014-08-27 06:28:36 +00007153 Ops[1] = Builder.CreateCall(F, makeArrayRef(Ops).slice(1), "vld4_lane");
Tim Northovera2ee4332014-03-29 15:09:45 +00007154 Ty = llvm::PointerType::getUnqual(Ops[1]->getType());
7155 Ops[0] = Builder.CreateBitCast(Ops[0], Ty);
John McCall7f416cc2015-09-08 08:05:57 +00007156 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Tim Northovera2ee4332014-03-29 15:09:45 +00007157 }
7158 case NEON::BI__builtin_neon_vst2_v:
7159 case NEON::BI__builtin_neon_vst2q_v: {
7160 Ops.push_back(Ops[0]);
7161 Ops.erase(Ops.begin());
7162 llvm::Type *Tys[2] = { VTy, Ops[2]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007163 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007164 Ops, "");
7165 }
7166 case NEON::BI__builtin_neon_vst2_lane_v:
7167 case NEON::BI__builtin_neon_vst2q_lane_v: {
7168 Ops.push_back(Ops[0]);
7169 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007170 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007171 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007172 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st2lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007173 Ops, "");
7174 }
7175 case NEON::BI__builtin_neon_vst3_v:
7176 case NEON::BI__builtin_neon_vst3q_v: {
7177 Ops.push_back(Ops[0]);
7178 Ops.erase(Ops.begin());
7179 llvm::Type *Tys[2] = { VTy, Ops[3]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007180 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007181 Ops, "");
7182 }
7183 case NEON::BI__builtin_neon_vst3_lane_v:
7184 case NEON::BI__builtin_neon_vst3q_lane_v: {
7185 Ops.push_back(Ops[0]);
7186 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007187 Ops[3] = Builder.CreateZExt(Ops[3], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007188 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007189 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st3lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007190 Ops, "");
7191 }
7192 case NEON::BI__builtin_neon_vst4_v:
7193 case NEON::BI__builtin_neon_vst4q_v: {
7194 Ops.push_back(Ops[0]);
7195 Ops.erase(Ops.begin());
7196 llvm::Type *Tys[2] = { VTy, Ops[4]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007197 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007198 Ops, "");
7199 }
7200 case NEON::BI__builtin_neon_vst4_lane_v:
7201 case NEON::BI__builtin_neon_vst4q_lane_v: {
7202 Ops.push_back(Ops[0]);
7203 Ops.erase(Ops.begin());
Benjamin Kramerc385a802015-07-28 15:40:11 +00007204 Ops[4] = Builder.CreateZExt(Ops[4], Int64Ty);
Tim Northovera2ee4332014-03-29 15:09:45 +00007205 llvm::Type *Tys[2] = { VTy, Ops[5]->getType() };
Tim Northover573cbee2014-05-24 12:52:07 +00007206 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_st4lane, Tys),
Tim Northovera2ee4332014-03-29 15:09:45 +00007207 Ops, "");
7208 }
7209 case NEON::BI__builtin_neon_vtrn_v:
7210 case NEON::BI__builtin_neon_vtrnq_v: {
7211 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7212 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7213 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007214 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007215
7216 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007217 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007218 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007219 Indices.push_back(i+vi);
7220 Indices.push_back(i+e+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007221 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007222 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007223 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vtrn");
John McCall7f416cc2015-09-08 08:05:57 +00007224 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007225 }
7226 return SV;
7227 }
7228 case NEON::BI__builtin_neon_vuzp_v:
7229 case NEON::BI__builtin_neon_vuzpq_v: {
7230 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7231 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7232 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007233 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007234
7235 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007236 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007237 for (unsigned i = 0, e = VTy->getNumElements(); i != e; ++i)
Craig Topper832caf02016-05-29 02:39:30 +00007238 Indices.push_back(2*i+vi);
Tim Northovera2ee4332014-03-29 15:09:45 +00007239
David Blaikiefb901c7a2015-04-04 15:12:29 +00007240 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007241 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vuzp");
John McCall7f416cc2015-09-08 08:05:57 +00007242 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007243 }
7244 return SV;
7245 }
7246 case NEON::BI__builtin_neon_vzip_v:
7247 case NEON::BI__builtin_neon_vzipq_v: {
7248 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::PointerType::getUnqual(Ty));
7249 Ops[1] = Builder.CreateBitCast(Ops[1], Ty);
7250 Ops[2] = Builder.CreateBitCast(Ops[2], Ty);
Craig Topper8a13c412014-05-21 05:09:00 +00007251 Value *SV = nullptr;
Tim Northovera2ee4332014-03-29 15:09:45 +00007252
7253 for (unsigned vi = 0; vi != 2; ++vi) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007254 SmallVector<uint32_t, 16> Indices;
Tim Northovera2ee4332014-03-29 15:09:45 +00007255 for (unsigned i = 0, e = VTy->getNumElements(); i != e; i += 2) {
Craig Topper832caf02016-05-29 02:39:30 +00007256 Indices.push_back((i + vi*e) >> 1);
7257 Indices.push_back(((i + vi*e) >> 1)+e);
Tim Northovera2ee4332014-03-29 15:09:45 +00007258 }
David Blaikiefb901c7a2015-04-04 15:12:29 +00007259 Value *Addr = Builder.CreateConstInBoundsGEP1_32(Ty, Ops[0], vi);
Craig Topper832caf02016-05-29 02:39:30 +00007260 SV = Builder.CreateShuffleVector(Ops[1], Ops[2], Indices, "vzip");
John McCall7f416cc2015-09-08 08:05:57 +00007261 SV = Builder.CreateDefaultAlignedStore(SV, Addr);
Tim Northovera2ee4332014-03-29 15:09:45 +00007262 }
7263 return SV;
7264 }
7265 case NEON::BI__builtin_neon_vqtbl1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007266 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007267 Ops, "vtbl1");
7268 }
7269 case NEON::BI__builtin_neon_vqtbl2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007270 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007271 Ops, "vtbl2");
7272 }
7273 case NEON::BI__builtin_neon_vqtbl3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007274 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007275 Ops, "vtbl3");
7276 }
7277 case NEON::BI__builtin_neon_vqtbl4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007278 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbl4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007279 Ops, "vtbl4");
7280 }
7281 case NEON::BI__builtin_neon_vqtbx1q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007282 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx1, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007283 Ops, "vtbx1");
7284 }
7285 case NEON::BI__builtin_neon_vqtbx2q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007286 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx2, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007287 Ops, "vtbx2");
7288 }
7289 case NEON::BI__builtin_neon_vqtbx3q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007290 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx3, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007291 Ops, "vtbx3");
7292 }
7293 case NEON::BI__builtin_neon_vqtbx4q_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007294 return EmitNeonCall(CGM.getIntrinsic(Intrinsic::aarch64_neon_tbx4, Ty),
Tim Northovera2ee4332014-03-29 15:09:45 +00007295 Ops, "vtbx4");
7296 }
7297 case NEON::BI__builtin_neon_vsqadd_v:
7298 case NEON::BI__builtin_neon_vsqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007299 Int = Intrinsic::aarch64_neon_usqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007300 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vsqadd");
7301 }
7302 case NEON::BI__builtin_neon_vuqadd_v:
7303 case NEON::BI__builtin_neon_vuqaddq_v: {
Tim Northover573cbee2014-05-24 12:52:07 +00007304 Int = Intrinsic::aarch64_neon_suqadd;
Tim Northovera2ee4332014-03-29 15:09:45 +00007305 return EmitNeonCall(CGM.getIntrinsic(Int, Ty), Ops, "vuqadd");
7306 }
7307 }
7308}
7309
Bill Wendling65b2a962010-10-09 08:47:25 +00007310llvm::Value *CodeGenFunction::
Bill Wendlingf1a3fca2012-02-22 09:30:11 +00007311BuildVector(ArrayRef<llvm::Value*> Ops) {
Bill Wendling65b2a962010-10-09 08:47:25 +00007312 assert((Ops.size() & (Ops.size() - 1)) == 0 &&
7313 "Not a power-of-two sized vector!");
7314 bool AllConstants = true;
7315 for (unsigned i = 0, e = Ops.size(); i != e && AllConstants; ++i)
7316 AllConstants &= isa<Constant>(Ops[i]);
7317
7318 // If this is a constant vector, create a ConstantVector.
7319 if (AllConstants) {
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007320 SmallVector<llvm::Constant*, 16> CstOps;
Bill Wendling65b2a962010-10-09 08:47:25 +00007321 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
7322 CstOps.push_back(cast<Constant>(Ops[i]));
7323 return llvm::ConstantVector::get(CstOps);
7324 }
7325
7326 // Otherwise, insertelement the values to build the vector.
7327 Value *Result =
7328 llvm::UndefValue::get(llvm::VectorType::get(Ops[0]->getType(), Ops.size()));
7329
7330 for (unsigned i = 0, e = Ops.size(); i != e; ++i)
Chris Lattner2d6b7b92012-01-25 05:34:41 +00007331 Result = Builder.CreateInsertElement(Result, Ops[i], Builder.getInt32(i));
Bill Wendling65b2a962010-10-09 08:47:25 +00007332
7333 return Result;
7334}
7335
Igor Bregeraadb8762016-06-08 13:59:20 +00007336// Convert the mask from an integer type to a vector of i1.
7337static Value *getMaskVecValue(CodeGenFunction &CGF, Value *Mask,
7338 unsigned NumElts) {
7339
7340 llvm::VectorType *MaskTy = llvm::VectorType::get(CGF.Builder.getInt1Ty(),
7341 cast<IntegerType>(Mask->getType())->getBitWidth());
7342 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy);
7343
7344 // If we have less than 8 elements, then the starting mask was an i8 and
7345 // we need to extract down to the right number of elements.
7346 if (NumElts < 8) {
Craig Topperd1cb4ce2016-06-12 00:41:24 +00007347 uint32_t Indices[4];
Igor Bregeraadb8762016-06-08 13:59:20 +00007348 for (unsigned i = 0; i != NumElts; ++i)
7349 Indices[i] = i;
7350 MaskVec = CGF.Builder.CreateShuffleVector(MaskVec, MaskVec,
7351 makeArrayRef(Indices, NumElts),
7352 "extract");
7353 }
7354 return MaskVec;
7355}
7356
Craig Topper6e891fb2016-05-31 01:50:10 +00007357static Value *EmitX86MaskedStore(CodeGenFunction &CGF,
7358 SmallVectorImpl<Value *> &Ops,
7359 unsigned Align) {
7360 // Cast the pointer to right type.
7361 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7362 llvm::PointerType::getUnqual(Ops[1]->getType()));
7363
7364 // If the mask is all ones just emit a regular store.
7365 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7366 if (C->isAllOnesValue())
7367 return CGF.Builder.CreateAlignedStore(Ops[1], Ops[0], Align);
7368
Igor Bregeraadb8762016-06-08 13:59:20 +00007369 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7370 Ops[1]->getType()->getVectorNumElements());
Craig Topper6e891fb2016-05-31 01:50:10 +00007371
Igor Bregeraadb8762016-06-08 13:59:20 +00007372 return CGF.Builder.CreateMaskedStore(Ops[1], Ops[0], Align, MaskVec);
Craig Topper6e891fb2016-05-31 01:50:10 +00007373}
7374
Craig Topper4b060e32016-05-31 06:58:07 +00007375static Value *EmitX86MaskedLoad(CodeGenFunction &CGF,
7376 SmallVectorImpl<Value *> &Ops, unsigned Align) {
7377 // Cast the pointer to right type.
7378 Ops[0] = CGF.Builder.CreateBitCast(Ops[0],
7379 llvm::PointerType::getUnqual(Ops[1]->getType()));
7380
7381 // If the mask is all ones just emit a regular store.
7382 if (const auto *C = dyn_cast<Constant>(Ops[2]))
7383 if (C->isAllOnesValue())
7384 return CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7385
Igor Bregeraadb8762016-06-08 13:59:20 +00007386 Value *MaskVec = getMaskVecValue(CGF, Ops[2],
7387 Ops[1]->getType()->getVectorNumElements());
Craig Topper4b060e32016-05-31 06:58:07 +00007388
Igor Bregeraadb8762016-06-08 13:59:20 +00007389 return CGF.Builder.CreateMaskedLoad(Ops[0], Align, MaskVec, Ops[1]);
7390}
Craig Topper4b060e32016-05-31 06:58:07 +00007391
Simon Pilgrim2d851732016-07-22 13:58:56 +00007392static Value *EmitX86SubVectorBroadcast(CodeGenFunction &CGF,
7393 SmallVectorImpl<Value *> &Ops,
7394 llvm::Type *DstTy,
7395 unsigned SrcSizeInBits,
7396 unsigned Align) {
7397 // Load the subvector.
7398 Ops[0] = CGF.Builder.CreateAlignedLoad(Ops[0], Align);
7399
7400 // Create broadcast mask.
7401 unsigned NumDstElts = DstTy->getVectorNumElements();
7402 unsigned NumSrcElts = SrcSizeInBits / DstTy->getScalarSizeInBits();
7403
7404 SmallVector<uint32_t, 8> Mask;
7405 for (unsigned i = 0; i != NumDstElts; i += NumSrcElts)
7406 for (unsigned j = 0; j != NumSrcElts; ++j)
7407 Mask.push_back(j);
7408
7409 return CGF.Builder.CreateShuffleVector(Ops[0], Ops[0], Mask, "subvecbcst");
7410}
7411
Igor Bregeraadb8762016-06-08 13:59:20 +00007412static Value *EmitX86Select(CodeGenFunction &CGF,
Craig Topperc1442972016-06-09 05:15:00 +00007413 Value *Mask, Value *Op0, Value *Op1) {
Igor Bregeraadb8762016-06-08 13:59:20 +00007414
7415 // If the mask is all ones just return first argument.
Craig Topperc1442972016-06-09 05:15:00 +00007416 if (const auto *C = dyn_cast<Constant>(Mask))
Igor Bregeraadb8762016-06-08 13:59:20 +00007417 if (C->isAllOnesValue())
Craig Topperc1442972016-06-09 05:15:00 +00007418 return Op0;
Igor Bregeraadb8762016-06-08 13:59:20 +00007419
Craig Topperc1442972016-06-09 05:15:00 +00007420 Mask = getMaskVecValue(CGF, Mask, Op0->getType()->getVectorNumElements());
Igor Bregeraadb8762016-06-08 13:59:20 +00007421
Craig Topperc1442972016-06-09 05:15:00 +00007422 return CGF.Builder.CreateSelect(Mask, Op0, Op1);
Craig Topper4b060e32016-05-31 06:58:07 +00007423}
7424
Craig Topperd1691c72016-06-22 04:47:58 +00007425static Value *EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC,
7426 bool Signed, SmallVectorImpl<Value *> &Ops) {
Craig Toppera54c21e2016-06-15 14:06:34 +00007427 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topperd1691c72016-06-22 04:47:58 +00007428 Value *Cmp;
Craig Toppera54c21e2016-06-15 14:06:34 +00007429
Craig Topperd1691c72016-06-22 04:47:58 +00007430 if (CC == 3) {
7431 Cmp = Constant::getNullValue(
7432 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7433 } else if (CC == 7) {
7434 Cmp = Constant::getAllOnesValue(
7435 llvm::VectorType::get(CGF.Builder.getInt1Ty(), NumElts));
7436 } else {
7437 ICmpInst::Predicate Pred;
7438 switch (CC) {
7439 default: llvm_unreachable("Unknown condition code");
7440 case 0: Pred = ICmpInst::ICMP_EQ; break;
7441 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
7442 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
7443 case 4: Pred = ICmpInst::ICMP_NE; break;
7444 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
7445 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
7446 }
7447 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7448 }
7449
7450 const auto *C = dyn_cast<Constant>(Ops.back());
Craig Toppera54c21e2016-06-15 14:06:34 +00007451 if (!C || !C->isAllOnesValue())
Craig Topperd1691c72016-06-22 04:47:58 +00007452 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, Ops.back(), NumElts));
Craig Toppera54c21e2016-06-15 14:06:34 +00007453
7454 if (NumElts < 8) {
7455 uint32_t Indices[8];
7456 for (unsigned i = 0; i != NumElts; ++i)
7457 Indices[i] = i;
7458 for (unsigned i = NumElts; i != 8; ++i)
Craig Topperac1823f2016-07-04 07:09:46 +00007459 Indices[i] = i % NumElts + NumElts;
Igor Breger2c880cf2016-06-29 08:14:17 +00007460 Cmp = CGF.Builder.CreateShuffleVector(
7461 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices);
Craig Toppera54c21e2016-06-15 14:06:34 +00007462 }
7463 return CGF.Builder.CreateBitCast(Cmp,
7464 IntegerType::get(CGF.getLLVMContext(),
7465 std::max(NumElts, 8U)));
7466}
7467
Uriel Korach3fba3c32017-09-13 09:02:02 +00007468static Value *EmitX86Abs(CodeGenFunction &CGF, ArrayRef<Value *> Ops) {
7469
7470 llvm::Type *Ty = Ops[0]->getType();
7471 Value *Zero = llvm::Constant::getNullValue(Ty);
7472 Value *Sub = CGF.Builder.CreateSub(Zero, Ops[0]);
7473 Value *Cmp = CGF.Builder.CreateICmp(ICmpInst::ICMP_SGT, Ops[0], Zero);
7474 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Sub);
7475 if (Ops.size() == 1)
7476 return Res;
7477 return EmitX86Select(CGF, Ops[2], Res, Ops[1]);
7478}
7479
Craig Topper531ce282016-10-24 04:04:24 +00007480static Value *EmitX86MinMax(CodeGenFunction &CGF, ICmpInst::Predicate Pred,
7481 ArrayRef<Value *> Ops) {
7482 Value *Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
7483 Value *Res = CGF.Builder.CreateSelect(Cmp, Ops[0], Ops[1]);
7484
7485 if (Ops.size() == 2)
7486 return Res;
7487
7488 assert(Ops.size() == 4);
7489 return EmitX86Select(CGF, Ops[3], Res, Ops[2]);
7490}
7491
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007492static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op,
7493 llvm::Type *DstTy) {
7494 unsigned NumberOfElements = DstTy->getVectorNumElements();
7495 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements);
7496 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2");
7497}
7498
Erich Keane9937b132017-09-01 19:42:45 +00007499Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007500 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
7501 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
Erich Keane9937b132017-09-01 19:42:45 +00007502 return EmitX86CpuIs(CPUStr);
7503}
7504
7505Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
Craig Topper699ae0c2017-08-10 20:28:30 +00007506
7507 // This enum contains the vendor, type, and subtype enums from the
7508 // runtime library concatenated together. The _START labels mark
7509 // the start and are used to adjust the value into the correct
7510 // encoding space.
7511 enum X86CPUs {
7512 INTEL = 1,
7513 AMD,
7514 CPU_TYPE_START,
7515 INTEL_BONNELL,
7516 INTEL_CORE2,
7517 INTEL_COREI7,
7518 AMDFAM10H,
7519 AMDFAM15H,
7520 INTEL_SILVERMONT,
7521 INTEL_KNL,
7522 AMD_BTVER1,
7523 AMD_BTVER2,
Craig Topper8c8e83a2017-10-11 21:42:02 +00007524 AMDFAM17H,
Craig Topper699ae0c2017-08-10 20:28:30 +00007525 CPU_SUBTYPE_START,
7526 INTEL_COREI7_NEHALEM,
7527 INTEL_COREI7_WESTMERE,
7528 INTEL_COREI7_SANDYBRIDGE,
7529 AMDFAM10H_BARCELONA,
7530 AMDFAM10H_SHANGHAI,
7531 AMDFAM10H_ISTANBUL,
7532 AMDFAM15H_BDVER1,
7533 AMDFAM15H_BDVER2,
7534 AMDFAM15H_BDVER3,
7535 AMDFAM15H_BDVER4,
7536 AMDFAM17H_ZNVER1,
7537 INTEL_COREI7_IVYBRIDGE,
7538 INTEL_COREI7_HASWELL,
7539 INTEL_COREI7_BROADWELL,
7540 INTEL_COREI7_SKYLAKE,
7541 INTEL_COREI7_SKYLAKE_AVX512,
7542 };
7543
7544 X86CPUs CPU =
7545 StringSwitch<X86CPUs>(CPUStr)
7546 .Case("amd", AMD)
7547 .Case("amdfam10h", AMDFAM10H)
Erich Keane9937b132017-09-01 19:42:45 +00007548 .Case("amdfam10", AMDFAM10H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007549 .Case("amdfam15h", AMDFAM15H)
Erich Keane9937b132017-09-01 19:42:45 +00007550 .Case("amdfam15", AMDFAM15H)
Craig Topper8c8e83a2017-10-11 21:42:02 +00007551 .Case("amdfam17h", AMDFAM17H)
Craig Topper699ae0c2017-08-10 20:28:30 +00007552 .Case("atom", INTEL_BONNELL)
7553 .Case("barcelona", AMDFAM10H_BARCELONA)
7554 .Case("bdver1", AMDFAM15H_BDVER1)
7555 .Case("bdver2", AMDFAM15H_BDVER2)
7556 .Case("bdver3", AMDFAM15H_BDVER3)
7557 .Case("bdver4", AMDFAM15H_BDVER4)
7558 .Case("bonnell", INTEL_BONNELL)
7559 .Case("broadwell", INTEL_COREI7_BROADWELL)
7560 .Case("btver1", AMD_BTVER1)
7561 .Case("btver2", AMD_BTVER2)
7562 .Case("core2", INTEL_CORE2)
7563 .Case("corei7", INTEL_COREI7)
7564 .Case("haswell", INTEL_COREI7_HASWELL)
7565 .Case("intel", INTEL)
7566 .Case("istanbul", AMDFAM10H_ISTANBUL)
7567 .Case("ivybridge", INTEL_COREI7_IVYBRIDGE)
7568 .Case("knl", INTEL_KNL)
7569 .Case("nehalem", INTEL_COREI7_NEHALEM)
7570 .Case("sandybridge", INTEL_COREI7_SANDYBRIDGE)
7571 .Case("shanghai", AMDFAM10H_SHANGHAI)
7572 .Case("silvermont", INTEL_SILVERMONT)
7573 .Case("skylake", INTEL_COREI7_SKYLAKE)
7574 .Case("skylake-avx512", INTEL_COREI7_SKYLAKE_AVX512)
7575 .Case("slm", INTEL_SILVERMONT)
7576 .Case("westmere", INTEL_COREI7_WESTMERE)
7577 .Case("znver1", AMDFAM17H_ZNVER1);
7578
Erich Keane9937b132017-09-01 19:42:45 +00007579 llvm::Type *Int32Ty = Builder.getInt32Ty();
Craig Topper699ae0c2017-08-10 20:28:30 +00007580
7581 // Matching the struct layout from the compiler-rt/libgcc structure that is
7582 // filled in:
7583 // unsigned int __cpu_vendor;
7584 // unsigned int __cpu_type;
7585 // unsigned int __cpu_subtype;
7586 // unsigned int __cpu_features[1];
7587 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7588 llvm::ArrayType::get(Int32Ty, 1));
7589
7590 // Grab the global __cpu_model.
Erich Keane9937b132017-09-01 19:42:45 +00007591 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
Craig Topper699ae0c2017-08-10 20:28:30 +00007592
7593 // Calculate the index needed to access the correct field based on the
7594 // range. Also adjust the expected value.
7595 unsigned Index;
7596 unsigned Value;
7597 if (CPU > CPU_SUBTYPE_START) {
7598 Index = 2;
7599 Value = CPU - CPU_SUBTYPE_START;
7600 } else if (CPU > CPU_TYPE_START) {
7601 Index = 1;
7602 Value = CPU - CPU_TYPE_START;
7603 } else {
7604 Index = 0;
7605 Value = CPU;
7606 }
7607
7608 // Grab the appropriate field from __cpu_model.
7609 llvm::Value *Idxs[] = {
7610 ConstantInt::get(Int32Ty, 0),
7611 ConstantInt::get(Int32Ty, Index)
7612 };
Erich Keane9937b132017-09-01 19:42:45 +00007613 llvm::Value *CpuValue = Builder.CreateGEP(STy, CpuModel, Idxs);
7614 CpuValue = Builder.CreateAlignedLoad(CpuValue, CharUnits::fromQuantity(4));
Craig Topper699ae0c2017-08-10 20:28:30 +00007615
7616 // Check the value of the field against the requested value.
Erich Keane9937b132017-09-01 19:42:45 +00007617 return Builder.CreateICmpEQ(CpuValue,
Craig Topper699ae0c2017-08-10 20:28:30 +00007618 llvm::ConstantInt::get(Int32Ty, Value));
7619}
7620
Erich Keane9937b132017-09-01 19:42:45 +00007621Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) {
7622 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts();
7623 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString();
7624 return EmitX86CpuSupports(FeatureStr);
7625}
7626
7627Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) {
7628 // TODO: When/if this becomes more than x86 specific then use a TargetInfo
7629 // based mapping.
7630 // Processor features and mapping to processor feature value.
7631 enum X86Features {
7632 CMOV = 0,
7633 MMX,
7634 POPCNT,
7635 SSE,
7636 SSE2,
7637 SSE3,
7638 SSSE3,
7639 SSE4_1,
7640 SSE4_2,
7641 AVX,
7642 AVX2,
7643 SSE4_A,
7644 FMA4,
7645 XOP,
7646 FMA,
7647 AVX512F,
7648 BMI,
7649 BMI2,
7650 AES,
7651 PCLMUL,
7652 AVX512VL,
7653 AVX512BW,
7654 AVX512DQ,
7655 AVX512CD,
7656 AVX512ER,
7657 AVX512PF,
7658 AVX512VBMI,
7659 AVX512IFMA,
7660 AVX5124VNNIW,
7661 AVX5124FMAPS,
7662 AVX512VPOPCNTDQ,
7663 MAX
7664 };
7665
7666 uint32_t FeaturesMask = 0;
7667
7668 for (const StringRef &FeatureStr : FeatureStrs) {
7669 X86Features Feature =
7670 StringSwitch<X86Features>(FeatureStr)
7671 .Case("cmov", X86Features::CMOV)
7672 .Case("mmx", X86Features::MMX)
7673 .Case("popcnt", X86Features::POPCNT)
7674 .Case("sse", X86Features::SSE)
7675 .Case("sse2", X86Features::SSE2)
7676 .Case("sse3", X86Features::SSE3)
7677 .Case("ssse3", X86Features::SSSE3)
7678 .Case("sse4.1", X86Features::SSE4_1)
7679 .Case("sse4.2", X86Features::SSE4_2)
7680 .Case("avx", X86Features::AVX)
7681 .Case("avx2", X86Features::AVX2)
7682 .Case("sse4a", X86Features::SSE4_A)
7683 .Case("fma4", X86Features::FMA4)
7684 .Case("xop", X86Features::XOP)
7685 .Case("fma", X86Features::FMA)
7686 .Case("avx512f", X86Features::AVX512F)
7687 .Case("bmi", X86Features::BMI)
7688 .Case("bmi2", X86Features::BMI2)
7689 .Case("aes", X86Features::AES)
7690 .Case("pclmul", X86Features::PCLMUL)
7691 .Case("avx512vl", X86Features::AVX512VL)
7692 .Case("avx512bw", X86Features::AVX512BW)
7693 .Case("avx512dq", X86Features::AVX512DQ)
7694 .Case("avx512cd", X86Features::AVX512CD)
7695 .Case("avx512er", X86Features::AVX512ER)
7696 .Case("avx512pf", X86Features::AVX512PF)
7697 .Case("avx512vbmi", X86Features::AVX512VBMI)
7698 .Case("avx512ifma", X86Features::AVX512IFMA)
7699 .Case("avx5124vnniw", X86Features::AVX5124VNNIW)
7700 .Case("avx5124fmaps", X86Features::AVX5124FMAPS)
7701 .Case("avx512vpopcntdq", X86Features::AVX512VPOPCNTDQ)
7702 .Default(X86Features::MAX);
7703 assert(Feature != X86Features::MAX && "Invalid feature!");
7704 FeaturesMask |= (1U << Feature);
7705 }
7706
7707 // Matching the struct layout from the compiler-rt/libgcc structure that is
7708 // filled in:
7709 // unsigned int __cpu_vendor;
7710 // unsigned int __cpu_type;
7711 // unsigned int __cpu_subtype;
7712 // unsigned int __cpu_features[1];
7713 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
7714 llvm::ArrayType::get(Int32Ty, 1));
7715
7716 // Grab the global __cpu_model.
7717 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
7718
7719 // Grab the first (0th) element from the field __cpu_features off of the
7720 // global in the struct STy.
7721 Value *Idxs[] = {ConstantInt::get(Int32Ty, 0), ConstantInt::get(Int32Ty, 3),
7722 ConstantInt::get(Int32Ty, 0)};
7723 Value *CpuFeatures = Builder.CreateGEP(STy, CpuModel, Idxs);
7724 Value *Features =
7725 Builder.CreateAlignedLoad(CpuFeatures, CharUnits::fromQuantity(4));
7726
7727 // Check the value of the bit corresponding to the feature requested.
7728 Value *Bitset = Builder.CreateAnd(
7729 Features, llvm::ConstantInt::get(Int32Ty, FeaturesMask));
7730 return Builder.CreateICmpNE(Bitset, llvm::ConstantInt::get(Int32Ty, 0));
7731}
7732
Erich Keane1fe643a2017-10-06 16:40:45 +00007733Value *CodeGenFunction::EmitX86CpuInit() {
7734 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
7735 /*Variadic*/ false);
7736 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init");
7737 return Builder.CreateCall(Func);
7738}
7739
Mike Stump11289f42009-09-09 15:08:12 +00007740Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00007741 const CallExpr *E) {
Erich Keane9937b132017-09-01 19:42:45 +00007742 if (BuiltinID == X86::BI__builtin_cpu_is)
7743 return EmitX86CpuIs(E);
7744 if (BuiltinID == X86::BI__builtin_cpu_supports)
7745 return EmitX86CpuSupports(E);
Erich Keane1fe643a2017-10-06 16:40:45 +00007746 if (BuiltinID == X86::BI__builtin_cpu_init)
7747 return EmitX86CpuInit();
Erich Keane9937b132017-09-01 19:42:45 +00007748
Chris Lattner0e62c1c2011-07-23 10:55:15 +00007749 SmallVector<Value*, 4> Ops;
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007750
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007751 // Find out if any arguments are required to be integer constant expressions.
7752 unsigned ICEArguments = 0;
7753 ASTContext::GetBuiltinTypeError Error;
7754 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
7755 assert(Error == ASTContext::GE_None && "Should not codegen an error");
7756
7757 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
7758 // If this is a normal argument, just emit it as a scalar.
7759 if ((ICEArguments & (1 << i)) == 0) {
7760 Ops.push_back(EmitScalarExpr(E->getArg(i)));
7761 continue;
7762 }
7763
7764 // If this is required to be a constant, constant fold it so that we know
7765 // that the generated intrinsic gets a ConstantInt.
7766 llvm::APSInt Result;
7767 bool IsConst = E->getArg(i)->isIntegerConstantExpr(Result, getContext());
7768 assert(IsConst && "Constant arg isn't actually constant?"); (void)IsConst;
John McCallad7c5c12011-02-08 08:22:06 +00007769 Ops.push_back(llvm::ConstantInt::get(getLLVMContext(), Result));
Chris Lattner64d7f2a2010-10-02 00:09:12 +00007770 }
Anders Carlsson4d3094a2007-12-14 17:48:24 +00007771
Sanjay Patel280cfd12016-06-15 21:20:04 +00007772 // These exist so that the builtin that takes an immediate can be bounds
7773 // checked by clang to avoid passing bad immediates to the backend. Since
7774 // AVX has a larger immediate than SSE we would need separate builtins to
7775 // do the different bounds checking. Rather than create a clang specific
7776 // SSE only builtin, this implements eight separate builtins to match gcc
7777 // implementation.
7778 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) {
7779 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm));
7780 llvm::Function *F = CGM.getIntrinsic(ID);
7781 return Builder.CreateCall(F, Ops);
7782 };
7783
7784 // For the vector forms of FP comparisons, translate the builtins directly to
7785 // IR.
7786 // TODO: The builtins could be removed if the SSE header files used vector
7787 // extension comparisons directly (vector ordered/unordered may need
7788 // additional support via __builtin_isnan()).
Craig Topper01600632016-07-08 01:57:24 +00007789 auto getVectorFCmpIR = [this, &Ops](CmpInst::Predicate Pred) {
Sanjay Patel280cfd12016-06-15 21:20:04 +00007790 Value *Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]);
Craig Topper01600632016-07-08 01:57:24 +00007791 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType());
Sanjay Patel280cfd12016-06-15 21:20:04 +00007792 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy);
7793 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy);
7794 return Builder.CreateBitCast(Sext, FPVecTy);
7795 };
7796
Anders Carlsson895af082007-12-09 23:17:02 +00007797 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00007798 default: return nullptr;
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007799 case X86::BI_mm_prefetch: {
John McCall7f416cc2015-09-08 08:05:57 +00007800 Value *Address = Ops[0];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007801 Value *RW = ConstantInt::get(Int32Ty, 0);
John McCall7f416cc2015-09-08 08:05:57 +00007802 Value *Locality = Ops[1];
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007803 Value *Data = ConstantInt::get(Int32Ty, 1);
7804 Value *F = CGM.getIntrinsic(Intrinsic::prefetch);
David Blaikie43f9bb72015-05-18 22:14:03 +00007805 return Builder.CreateCall(F, {Address, RW, Locality, Data});
Warren Hunt20e4a5d2014-02-21 23:08:53 +00007806 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007807 case X86::BI_mm_clflush: {
7808 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush),
7809 Ops[0]);
7810 }
7811 case X86::BI_mm_lfence: {
7812 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence));
7813 }
7814 case X86::BI_mm_mfence: {
7815 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence));
7816 }
7817 case X86::BI_mm_sfence: {
7818 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence));
7819 }
7820 case X86::BI_mm_pause: {
7821 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause));
7822 }
7823 case X86::BI__rdtsc: {
7824 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc));
7825 }
Simon Pilgrim5aba9922015-08-26 21:17:12 +00007826 case X86::BI__builtin_ia32_undef128:
7827 case X86::BI__builtin_ia32_undef256:
7828 case X86::BI__builtin_ia32_undef512:
Sanjay Patele795daa2017-03-12 19:15:10 +00007829 // The x86 definition of "undef" is not the same as the LLVM definition
7830 // (PR32176). We leave optimizing away an unnecessary zero constant to the
7831 // IR optimizer and backend.
7832 // TODO: If we had a "freeze" IR instruction to generate a fixed undef
7833 // value, we should use that here instead of a zero.
7834 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Bill Wendling65b2a962010-10-09 08:47:25 +00007835 case X86::BI__builtin_ia32_vec_init_v8qi:
7836 case X86::BI__builtin_ia32_vec_init_v4hi:
7837 case X86::BI__builtin_ia32_vec_init_v2si:
7838 return Builder.CreateBitCast(BuildVector(Ops),
John McCallad7c5c12011-02-08 08:22:06 +00007839 llvm::Type::getX86_MMXTy(getLLVMContext()));
Argyrios Kyrtzidis073c9cb2010-10-10 03:19:11 +00007840 case X86::BI__builtin_ia32_vec_ext_v2si:
7841 return Builder.CreateExtractElement(Ops[0],
7842 llvm::ConstantInt::get(Ops[1]->getType(), 0));
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007843 case X86::BI_mm_setcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007844 case X86::BI__builtin_ia32_ldmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007845 Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Nate Begeman91f40e32008-04-14 04:49:57 +00007846 Builder.CreateStore(Ops[0], Tmp);
7847 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007848 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007849 }
Albert Gutowski727ab8a2016-09-14 21:19:43 +00007850 case X86::BI_mm_getcsr:
Nate Begeman91f40e32008-04-14 04:49:57 +00007851 case X86::BI__builtin_ia32_stmxcsr: {
John McCall7f416cc2015-09-08 08:05:57 +00007852 Address Tmp = CreateMemTemp(E->getType());
Ted Kremenekc14efa72011-08-17 21:04:19 +00007853 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
John McCall7f416cc2015-09-08 08:05:57 +00007854 Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
Nate Begeman91f40e32008-04-14 04:49:57 +00007855 return Builder.CreateLoad(Tmp, "stmxcsr");
7856 }
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007857 case X86::BI__builtin_ia32_xsave:
7858 case X86::BI__builtin_ia32_xsave64:
7859 case X86::BI__builtin_ia32_xrstor:
7860 case X86::BI__builtin_ia32_xrstor64:
7861 case X86::BI__builtin_ia32_xsaveopt:
7862 case X86::BI__builtin_ia32_xsaveopt64:
7863 case X86::BI__builtin_ia32_xrstors:
7864 case X86::BI__builtin_ia32_xrstors64:
7865 case X86::BI__builtin_ia32_xsavec:
7866 case X86::BI__builtin_ia32_xsavec64:
7867 case X86::BI__builtin_ia32_xsaves:
Reid Kleckner66e77172016-08-16 16:04:14 +00007868 case X86::BI__builtin_ia32_xsaves64: {
Amjad Aboud2b9b8a52015-10-13 12:29:35 +00007869 Intrinsic::ID ID;
7870#define INTRINSIC_X86_XSAVE_ID(NAME) \
7871 case X86::BI__builtin_ia32_##NAME: \
7872 ID = Intrinsic::x86_##NAME; \
7873 break
7874 switch (BuiltinID) {
7875 default: llvm_unreachable("Unsupported intrinsic!");
7876 INTRINSIC_X86_XSAVE_ID(xsave);
7877 INTRINSIC_X86_XSAVE_ID(xsave64);
7878 INTRINSIC_X86_XSAVE_ID(xrstor);
7879 INTRINSIC_X86_XSAVE_ID(xrstor64);
7880 INTRINSIC_X86_XSAVE_ID(xsaveopt);
7881 INTRINSIC_X86_XSAVE_ID(xsaveopt64);
7882 INTRINSIC_X86_XSAVE_ID(xrstors);
7883 INTRINSIC_X86_XSAVE_ID(xrstors64);
7884 INTRINSIC_X86_XSAVE_ID(xsavec);
7885 INTRINSIC_X86_XSAVE_ID(xsavec64);
7886 INTRINSIC_X86_XSAVE_ID(xsaves);
7887 INTRINSIC_X86_XSAVE_ID(xsaves64);
7888 }
7889#undef INTRINSIC_X86_XSAVE_ID
7890 Value *Mhi = Builder.CreateTrunc(
7891 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty);
7892 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty);
7893 Ops[1] = Mhi;
7894 Ops.push_back(Mlo);
7895 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
7896 }
Craig Topper6e891fb2016-05-31 01:50:10 +00007897 case X86::BI__builtin_ia32_storedqudi128_mask:
7898 case X86::BI__builtin_ia32_storedqusi128_mask:
7899 case X86::BI__builtin_ia32_storedquhi128_mask:
7900 case X86::BI__builtin_ia32_storedquqi128_mask:
7901 case X86::BI__builtin_ia32_storeupd128_mask:
7902 case X86::BI__builtin_ia32_storeups128_mask:
7903 case X86::BI__builtin_ia32_storedqudi256_mask:
7904 case X86::BI__builtin_ia32_storedqusi256_mask:
7905 case X86::BI__builtin_ia32_storedquhi256_mask:
7906 case X86::BI__builtin_ia32_storedquqi256_mask:
7907 case X86::BI__builtin_ia32_storeupd256_mask:
7908 case X86::BI__builtin_ia32_storeups256_mask:
7909 case X86::BI__builtin_ia32_storedqudi512_mask:
7910 case X86::BI__builtin_ia32_storedqusi512_mask:
7911 case X86::BI__builtin_ia32_storedquhi512_mask:
7912 case X86::BI__builtin_ia32_storedquqi512_mask:
7913 case X86::BI__builtin_ia32_storeupd512_mask:
7914 case X86::BI__builtin_ia32_storeups512_mask:
7915 return EmitX86MaskedStore(*this, Ops, 1);
7916
Ayman Musae60a41c2016-11-08 12:00:30 +00007917 case X86::BI__builtin_ia32_storess128_mask:
7918 case X86::BI__builtin_ia32_storesd128_mask: {
7919 return EmitX86MaskedStore(*this, Ops, 16);
7920 }
Oren Ben Simhon140c1fb2017-05-25 13:44:11 +00007921 case X86::BI__builtin_ia32_vpopcntd_512:
7922 case X86::BI__builtin_ia32_vpopcntq_512: {
7923 llvm::Type *ResultType = ConvertType(E->getType());
7924 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
7925 return Builder.CreateCall(F, Ops);
7926 }
Michael Zuckerman755a13d2017-04-04 13:29:53 +00007927 case X86::BI__builtin_ia32_cvtmask2b128:
7928 case X86::BI__builtin_ia32_cvtmask2b256:
7929 case X86::BI__builtin_ia32_cvtmask2b512:
7930 case X86::BI__builtin_ia32_cvtmask2w128:
7931 case X86::BI__builtin_ia32_cvtmask2w256:
7932 case X86::BI__builtin_ia32_cvtmask2w512:
7933 case X86::BI__builtin_ia32_cvtmask2d128:
7934 case X86::BI__builtin_ia32_cvtmask2d256:
7935 case X86::BI__builtin_ia32_cvtmask2d512:
7936 case X86::BI__builtin_ia32_cvtmask2q128:
7937 case X86::BI__builtin_ia32_cvtmask2q256:
7938 case X86::BI__builtin_ia32_cvtmask2q512:
7939 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType()));
7940
Craig Topper6e891fb2016-05-31 01:50:10 +00007941 case X86::BI__builtin_ia32_movdqa32store128_mask:
7942 case X86::BI__builtin_ia32_movdqa64store128_mask:
7943 case X86::BI__builtin_ia32_storeaps128_mask:
7944 case X86::BI__builtin_ia32_storeapd128_mask:
7945 case X86::BI__builtin_ia32_movdqa32store256_mask:
7946 case X86::BI__builtin_ia32_movdqa64store256_mask:
7947 case X86::BI__builtin_ia32_storeaps256_mask:
7948 case X86::BI__builtin_ia32_storeapd256_mask:
7949 case X86::BI__builtin_ia32_movdqa32store512_mask:
7950 case X86::BI__builtin_ia32_movdqa64store512_mask:
7951 case X86::BI__builtin_ia32_storeaps512_mask:
7952 case X86::BI__builtin_ia32_storeapd512_mask: {
7953 unsigned Align =
7954 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7955 return EmitX86MaskedStore(*this, Ops, Align);
7956 }
Craig Topper4b060e32016-05-31 06:58:07 +00007957 case X86::BI__builtin_ia32_loadups128_mask:
7958 case X86::BI__builtin_ia32_loadups256_mask:
7959 case X86::BI__builtin_ia32_loadups512_mask:
7960 case X86::BI__builtin_ia32_loadupd128_mask:
7961 case X86::BI__builtin_ia32_loadupd256_mask:
7962 case X86::BI__builtin_ia32_loadupd512_mask:
7963 case X86::BI__builtin_ia32_loaddquqi128_mask:
7964 case X86::BI__builtin_ia32_loaddquqi256_mask:
7965 case X86::BI__builtin_ia32_loaddquqi512_mask:
7966 case X86::BI__builtin_ia32_loaddquhi128_mask:
7967 case X86::BI__builtin_ia32_loaddquhi256_mask:
7968 case X86::BI__builtin_ia32_loaddquhi512_mask:
7969 case X86::BI__builtin_ia32_loaddqusi128_mask:
7970 case X86::BI__builtin_ia32_loaddqusi256_mask:
7971 case X86::BI__builtin_ia32_loaddqusi512_mask:
7972 case X86::BI__builtin_ia32_loaddqudi128_mask:
7973 case X86::BI__builtin_ia32_loaddqudi256_mask:
7974 case X86::BI__builtin_ia32_loaddqudi512_mask:
7975 return EmitX86MaskedLoad(*this, Ops, 1);
7976
Ayman Musae60a41c2016-11-08 12:00:30 +00007977 case X86::BI__builtin_ia32_loadss128_mask:
7978 case X86::BI__builtin_ia32_loadsd128_mask:
7979 return EmitX86MaskedLoad(*this, Ops, 16);
7980
Craig Topper4b060e32016-05-31 06:58:07 +00007981 case X86::BI__builtin_ia32_loadaps128_mask:
7982 case X86::BI__builtin_ia32_loadaps256_mask:
7983 case X86::BI__builtin_ia32_loadaps512_mask:
7984 case X86::BI__builtin_ia32_loadapd128_mask:
7985 case X86::BI__builtin_ia32_loadapd256_mask:
7986 case X86::BI__builtin_ia32_loadapd512_mask:
7987 case X86::BI__builtin_ia32_movdqa32load128_mask:
7988 case X86::BI__builtin_ia32_movdqa32load256_mask:
7989 case X86::BI__builtin_ia32_movdqa32load512_mask:
7990 case X86::BI__builtin_ia32_movdqa64load128_mask:
7991 case X86::BI__builtin_ia32_movdqa64load256_mask:
7992 case X86::BI__builtin_ia32_movdqa64load512_mask: {
7993 unsigned Align =
7994 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getQuantity();
7995 return EmitX86MaskedLoad(*this, Ops, Align);
7996 }
Simon Pilgrim2d851732016-07-22 13:58:56 +00007997
7998 case X86::BI__builtin_ia32_vbroadcastf128_pd256:
7999 case X86::BI__builtin_ia32_vbroadcastf128_ps256: {
8000 llvm::Type *DstTy = ConvertType(E->getType());
Chandler Carruth4c5e8cc2016-08-10 07:32:47 +00008001 return EmitX86SubVectorBroadcast(*this, Ops, DstTy, 128, 1);
Simon Pilgrim2d851732016-07-22 13:58:56 +00008002 }
8003
Nate Begeman91f40e32008-04-14 04:49:57 +00008004 case X86::BI__builtin_ia32_storehps:
8005 case X86::BI__builtin_ia32_storelps: {
Chris Lattner5e016ae2010-06-27 07:15:29 +00008006 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty);
8007 llvm::Type *VecTy = llvm::VectorType::get(Int64Ty, 2);
Mike Stump11289f42009-09-09 15:08:12 +00008008
Nate Begeman91f40e32008-04-14 04:49:57 +00008009 // cast val v2i64
8010 Ops[1] = Builder.CreateBitCast(Ops[1], VecTy, "cast");
Mike Stump11289f42009-09-09 15:08:12 +00008011
Nate Begeman91f40e32008-04-14 04:49:57 +00008012 // extract (0, 1)
8013 unsigned Index = BuiltinID == X86::BI__builtin_ia32_storelps ? 0 : 1;
Michael J. Spencerdd597752014-05-31 00:22:12 +00008014 llvm::Value *Idx = llvm::ConstantInt::get(SizeTy, Index);
Nate Begeman91f40e32008-04-14 04:49:57 +00008015 Ops[1] = Builder.CreateExtractElement(Ops[1], Idx, "extract");
8016
8017 // cast pointer to i64 & store
8018 Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy);
John McCall7f416cc2015-09-08 08:05:57 +00008019 return Builder.CreateDefaultAlignedStore(Ops[1], Ops[0]);
Nate Begeman91f40e32008-04-14 04:49:57 +00008020 }
Craig Topper480e2b62015-02-17 06:37:58 +00008021 case X86::BI__builtin_ia32_palignr128:
Craig Topperf51cc072016-06-06 06:13:01 +00008022 case X86::BI__builtin_ia32_palignr256:
Craig Topperf51cc072016-06-06 06:13:01 +00008023 case X86::BI__builtin_ia32_palignr512_mask: {
Craig Topper480e2b62015-02-17 06:37:58 +00008024 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
Craig Topper94aba2c2011-12-19 07:03:25 +00008025
Craig Topperf2f1a092016-07-08 02:17:35 +00008026 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
Craig Topper480e2b62015-02-17 06:37:58 +00008027 assert(NumElts % 16 == 0);
Craig Topper480e2b62015-02-17 06:37:58 +00008028
Craig Topper480e2b62015-02-17 06:37:58 +00008029 // If palignr is shifting the pair of vectors more than the size of two
8030 // lanes, emit zero.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008031 if (ShiftVal >= 32)
Craig Topper480e2b62015-02-17 06:37:58 +00008032 return llvm::Constant::getNullValue(ConvertType(E->getType()));
Craig Topper94aba2c2011-12-19 07:03:25 +00008033
Craig Topper480e2b62015-02-17 06:37:58 +00008034 // If palignr is shifting the pair of input vectors more than one lane,
Craig Topper96f9a572015-02-17 07:18:01 +00008035 // but less than two lanes, convert to shifting in zeroes.
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008036 if (ShiftVal > 16) {
8037 ShiftVal -= 16;
Benjamin Kramerb5960562015-07-20 15:31:17 +00008038 Ops[1] = Ops[0];
Craig Topper96f9a572015-02-17 07:18:01 +00008039 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType());
Craig Topper94aba2c2011-12-19 07:03:25 +00008040 }
8041
Craig Topperd1cb4ce2016-06-12 00:41:24 +00008042 uint32_t Indices[64];
Craig Topper96f9a572015-02-17 07:18:01 +00008043 // 256-bit palignr operates on 128-bit lanes so we need to handle that
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008044 for (unsigned l = 0; l != NumElts; l += 16) {
8045 for (unsigned i = 0; i != 16; ++i) {
Craig Topper96f9a572015-02-17 07:18:01 +00008046 unsigned Idx = ShiftVal + i;
Craig Topperb8b4b7e2016-05-29 07:06:02 +00008047 if (Idx >= 16)
8048 Idx += NumElts - 16; // End of lane, switch operand.
Benjamin Kramerc385a802015-07-28 15:40:11 +00008049 Indices[l + i] = Idx + l;
Craig Topper96f9a572015-02-17 07:18:01 +00008050 }
8051 }
8052
Craig Topperf51cc072016-06-06 06:13:01 +00008053 Value *Align = Builder.CreateShuffleVector(Ops[1], Ops[0],
8054 makeArrayRef(Indices, NumElts),
8055 "palignr");
8056
8057 // If this isn't a masked builtin, just return the align operation.
8058 if (Ops.size() == 3)
8059 return Align;
8060
Simon Pilgrim532de1c2016-06-13 10:05:19 +00008061 return EmitX86Select(*this, Ops[4], Align, Ops[3]);
8062 }
8063
Craig Topper8cd7b0c2017-09-15 23:00:59 +00008064 case X86::BI__builtin_ia32_vperm2f128_pd256:
8065 case X86::BI__builtin_ia32_vperm2f128_ps256:
8066 case X86::BI__builtin_ia32_vperm2f128_si256:
8067 case X86::BI__builtin_ia32_permti256: {
8068 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
8069 unsigned NumElts = Ops[0]->getType()->getVectorNumElements();
8070
8071 // This takes a very simple approach since there are two lanes and a
8072 // shuffle can have 2 inputs. So we reserve the first input for the first
8073 // lane and the second input for the second lane. This may result in
8074 // duplicate sources, but this can be dealt with in the backend.
8075
8076 Value *OutOps[2];
8077 uint32_t Indices[8];
8078 for (unsigned l = 0; l != 2; ++l) {
8079 // Determine the source for this lane.
8080 if (Imm & (1 << ((l * 4) + 3)))
8081 OutOps[l] = llvm::ConstantAggregateZero::get(Ops[0]->getType());
8082 else if (Imm & (1 << ((l * 4) + 1)))
8083 OutOps[l] = Ops[1];
8084 else
8085 OutOps[l] = Ops[0];
8086
8087 for (unsigned i = 0; i != NumElts/2; ++i) {
8088 // Start with ith element of the source for this lane.
8089 unsigned Idx = (l * NumElts) + i;
8090 // If bit 0 of the immediate half is set, switch to the high half of
8091 // the source.
8092 if (Imm & (1 << (l * 4)))
8093 Idx += NumElts/2;
8094 Indices[(l * (NumElts/2)) + i] = Idx;
8095 }
8096 }
8097
8098 return Builder.CreateShuffleVector(OutOps[0], OutOps[1],
8099 makeArrayRef(Indices, NumElts),
8100 "vperm");
8101 }
8102
Simon Pilgrim532de1c2016-06-13 10:05:19 +00008103 case X86::BI__builtin_ia32_movnti:
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008104 case X86::BI__builtin_ia32_movnti64:
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008105 case X86::BI__builtin_ia32_movntsd:
8106 case X86::BI__builtin_ia32_movntss: {
8107 llvm::MDNode *Node = llvm::MDNode::get(
8108 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
8109
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008110 Value *Ptr = Ops[0];
8111 Value *Src = Ops[1];
8112
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008113 // Extract the 0'th element of the source vector.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008114 if (BuiltinID == X86::BI__builtin_ia32_movntsd ||
8115 BuiltinID == X86::BI__builtin_ia32_movntss)
8116 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008117
8118 // Convert the type of the pointer to a pointer to the stored type.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008119 Value *BC = Builder.CreateBitCast(
8120 Ptr, llvm::PointerType::getUnqual(Src->getType()), "cast");
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008121
8122 // Unaligned nontemporal store of the scalar value.
Simon Pilgrime47f2cd02016-11-11 14:38:34 +00008123 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, BC);
Simon Pilgrimd39d0262016-06-17 14:28:16 +00008124 SI->setMetadata(CGM.getModule().getMDKindID("nontemporal"), Node);
8125 SI->setAlignment(1);
8126 return SI;
8127 }
8128
Simon Pilgrim532de1c2016-06-13 10:05:19 +00008129 case X86::BI__builtin_ia32_selectb_128:
Igor Bregeraadb8762016-06-08 13:59:20 +00008130 case X86::BI__builtin_ia32_selectb_256:
8131 case X86::BI__builtin_ia32_selectb_512:
8132 case X86::BI__builtin_ia32_selectw_128:
8133 case X86::BI__builtin_ia32_selectw_256:
8134 case X86::BI__builtin_ia32_selectw_512:
8135 case X86::BI__builtin_ia32_selectd_128:
8136 case X86::BI__builtin_ia32_selectd_256:
8137 case X86::BI__builtin_ia32_selectd_512:
8138 case X86::BI__builtin_ia32_selectq_128:
8139 case X86::BI__builtin_ia32_selectq_256:
8140 case X86::BI__builtin_ia32_selectq_512:
8141 case X86::BI__builtin_ia32_selectps_128:
8142 case X86::BI__builtin_ia32_selectps_256:
8143 case X86::BI__builtin_ia32_selectps_512:
8144 case X86::BI__builtin_ia32_selectpd_128:
8145 case X86::BI__builtin_ia32_selectpd_256:
8146 case X86::BI__builtin_ia32_selectpd_512:
Craig Topperc1442972016-06-09 05:15:00 +00008147 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]);
Craig Toppera54c21e2016-06-15 14:06:34 +00008148 case X86::BI__builtin_ia32_pcmpeqb128_mask:
8149 case X86::BI__builtin_ia32_pcmpeqb256_mask:
8150 case X86::BI__builtin_ia32_pcmpeqb512_mask:
8151 case X86::BI__builtin_ia32_pcmpeqw128_mask:
8152 case X86::BI__builtin_ia32_pcmpeqw256_mask:
8153 case X86::BI__builtin_ia32_pcmpeqw512_mask:
8154 case X86::BI__builtin_ia32_pcmpeqd128_mask:
8155 case X86::BI__builtin_ia32_pcmpeqd256_mask:
8156 case X86::BI__builtin_ia32_pcmpeqd512_mask:
8157 case X86::BI__builtin_ia32_pcmpeqq128_mask:
8158 case X86::BI__builtin_ia32_pcmpeqq256_mask:
8159 case X86::BI__builtin_ia32_pcmpeqq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00008160 return EmitX86MaskedCompare(*this, 0, false, Ops);
Craig Toppera54c21e2016-06-15 14:06:34 +00008161 case X86::BI__builtin_ia32_pcmpgtb128_mask:
8162 case X86::BI__builtin_ia32_pcmpgtb256_mask:
8163 case X86::BI__builtin_ia32_pcmpgtb512_mask:
8164 case X86::BI__builtin_ia32_pcmpgtw128_mask:
8165 case X86::BI__builtin_ia32_pcmpgtw256_mask:
8166 case X86::BI__builtin_ia32_pcmpgtw512_mask:
8167 case X86::BI__builtin_ia32_pcmpgtd128_mask:
8168 case X86::BI__builtin_ia32_pcmpgtd256_mask:
8169 case X86::BI__builtin_ia32_pcmpgtd512_mask:
8170 case X86::BI__builtin_ia32_pcmpgtq128_mask:
8171 case X86::BI__builtin_ia32_pcmpgtq256_mask:
8172 case X86::BI__builtin_ia32_pcmpgtq512_mask:
Craig Topperd1691c72016-06-22 04:47:58 +00008173 return EmitX86MaskedCompare(*this, 6, true, Ops);
8174 case X86::BI__builtin_ia32_cmpb128_mask:
8175 case X86::BI__builtin_ia32_cmpb256_mask:
8176 case X86::BI__builtin_ia32_cmpb512_mask:
8177 case X86::BI__builtin_ia32_cmpw128_mask:
8178 case X86::BI__builtin_ia32_cmpw256_mask:
8179 case X86::BI__builtin_ia32_cmpw512_mask:
8180 case X86::BI__builtin_ia32_cmpd128_mask:
8181 case X86::BI__builtin_ia32_cmpd256_mask:
8182 case X86::BI__builtin_ia32_cmpd512_mask:
8183 case X86::BI__builtin_ia32_cmpq128_mask:
8184 case X86::BI__builtin_ia32_cmpq256_mask:
8185 case X86::BI__builtin_ia32_cmpq512_mask: {
8186 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
8187 return EmitX86MaskedCompare(*this, CC, true, Ops);
8188 }
8189 case X86::BI__builtin_ia32_ucmpb128_mask:
8190 case X86::BI__builtin_ia32_ucmpb256_mask:
8191 case X86::BI__builtin_ia32_ucmpb512_mask:
8192 case X86::BI__builtin_ia32_ucmpw128_mask:
8193 case X86::BI__builtin_ia32_ucmpw256_mask:
8194 case X86::BI__builtin_ia32_ucmpw512_mask:
8195 case X86::BI__builtin_ia32_ucmpd128_mask:
8196 case X86::BI__builtin_ia32_ucmpd256_mask:
8197 case X86::BI__builtin_ia32_ucmpd512_mask:
8198 case X86::BI__builtin_ia32_ucmpq128_mask:
8199 case X86::BI__builtin_ia32_ucmpq256_mask:
8200 case X86::BI__builtin_ia32_ucmpq512_mask: {
8201 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
8202 return EmitX86MaskedCompare(*this, CC, false, Ops);
8203 }
Sanjay Patel7495ec02016-06-15 17:18:50 +00008204
Craig Topper46e75552016-07-06 04:24:29 +00008205 case X86::BI__builtin_ia32_vplzcntd_128_mask:
8206 case X86::BI__builtin_ia32_vplzcntd_256_mask:
8207 case X86::BI__builtin_ia32_vplzcntd_512_mask:
8208 case X86::BI__builtin_ia32_vplzcntq_128_mask:
8209 case X86::BI__builtin_ia32_vplzcntq_256_mask:
8210 case X86::BI__builtin_ia32_vplzcntq_512_mask: {
8211 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType());
8212 return EmitX86Select(*this, Ops[2],
8213 Builder.CreateCall(F, {Ops[0],Builder.getInt1(false)}),
8214 Ops[1]);
8215 }
8216
Uriel Korach3fba3c32017-09-13 09:02:02 +00008217 case X86::BI__builtin_ia32_pabsb128:
8218 case X86::BI__builtin_ia32_pabsw128:
8219 case X86::BI__builtin_ia32_pabsd128:
8220 case X86::BI__builtin_ia32_pabsb256:
8221 case X86::BI__builtin_ia32_pabsw256:
8222 case X86::BI__builtin_ia32_pabsd256:
8223 case X86::BI__builtin_ia32_pabsq128_mask:
8224 case X86::BI__builtin_ia32_pabsq256_mask:
8225 case X86::BI__builtin_ia32_pabsb512_mask:
8226 case X86::BI__builtin_ia32_pabsw512_mask:
8227 case X86::BI__builtin_ia32_pabsd512_mask:
8228 case X86::BI__builtin_ia32_pabsq512_mask:
8229 return EmitX86Abs(*this, Ops);
8230
Sanjay Patel7495ec02016-06-15 17:18:50 +00008231 case X86::BI__builtin_ia32_pmaxsb128:
8232 case X86::BI__builtin_ia32_pmaxsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008233 case X86::BI__builtin_ia32_pmaxsd128:
Craig Topper531ce282016-10-24 04:04:24 +00008234 case X86::BI__builtin_ia32_pmaxsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008235 case X86::BI__builtin_ia32_pmaxsb256:
8236 case X86::BI__builtin_ia32_pmaxsw256:
Craig Topper531ce282016-10-24 04:04:24 +00008237 case X86::BI__builtin_ia32_pmaxsd256:
8238 case X86::BI__builtin_ia32_pmaxsq256_mask:
8239 case X86::BI__builtin_ia32_pmaxsb512_mask:
8240 case X86::BI__builtin_ia32_pmaxsw512_mask:
8241 case X86::BI__builtin_ia32_pmaxsd512_mask:
8242 case X86::BI__builtin_ia32_pmaxsq512_mask:
8243 return EmitX86MinMax(*this, ICmpInst::ICMP_SGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008244 case X86::BI__builtin_ia32_pmaxub128:
8245 case X86::BI__builtin_ia32_pmaxuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008246 case X86::BI__builtin_ia32_pmaxud128:
Craig Topper531ce282016-10-24 04:04:24 +00008247 case X86::BI__builtin_ia32_pmaxuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008248 case X86::BI__builtin_ia32_pmaxub256:
8249 case X86::BI__builtin_ia32_pmaxuw256:
Craig Topper531ce282016-10-24 04:04:24 +00008250 case X86::BI__builtin_ia32_pmaxud256:
8251 case X86::BI__builtin_ia32_pmaxuq256_mask:
8252 case X86::BI__builtin_ia32_pmaxub512_mask:
8253 case X86::BI__builtin_ia32_pmaxuw512_mask:
8254 case X86::BI__builtin_ia32_pmaxud512_mask:
8255 case X86::BI__builtin_ia32_pmaxuq512_mask:
8256 return EmitX86MinMax(*this, ICmpInst::ICMP_UGT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008257 case X86::BI__builtin_ia32_pminsb128:
8258 case X86::BI__builtin_ia32_pminsw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008259 case X86::BI__builtin_ia32_pminsd128:
Craig Topper531ce282016-10-24 04:04:24 +00008260 case X86::BI__builtin_ia32_pminsq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008261 case X86::BI__builtin_ia32_pminsb256:
8262 case X86::BI__builtin_ia32_pminsw256:
Craig Topper531ce282016-10-24 04:04:24 +00008263 case X86::BI__builtin_ia32_pminsd256:
8264 case X86::BI__builtin_ia32_pminsq256_mask:
8265 case X86::BI__builtin_ia32_pminsb512_mask:
8266 case X86::BI__builtin_ia32_pminsw512_mask:
8267 case X86::BI__builtin_ia32_pminsd512_mask:
8268 case X86::BI__builtin_ia32_pminsq512_mask:
8269 return EmitX86MinMax(*this, ICmpInst::ICMP_SLT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008270 case X86::BI__builtin_ia32_pminub128:
8271 case X86::BI__builtin_ia32_pminuw128:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008272 case X86::BI__builtin_ia32_pminud128:
Craig Topper531ce282016-10-24 04:04:24 +00008273 case X86::BI__builtin_ia32_pminuq128_mask:
Sanjay Pateldbd68dd2016-06-16 18:45:01 +00008274 case X86::BI__builtin_ia32_pminub256:
8275 case X86::BI__builtin_ia32_pminuw256:
Craig Topper531ce282016-10-24 04:04:24 +00008276 case X86::BI__builtin_ia32_pminud256:
8277 case X86::BI__builtin_ia32_pminuq256_mask:
8278 case X86::BI__builtin_ia32_pminub512_mask:
8279 case X86::BI__builtin_ia32_pminuw512_mask:
8280 case X86::BI__builtin_ia32_pminud512_mask:
8281 case X86::BI__builtin_ia32_pminuq512_mask:
8282 return EmitX86MinMax(*this, ICmpInst::ICMP_ULT, Ops);
Sanjay Patel7495ec02016-06-15 17:18:50 +00008283
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008284 // 3DNow!
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008285 case X86::BI__builtin_ia32_pswapdsf:
8286 case X86::BI__builtin_ia32_pswapdsi: {
Chandler Carrutha2a54102012-02-20 07:35:45 +00008287 llvm::Type *MMXTy = llvm::Type::getX86_MMXTy(getLLVMContext());
8288 Ops[0] = Builder.CreateBitCast(Ops[0], MMXTy, "cast");
Craig Topperd2f814d2015-02-16 21:30:08 +00008289 llvm::Function *F = CGM.getIntrinsic(Intrinsic::x86_3dnowa_pswapd);
8290 return Builder.CreateCall(F, Ops, "pswapd");
Michael J. Spencer6826eb82011-04-15 15:07:13 +00008291 }
Benjamin Kramera43b6992012-07-12 09:33:03 +00008292 case X86::BI__builtin_ia32_rdrand16_step:
8293 case X86::BI__builtin_ia32_rdrand32_step:
Michael Liaoffaae352013-03-29 05:17:55 +00008294 case X86::BI__builtin_ia32_rdrand64_step:
8295 case X86::BI__builtin_ia32_rdseed16_step:
8296 case X86::BI__builtin_ia32_rdseed32_step:
8297 case X86::BI__builtin_ia32_rdseed64_step: {
Benjamin Kramera43b6992012-07-12 09:33:03 +00008298 Intrinsic::ID ID;
8299 switch (BuiltinID) {
8300 default: llvm_unreachable("Unsupported intrinsic!");
8301 case X86::BI__builtin_ia32_rdrand16_step:
8302 ID = Intrinsic::x86_rdrand_16;
8303 break;
8304 case X86::BI__builtin_ia32_rdrand32_step:
8305 ID = Intrinsic::x86_rdrand_32;
8306 break;
8307 case X86::BI__builtin_ia32_rdrand64_step:
8308 ID = Intrinsic::x86_rdrand_64;
8309 break;
Michael Liaoffaae352013-03-29 05:17:55 +00008310 case X86::BI__builtin_ia32_rdseed16_step:
8311 ID = Intrinsic::x86_rdseed_16;
8312 break;
8313 case X86::BI__builtin_ia32_rdseed32_step:
8314 ID = Intrinsic::x86_rdseed_32;
8315 break;
8316 case X86::BI__builtin_ia32_rdseed64_step:
8317 ID = Intrinsic::x86_rdseed_64;
8318 break;
Benjamin Kramera43b6992012-07-12 09:33:03 +00008319 }
8320
David Blaikie4ba525b2015-07-14 17:27:39 +00008321 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID));
John McCall7f416cc2015-09-08 08:05:57 +00008322 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0),
8323 Ops[0]);
Benjamin Kramera43b6992012-07-12 09:33:03 +00008324 return Builder.CreateExtractValue(Call, 1);
8325 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008326
8327 // SSE packed comparison intrinsics
Craig Topper2094d8f2014-12-27 06:59:57 +00008328 case X86::BI__builtin_ia32_cmpeqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008329 case X86::BI__builtin_ia32_cmpeqpd:
Craig Topper01600632016-07-08 01:57:24 +00008330 return getVectorFCmpIR(CmpInst::FCMP_OEQ);
Craig Topper925ef0a2016-07-08 01:48:44 +00008331 case X86::BI__builtin_ia32_cmpltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008332 case X86::BI__builtin_ia32_cmpltpd:
Craig Topper01600632016-07-08 01:57:24 +00008333 return getVectorFCmpIR(CmpInst::FCMP_OLT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008334 case X86::BI__builtin_ia32_cmpleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008335 case X86::BI__builtin_ia32_cmplepd:
Craig Topper01600632016-07-08 01:57:24 +00008336 return getVectorFCmpIR(CmpInst::FCMP_OLE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008337 case X86::BI__builtin_ia32_cmpunordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008338 case X86::BI__builtin_ia32_cmpunordpd:
Craig Topper01600632016-07-08 01:57:24 +00008339 return getVectorFCmpIR(CmpInst::FCMP_UNO);
Craig Topper925ef0a2016-07-08 01:48:44 +00008340 case X86::BI__builtin_ia32_cmpneqps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008341 case X86::BI__builtin_ia32_cmpneqpd:
Craig Topper01600632016-07-08 01:57:24 +00008342 return getVectorFCmpIR(CmpInst::FCMP_UNE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008343 case X86::BI__builtin_ia32_cmpnltps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008344 case X86::BI__builtin_ia32_cmpnltpd:
Craig Topper01600632016-07-08 01:57:24 +00008345 return getVectorFCmpIR(CmpInst::FCMP_UGE);
Craig Topper925ef0a2016-07-08 01:48:44 +00008346 case X86::BI__builtin_ia32_cmpnleps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008347 case X86::BI__builtin_ia32_cmpnlepd:
Craig Topper01600632016-07-08 01:57:24 +00008348 return getVectorFCmpIR(CmpInst::FCMP_UGT);
Craig Topper925ef0a2016-07-08 01:48:44 +00008349 case X86::BI__builtin_ia32_cmpordps:
Craig Topper2094d8f2014-12-27 06:59:57 +00008350 case X86::BI__builtin_ia32_cmpordpd:
Craig Topper01600632016-07-08 01:57:24 +00008351 return getVectorFCmpIR(CmpInst::FCMP_ORD);
Craig Topper425d02d2016-07-06 06:27:31 +00008352 case X86::BI__builtin_ia32_cmpps:
8353 case X86::BI__builtin_ia32_cmpps256:
8354 case X86::BI__builtin_ia32_cmppd:
8355 case X86::BI__builtin_ia32_cmppd256: {
8356 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
8357 // If this one of the SSE immediates, we can use native IR.
8358 if (CC < 8) {
8359 FCmpInst::Predicate Pred;
8360 switch (CC) {
8361 case 0: Pred = FCmpInst::FCMP_OEQ; break;
8362 case 1: Pred = FCmpInst::FCMP_OLT; break;
8363 case 2: Pred = FCmpInst::FCMP_OLE; break;
8364 case 3: Pred = FCmpInst::FCMP_UNO; break;
8365 case 4: Pred = FCmpInst::FCMP_UNE; break;
8366 case 5: Pred = FCmpInst::FCMP_UGE; break;
8367 case 6: Pred = FCmpInst::FCMP_UGT; break;
8368 case 7: Pred = FCmpInst::FCMP_ORD; break;
8369 }
Craig Topper01600632016-07-08 01:57:24 +00008370 return getVectorFCmpIR(Pred);
Craig Topper425d02d2016-07-06 06:27:31 +00008371 }
8372
8373 // We can't handle 8-31 immediates with native IR, use the intrinsic.
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008374 // Except for predicates that create constants.
Craig Topper425d02d2016-07-06 06:27:31 +00008375 Intrinsic::ID ID;
8376 switch (BuiltinID) {
8377 default: llvm_unreachable("Unsupported intrinsic!");
8378 case X86::BI__builtin_ia32_cmpps:
8379 ID = Intrinsic::x86_sse_cmp_ps;
8380 break;
8381 case X86::BI__builtin_ia32_cmpps256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008382 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8383 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8384 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8385 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8386 llvm::Constant::getAllOnesValue(Builder.getInt32Ty()) :
8387 llvm::Constant::getNullValue(Builder.getInt32Ty());
8388 Value *Vec = Builder.CreateVectorSplat(
8389 Ops[0]->getType()->getVectorNumElements(), Constant);
8390 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8391 }
Craig Topper425d02d2016-07-06 06:27:31 +00008392 ID = Intrinsic::x86_avx_cmp_ps_256;
8393 break;
8394 case X86::BI__builtin_ia32_cmppd:
8395 ID = Intrinsic::x86_sse2_cmp_pd;
8396 break;
8397 case X86::BI__builtin_ia32_cmppd256:
Dinar Temirbulatov7b224252017-06-16 12:09:52 +00008398 // _CMP_TRUE_UQ, _CMP_TRUE_US produce -1,-1... vector
8399 // on any input and _CMP_FALSE_OQ, _CMP_FALSE_OS produce 0, 0...
8400 if (CC == 0xf || CC == 0xb || CC == 0x1b || CC == 0x1f) {
8401 Value *Constant = (CC == 0xf || CC == 0x1f) ?
8402 llvm::Constant::getAllOnesValue(Builder.getInt64Ty()) :
8403 llvm::Constant::getNullValue(Builder.getInt64Ty());
8404 Value *Vec = Builder.CreateVectorSplat(
8405 Ops[0]->getType()->getVectorNumElements(), Constant);
8406 return Builder.CreateBitCast(Vec, Ops[0]->getType());
8407 }
Craig Topper425d02d2016-07-06 06:27:31 +00008408 ID = Intrinsic::x86_avx_cmp_pd_256;
8409 break;
8410 }
8411
8412 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
8413 }
Sanjay Patel280cfd12016-06-15 21:20:04 +00008414
8415 // SSE scalar comparison intrinsics
8416 case X86::BI__builtin_ia32_cmpeqss:
8417 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0);
8418 case X86::BI__builtin_ia32_cmpltss:
8419 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1);
8420 case X86::BI__builtin_ia32_cmpless:
8421 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2);
8422 case X86::BI__builtin_ia32_cmpunordss:
8423 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3);
8424 case X86::BI__builtin_ia32_cmpneqss:
8425 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4);
8426 case X86::BI__builtin_ia32_cmpnltss:
8427 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5);
8428 case X86::BI__builtin_ia32_cmpnless:
8429 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6);
8430 case X86::BI__builtin_ia32_cmpordss:
8431 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7);
Craig Topper2094d8f2014-12-27 06:59:57 +00008432 case X86::BI__builtin_ia32_cmpeqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008433 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0);
Craig Topper2094d8f2014-12-27 06:59:57 +00008434 case X86::BI__builtin_ia32_cmpltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008435 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1);
Craig Topper2094d8f2014-12-27 06:59:57 +00008436 case X86::BI__builtin_ia32_cmplesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008437 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2);
Craig Topper2094d8f2014-12-27 06:59:57 +00008438 case X86::BI__builtin_ia32_cmpunordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008439 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3);
Craig Topper2094d8f2014-12-27 06:59:57 +00008440 case X86::BI__builtin_ia32_cmpneqsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008441 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4);
Craig Topper2094d8f2014-12-27 06:59:57 +00008442 case X86::BI__builtin_ia32_cmpnltsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008443 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5);
Craig Topper2094d8f2014-12-27 06:59:57 +00008444 case X86::BI__builtin_ia32_cmpnlesd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008445 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6);
Craig Topper2094d8f2014-12-27 06:59:57 +00008446 case X86::BI__builtin_ia32_cmpordsd:
Sanjay Patel280cfd12016-06-15 21:20:04 +00008447 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008448
Albert Gutowski7216f172016-10-10 18:09:27 +00008449 case X86::BI__emul:
8450 case X86::BI__emulu: {
8451 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64);
8452 bool isSigned = (BuiltinID == X86::BI__emul);
8453 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned);
8454 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned);
8455 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned);
8456 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008457 case X86::BI__mulh:
Albert Gutowski7216f172016-10-10 18:09:27 +00008458 case X86::BI__umulh:
8459 case X86::BI_mul128:
8460 case X86::BI_umul128: {
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008461 llvm::Type *ResType = ConvertType(E->getType());
8462 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
8463
Albert Gutowski7216f172016-10-10 18:09:27 +00008464 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128);
8465 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned);
8466 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008467
8468 Value *MulResult, *HigherBits;
8469 if (IsSigned) {
8470 MulResult = Builder.CreateNSWMul(LHS, RHS);
8471 HigherBits = Builder.CreateAShr(MulResult, 64);
8472 } else {
8473 MulResult = Builder.CreateNUWMul(LHS, RHS);
8474 HigherBits = Builder.CreateLShr(MulResult, 64);
8475 }
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008476 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned);
Albert Gutowski7216f172016-10-10 18:09:27 +00008477
8478 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh)
8479 return HigherBits;
8480
8481 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2));
8482 Builder.CreateStore(HigherBits, HighBitsAddress);
8483 return Builder.CreateIntCast(MulResult, ResType, IsSigned);
Albert Gutowskif3a0bce2016-10-04 22:29:49 +00008484 }
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008485
8486 case X86::BI__faststorefence: {
8487 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008488 llvm::SyncScope::System);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008489 }
8490 case X86::BI_ReadWriteBarrier:
8491 case X86::BI_ReadBarrier:
8492 case X86::BI_WriteBarrier: {
8493 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
Konstantin Zhuravlyovb0beb302017-07-11 22:23:37 +00008494 llvm::SyncScope::SingleThread);
Albert Gutowskifcea61c2016-10-10 19:40:51 +00008495 }
Albert Gutowski2a0621e2016-10-12 22:01:05 +00008496 case X86::BI_BitScanForward:
8497 case X86::BI_BitScanForward64:
8498 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanForward, E);
8499 case X86::BI_BitScanReverse:
8500 case X86::BI_BitScanReverse64:
8501 return EmitMSVCBuiltinExpr(MSVCIntrin::_BitScanReverse, E);
Albert Gutowski5e08df02016-10-13 22:35:07 +00008502
8503 case X86::BI_InterlockedAnd64:
8504 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedAnd, E);
8505 case X86::BI_InterlockedExchange64:
8506 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E);
8507 case X86::BI_InterlockedExchangeAdd64:
8508 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeAdd, E);
8509 case X86::BI_InterlockedExchangeSub64:
8510 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchangeSub, E);
8511 case X86::BI_InterlockedOr64:
8512 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedOr, E);
8513 case X86::BI_InterlockedXor64:
8514 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedXor, E);
8515 case X86::BI_InterlockedDecrement64:
8516 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedDecrement, E);
8517 case X86::BI_InterlockedIncrement64:
8518 return EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedIncrement, E);
8519
Albert Gutowski397d81b2016-10-13 16:03:42 +00008520 case X86::BI_AddressOfReturnAddress: {
8521 Value *F = CGM.getIntrinsic(Intrinsic::addressofreturnaddress);
8522 return Builder.CreateCall(F);
8523 }
Albert Gutowski1deab382016-10-14 17:33:05 +00008524 case X86::BI__stosb: {
8525 // We treat __stosb as a volatile memset - it may not generate "rep stosb"
8526 // instruction, but it will create a memset that won't be optimized away.
8527 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], 1, true);
8528 }
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008529 case X86::BI__ud2:
8530 // llvm.trap makes a ud2a instruction on x86.
8531 return EmitTrapCall(Intrinsic::trap);
8532 case X86::BI__int2c: {
8533 // This syscall signals a driver assertion failure in x86 NT kernels.
8534 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
8535 llvm::InlineAsm *IA =
8536 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*SideEffects=*/true);
Reid Klecknerde864822017-03-21 16:57:30 +00008537 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
8538 getLLVMContext(), llvm::AttributeList::FunctionIndex,
8539 llvm::Attribute::NoReturn);
Reid Klecknerb04cb9a2017-03-06 19:43:16 +00008540 CallSite CS = Builder.CreateCall(IA);
8541 CS.setAttributes(NoReturnAttr);
8542 return CS.getInstruction();
8543 }
Hans Wennborg043f4022017-03-22 19:13:13 +00008544 case X86::BI__readfsbyte:
8545 case X86::BI__readfsword:
8546 case X86::BI__readfsdword:
8547 case X86::BI__readfsqword: {
8548 llvm::Type *IntTy = ConvertType(E->getType());
8549 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8550 llvm::PointerType::get(IntTy, 257));
8551 LoadInst *Load = Builder.CreateAlignedLoad(
8552 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8553 Load->setVolatile(true);
8554 return Load;
8555 }
8556 case X86::BI__readgsbyte:
8557 case X86::BI__readgsword:
8558 case X86::BI__readgsdword:
8559 case X86::BI__readgsqword: {
8560 llvm::Type *IntTy = ConvertType(E->getType());
8561 Value *Ptr = Builder.CreateIntToPtr(EmitScalarExpr(E->getArg(0)),
8562 llvm::PointerType::get(IntTy, 256));
8563 LoadInst *Load = Builder.CreateAlignedLoad(
8564 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
8565 Load->setVolatile(true);
8566 return Load;
8567 }
Anders Carlsson895af082007-12-09 23:17:02 +00008568 }
8569}
8570
Tony Linthicum76329bf2011-12-12 21:14:55 +00008571
Mike Stump11289f42009-09-09 15:08:12 +00008572Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
Chris Lattner13653d72007-12-13 07:34:23 +00008573 const CallExpr *E) {
Chris Lattner0e62c1c2011-07-23 10:55:15 +00008574 SmallVector<Value*, 4> Ops;
Chris Lattnerdad40622010-04-14 03:54:58 +00008575
8576 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
8577 Ops.push_back(EmitScalarExpr(E->getArg(i)));
8578
8579 Intrinsic::ID ID = Intrinsic::not_intrinsic;
8580
8581 switch (BuiltinID) {
Craig Topper8a13c412014-05-21 05:09:00 +00008582 default: return nullptr;
Chris Lattnerdad40622010-04-14 03:54:58 +00008583
Hal Finkel65e1e4d2015-08-31 23:55:19 +00008584 // __builtin_ppc_get_timebase is GCC 4.8+'s PowerPC-specific name for what we
8585 // call __builtin_readcyclecounter.
8586 case PPC::BI__builtin_ppc_get_timebase:
8587 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::readcyclecounter));
8588
Tony Jiang6a49aad2016-11-15 14:30:56 +00008589 // vec_ld, vec_xl_be, vec_lvsl, vec_lvsr
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008590 case PPC::BI__builtin_altivec_lvx:
8591 case PPC::BI__builtin_altivec_lvxl:
8592 case PPC::BI__builtin_altivec_lvebx:
8593 case PPC::BI__builtin_altivec_lvehx:
8594 case PPC::BI__builtin_altivec_lvewx:
8595 case PPC::BI__builtin_altivec_lvsl:
8596 case PPC::BI__builtin_altivec_lvsr:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008597 case PPC::BI__builtin_vsx_lxvd2x:
8598 case PPC::BI__builtin_vsx_lxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008599 case PPC::BI__builtin_vsx_lxvd2x_be:
8600 case PPC::BI__builtin_vsx_lxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008601 case PPC::BI__builtin_vsx_lxvl:
8602 case PPC::BI__builtin_vsx_lxvll:
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008603 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008604 if(BuiltinID == PPC::BI__builtin_vsx_lxvl ||
8605 BuiltinID == PPC::BI__builtin_vsx_lxvll){
8606 Ops[0] = Builder.CreateBitCast(Ops[0], Int8PtrTy);
8607 }else {
8608 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8609 Ops[0] = Builder.CreateGEP(Ops[1], Ops[0]);
8610 Ops.pop_back();
8611 }
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008612
8613 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008614 default: llvm_unreachable("Unsupported ld/lvsl/lvsr intrinsic!");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008615 case PPC::BI__builtin_altivec_lvx:
8616 ID = Intrinsic::ppc_altivec_lvx;
8617 break;
8618 case PPC::BI__builtin_altivec_lvxl:
8619 ID = Intrinsic::ppc_altivec_lvxl;
8620 break;
8621 case PPC::BI__builtin_altivec_lvebx:
8622 ID = Intrinsic::ppc_altivec_lvebx;
8623 break;
8624 case PPC::BI__builtin_altivec_lvehx:
8625 ID = Intrinsic::ppc_altivec_lvehx;
8626 break;
8627 case PPC::BI__builtin_altivec_lvewx:
8628 ID = Intrinsic::ppc_altivec_lvewx;
8629 break;
8630 case PPC::BI__builtin_altivec_lvsl:
8631 ID = Intrinsic::ppc_altivec_lvsl;
8632 break;
8633 case PPC::BI__builtin_altivec_lvsr:
8634 ID = Intrinsic::ppc_altivec_lvsr;
8635 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008636 case PPC::BI__builtin_vsx_lxvd2x:
8637 ID = Intrinsic::ppc_vsx_lxvd2x;
8638 break;
8639 case PPC::BI__builtin_vsx_lxvw4x:
8640 ID = Intrinsic::ppc_vsx_lxvw4x;
8641 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008642 case PPC::BI__builtin_vsx_lxvd2x_be:
8643 ID = Intrinsic::ppc_vsx_lxvd2x_be;
8644 break;
8645 case PPC::BI__builtin_vsx_lxvw4x_be:
8646 ID = Intrinsic::ppc_vsx_lxvw4x_be;
8647 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008648 case PPC::BI__builtin_vsx_lxvl:
8649 ID = Intrinsic::ppc_vsx_lxvl;
8650 break;
8651 case PPC::BI__builtin_vsx_lxvll:
8652 ID = Intrinsic::ppc_vsx_lxvll;
8653 break;
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008654 }
8655 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008656 return Builder.CreateCall(F, Ops, "");
Anton Korobeynikovcc50b7d2010-06-19 09:47:18 +00008657 }
8658
Tony Jiang6a49aad2016-11-15 14:30:56 +00008659 // vec_st, vec_xst_be
Chris Lattnerdad40622010-04-14 03:54:58 +00008660 case PPC::BI__builtin_altivec_stvx:
8661 case PPC::BI__builtin_altivec_stvxl:
8662 case PPC::BI__builtin_altivec_stvebx:
8663 case PPC::BI__builtin_altivec_stvehx:
8664 case PPC::BI__builtin_altivec_stvewx:
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008665 case PPC::BI__builtin_vsx_stxvd2x:
8666 case PPC::BI__builtin_vsx_stxvw4x:
Tony Jiang6a49aad2016-11-15 14:30:56 +00008667 case PPC::BI__builtin_vsx_stxvd2x_be:
8668 case PPC::BI__builtin_vsx_stxvw4x_be:
Zaara Syedac1d29522016-11-15 18:04:13 +00008669 case PPC::BI__builtin_vsx_stxvl:
8670 case PPC::BI__builtin_vsx_stxvll:
Chris Lattnerdad40622010-04-14 03:54:58 +00008671 {
Zaara Syedac1d29522016-11-15 18:04:13 +00008672 if(BuiltinID == PPC::BI__builtin_vsx_stxvl ||
8673 BuiltinID == PPC::BI__builtin_vsx_stxvll ){
8674 Ops[1] = Builder.CreateBitCast(Ops[1], Int8PtrTy);
8675 }else {
8676 Ops[2] = Builder.CreateBitCast(Ops[2], Int8PtrTy);
8677 Ops[1] = Builder.CreateGEP(Ops[2], Ops[1]);
8678 Ops.pop_back();
8679 }
Chris Lattnerdad40622010-04-14 03:54:58 +00008680
8681 switch (BuiltinID) {
David Blaikie83d382b2011-09-23 05:06:16 +00008682 default: llvm_unreachable("Unsupported st intrinsic!");
Chris Lattnerdad40622010-04-14 03:54:58 +00008683 case PPC::BI__builtin_altivec_stvx:
8684 ID = Intrinsic::ppc_altivec_stvx;
8685 break;
8686 case PPC::BI__builtin_altivec_stvxl:
8687 ID = Intrinsic::ppc_altivec_stvxl;
8688 break;
8689 case PPC::BI__builtin_altivec_stvebx:
8690 ID = Intrinsic::ppc_altivec_stvebx;
8691 break;
8692 case PPC::BI__builtin_altivec_stvehx:
8693 ID = Intrinsic::ppc_altivec_stvehx;
8694 break;
8695 case PPC::BI__builtin_altivec_stvewx:
8696 ID = Intrinsic::ppc_altivec_stvewx;
8697 break;
Bill Schmidt9ec8cea2014-11-12 04:19:56 +00008698 case PPC::BI__builtin_vsx_stxvd2x:
8699 ID = Intrinsic::ppc_vsx_stxvd2x;
8700 break;
8701 case PPC::BI__builtin_vsx_stxvw4x:
8702 ID = Intrinsic::ppc_vsx_stxvw4x;
8703 break;
Tony Jiang6a49aad2016-11-15 14:30:56 +00008704 case PPC::BI__builtin_vsx_stxvd2x_be:
8705 ID = Intrinsic::ppc_vsx_stxvd2x_be;
8706 break;
8707 case PPC::BI__builtin_vsx_stxvw4x_be:
8708 ID = Intrinsic::ppc_vsx_stxvw4x_be;
8709 break;
Zaara Syedac1d29522016-11-15 18:04:13 +00008710 case PPC::BI__builtin_vsx_stxvl:
8711 ID = Intrinsic::ppc_vsx_stxvl;
8712 break;
8713 case PPC::BI__builtin_vsx_stxvll:
8714 ID = Intrinsic::ppc_vsx_stxvll;
8715 break;
Chris Lattnerdad40622010-04-14 03:54:58 +00008716 }
8717 llvm::Function *F = CGM.getIntrinsic(ID);
Jay Foad5bd375a2011-07-15 08:37:34 +00008718 return Builder.CreateCall(F, Ops, "");
Chris Lattnerdad40622010-04-14 03:54:58 +00008719 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008720 // Square root
8721 case PPC::BI__builtin_vsx_xvsqrtsp:
8722 case PPC::BI__builtin_vsx_xvsqrtdp: {
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008723 llvm::Type *ResultType = ConvertType(E->getType());
8724 Value *X = EmitScalarExpr(E->getArg(0));
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008725 ID = Intrinsic::sqrt;
Nemanja Ivanovic2f1f9262015-06-26 19:27:20 +00008726 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8727 return Builder.CreateCall(F, X);
Chris Lattnerdad40622010-04-14 03:54:58 +00008728 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008729 // Count leading zeros
8730 case PPC::BI__builtin_altivec_vclzb:
8731 case PPC::BI__builtin_altivec_vclzh:
8732 case PPC::BI__builtin_altivec_vclzw:
8733 case PPC::BI__builtin_altivec_vclzd: {
8734 llvm::Type *ResultType = ConvertType(E->getType());
8735 Value *X = EmitScalarExpr(E->getArg(0));
8736 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8737 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
8738 return Builder.CreateCall(F, {X, Undef});
8739 }
Nemanja Ivanovic10e2b5d2016-09-27 10:45:22 +00008740 case PPC::BI__builtin_altivec_vctzb:
8741 case PPC::BI__builtin_altivec_vctzh:
8742 case PPC::BI__builtin_altivec_vctzw:
8743 case PPC::BI__builtin_altivec_vctzd: {
8744 llvm::Type *ResultType = ConvertType(E->getType());
8745 Value *X = EmitScalarExpr(E->getArg(0));
8746 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
8747 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
8748 return Builder.CreateCall(F, {X, Undef});
8749 }
8750 case PPC::BI__builtin_altivec_vpopcntb:
8751 case PPC::BI__builtin_altivec_vpopcnth:
8752 case PPC::BI__builtin_altivec_vpopcntw:
8753 case PPC::BI__builtin_altivec_vpopcntd: {
8754 llvm::Type *ResultType = ConvertType(E->getType());
8755 Value *X = EmitScalarExpr(E->getArg(0));
8756 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
8757 return Builder.CreateCall(F, X);
8758 }
Nemanja Ivanovic6c363ed2015-07-14 17:50:27 +00008759 // Copy sign
8760 case PPC::BI__builtin_vsx_xvcpsgnsp:
8761 case PPC::BI__builtin_vsx_xvcpsgndp: {
8762 llvm::Type *ResultType = ConvertType(E->getType());
8763 Value *X = EmitScalarExpr(E->getArg(0));
8764 Value *Y = EmitScalarExpr(E->getArg(1));
8765 ID = Intrinsic::copysign;
8766 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8767 return Builder.CreateCall(F, {X, Y});
8768 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008769 // Rounding/truncation
8770 case PPC::BI__builtin_vsx_xvrspip:
8771 case PPC::BI__builtin_vsx_xvrdpip:
8772 case PPC::BI__builtin_vsx_xvrdpim:
8773 case PPC::BI__builtin_vsx_xvrspim:
8774 case PPC::BI__builtin_vsx_xvrdpi:
8775 case PPC::BI__builtin_vsx_xvrspi:
8776 case PPC::BI__builtin_vsx_xvrdpic:
8777 case PPC::BI__builtin_vsx_xvrspic:
8778 case PPC::BI__builtin_vsx_xvrdpiz:
8779 case PPC::BI__builtin_vsx_xvrspiz: {
8780 llvm::Type *ResultType = ConvertType(E->getType());
8781 Value *X = EmitScalarExpr(E->getArg(0));
8782 if (BuiltinID == PPC::BI__builtin_vsx_xvrdpim ||
8783 BuiltinID == PPC::BI__builtin_vsx_xvrspim)
8784 ID = Intrinsic::floor;
8785 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpi ||
8786 BuiltinID == PPC::BI__builtin_vsx_xvrspi)
8787 ID = Intrinsic::round;
8788 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpic ||
8789 BuiltinID == PPC::BI__builtin_vsx_xvrspic)
8790 ID = Intrinsic::nearbyint;
8791 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpip ||
8792 BuiltinID == PPC::BI__builtin_vsx_xvrspip)
8793 ID = Intrinsic::ceil;
8794 else if (BuiltinID == PPC::BI__builtin_vsx_xvrdpiz ||
8795 BuiltinID == PPC::BI__builtin_vsx_xvrspiz)
8796 ID = Intrinsic::trunc;
8797 llvm::Function *F = CGM.getIntrinsic(ID, ResultType);
8798 return Builder.CreateCall(F, X);
8799 }
Kit Bartonfbab1582016-03-09 19:28:31 +00008800
8801 // Absolute value
8802 case PPC::BI__builtin_vsx_xvabsdp:
8803 case PPC::BI__builtin_vsx_xvabssp: {
8804 llvm::Type *ResultType = ConvertType(E->getType());
8805 Value *X = EmitScalarExpr(E->getArg(0));
8806 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
8807 return Builder.CreateCall(F, X);
8808 }
8809
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008810 // FMA variations
8811 case PPC::BI__builtin_vsx_xvmaddadp:
8812 case PPC::BI__builtin_vsx_xvmaddasp:
8813 case PPC::BI__builtin_vsx_xvnmaddadp:
8814 case PPC::BI__builtin_vsx_xvnmaddasp:
8815 case PPC::BI__builtin_vsx_xvmsubadp:
8816 case PPC::BI__builtin_vsx_xvmsubasp:
8817 case PPC::BI__builtin_vsx_xvnmsubadp:
8818 case PPC::BI__builtin_vsx_xvnmsubasp: {
8819 llvm::Type *ResultType = ConvertType(E->getType());
8820 Value *X = EmitScalarExpr(E->getArg(0));
8821 Value *Y = EmitScalarExpr(E->getArg(1));
8822 Value *Z = EmitScalarExpr(E->getArg(2));
8823 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
8824 llvm::Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
8825 switch (BuiltinID) {
8826 case PPC::BI__builtin_vsx_xvmaddadp:
8827 case PPC::BI__builtin_vsx_xvmaddasp:
8828 return Builder.CreateCall(F, {X, Y, Z});
8829 case PPC::BI__builtin_vsx_xvnmaddadp:
8830 case PPC::BI__builtin_vsx_xvnmaddasp:
8831 return Builder.CreateFSub(Zero,
8832 Builder.CreateCall(F, {X, Y, Z}), "sub");
8833 case PPC::BI__builtin_vsx_xvmsubadp:
8834 case PPC::BI__builtin_vsx_xvmsubasp:
8835 return Builder.CreateCall(F,
8836 {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8837 case PPC::BI__builtin_vsx_xvnmsubadp:
8838 case PPC::BI__builtin_vsx_xvnmsubasp:
8839 Value *FsubRes =
8840 Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
8841 return Builder.CreateFSub(Zero, FsubRes, "sub");
8842 }
8843 llvm_unreachable("Unknown FMA operation");
8844 return nullptr; // Suppress no-return warning
8845 }
Sean Fertile96d9e0e2017-01-05 21:43:30 +00008846
8847 case PPC::BI__builtin_vsx_insertword: {
8848 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxinsertw);
8849
8850 // Third argument is a compile time constant int. It must be clamped to
8851 // to the range [0, 12].
8852 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8853 assert(ArgCI &&
8854 "Third arg to xxinsertw intrinsic must be constant integer");
8855 const int64_t MaxIndex = 12;
8856 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8857
8858 // The builtin semantics don't exactly match the xxinsertw instructions
8859 // semantics (which ppc_vsx_xxinsertw follows). The builtin extracts the
8860 // word from the first argument, and inserts it in the second argument. The
8861 // instruction extracts the word from its second input register and inserts
8862 // it into its first input register, so swap the first and second arguments.
8863 std::swap(Ops[0], Ops[1]);
8864
8865 // Need to cast the second argument from a vector of unsigned int to a
8866 // vector of long long.
8867 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8868
8869 if (getTarget().isLittleEndian()) {
8870 // Create a shuffle mask of (1, 0)
8871 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8872 ConstantInt::get(Int32Ty, 0)
8873 };
8874 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8875
8876 // Reverse the double words in the vector we will extract from.
8877 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8878 Ops[0] = Builder.CreateShuffleVector(Ops[0], Ops[0], ShuffleMask);
8879
8880 // Reverse the index.
8881 Index = MaxIndex - Index;
8882 }
8883
8884 // Intrinsic expects the first arg to be a vector of int.
8885 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8886 Ops[2] = ConstantInt::getSigned(Int32Ty, Index);
8887 return Builder.CreateCall(F, Ops);
8888 }
8889
8890 case PPC::BI__builtin_vsx_extractuword: {
8891 llvm::Function *F = CGM.getIntrinsic(Intrinsic::ppc_vsx_xxextractuw);
8892
8893 // Intrinsic expects the first argument to be a vector of doublewords.
8894 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8895
8896 // The second argument is a compile time constant int that needs to
8897 // be clamped to the range [0, 12].
8898 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[1]);
8899 assert(ArgCI &&
8900 "Second Arg to xxextractuw intrinsic must be a constant integer!");
8901 const int64_t MaxIndex = 12;
8902 int64_t Index = clamp(ArgCI->getSExtValue(), 0, MaxIndex);
8903
8904 if (getTarget().isLittleEndian()) {
8905 // Reverse the index.
8906 Index = MaxIndex - Index;
8907 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8908
8909 // Emit the call, then reverse the double words of the results vector.
8910 Value *Call = Builder.CreateCall(F, Ops);
8911
8912 // Create a shuffle mask of (1, 0)
8913 Constant *ShuffleElts[2] = { ConstantInt::get(Int32Ty, 1),
8914 ConstantInt::get(Int32Ty, 0)
8915 };
8916 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8917
8918 Value *ShuffleCall = Builder.CreateShuffleVector(Call, Call, ShuffleMask);
8919 return ShuffleCall;
8920 } else {
8921 Ops[1] = ConstantInt::getSigned(Int32Ty, Index);
8922 return Builder.CreateCall(F, Ops);
8923 }
8924 }
Tony Jiangbbc48e92017-05-24 15:13:32 +00008925
8926 case PPC::BI__builtin_vsx_xxpermdi: {
8927 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8928 assert(ArgCI && "Third arg must be constant integer!");
8929
8930 unsigned Index = ArgCI->getZExtValue();
8931 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int64Ty, 2));
8932 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int64Ty, 2));
8933
8934 // Element zero comes from the first input vector and element one comes from
8935 // the second. The element indices within each vector are numbered in big
8936 // endian order so the shuffle mask must be adjusted for this on little
8937 // endian platforms (i.e. index is complemented and source vector reversed).
8938 unsigned ElemIdx0;
8939 unsigned ElemIdx1;
8940 if (getTarget().isLittleEndian()) {
8941 ElemIdx0 = (~Index & 1) + 2;
8942 ElemIdx1 = (~Index & 2) >> 1;
8943 } else { // BigEndian
8944 ElemIdx0 = (Index & 2) >> 1;
8945 ElemIdx1 = 2 + (Index & 1);
8946 }
8947
8948 Constant *ShuffleElts[2] = {ConstantInt::get(Int32Ty, ElemIdx0),
8949 ConstantInt::get(Int32Ty, ElemIdx1)};
8950 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8951
8952 Value *ShuffleCall =
8953 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8954 QualType BIRetType = E->getType();
8955 auto RetTy = ConvertType(BIRetType);
8956 return Builder.CreateBitCast(ShuffleCall, RetTy);
8957 }
Tony Jiang9aa2c032017-05-24 15:54:13 +00008958
8959 case PPC::BI__builtin_vsx_xxsldwi: {
8960 ConstantInt *ArgCI = dyn_cast<ConstantInt>(Ops[2]);
8961 assert(ArgCI && "Third argument must be a compile time constant");
8962 unsigned Index = ArgCI->getZExtValue() & 0x3;
8963 Ops[0] = Builder.CreateBitCast(Ops[0], llvm::VectorType::get(Int32Ty, 4));
8964 Ops[1] = Builder.CreateBitCast(Ops[1], llvm::VectorType::get(Int32Ty, 4));
8965
8966 // Create a shuffle mask
8967 unsigned ElemIdx0;
8968 unsigned ElemIdx1;
8969 unsigned ElemIdx2;
8970 unsigned ElemIdx3;
8971 if (getTarget().isLittleEndian()) {
8972 // Little endian element N comes from element 8+N-Index of the
8973 // concatenated wide vector (of course, using modulo arithmetic on
8974 // the total number of elements).
8975 ElemIdx0 = (8 - Index) % 8;
8976 ElemIdx1 = (9 - Index) % 8;
8977 ElemIdx2 = (10 - Index) % 8;
8978 ElemIdx3 = (11 - Index) % 8;
8979 } else {
8980 // Big endian ElemIdx<N> = Index + N
8981 ElemIdx0 = Index;
8982 ElemIdx1 = Index + 1;
8983 ElemIdx2 = Index + 2;
8984 ElemIdx3 = Index + 3;
8985 }
8986
8987 Constant *ShuffleElts[4] = {ConstantInt::get(Int32Ty, ElemIdx0),
8988 ConstantInt::get(Int32Ty, ElemIdx1),
8989 ConstantInt::get(Int32Ty, ElemIdx2),
8990 ConstantInt::get(Int32Ty, ElemIdx3)};
8991
8992 Constant *ShuffleMask = llvm::ConstantVector::get(ShuffleElts);
8993 Value *ShuffleCall =
8994 Builder.CreateShuffleVector(Ops[0], Ops[1], ShuffleMask);
8995 QualType BIRetType = E->getType();
8996 auto RetTy = ConvertType(BIRetType);
8997 return Builder.CreateBitCast(ShuffleCall, RetTy);
8998 }
Nemanja Ivanovic1c7ad712015-07-05 06:40:52 +00008999 }
Mike Stump11289f42009-09-09 15:08:12 +00009000}
Matt Arsenault56f008d2014-06-24 20:45:01 +00009001
Matt Arsenault3ea39f92015-06-19 17:54:10 +00009002Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
9003 const CallExpr *E) {
Matt Arsenault56f008d2014-06-24 20:45:01 +00009004 switch (BuiltinID) {
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009005 case AMDGPU::BI__builtin_amdgcn_div_scale:
9006 case AMDGPU::BI__builtin_amdgcn_div_scalef: {
Matt Arsenault56f008d2014-06-24 20:45:01 +00009007 // Translate from the intrinsics's struct return to the builtin's out
9008 // argument.
9009
John McCall7f416cc2015-09-08 08:05:57 +00009010 Address FlagOutPtr = EmitPointerWithAlignment(E->getArg(3));
Matt Arsenault56f008d2014-06-24 20:45:01 +00009011
9012 llvm::Value *X = EmitScalarExpr(E->getArg(0));
9013 llvm::Value *Y = EmitScalarExpr(E->getArg(1));
9014 llvm::Value *Z = EmitScalarExpr(E->getArg(2));
9015
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009016 llvm::Value *Callee = CGM.getIntrinsic(Intrinsic::amdgcn_div_scale,
Matt Arsenault56f008d2014-06-24 20:45:01 +00009017 X->getType());
9018
David Blaikie43f9bb72015-05-18 22:14:03 +00009019 llvm::Value *Tmp = Builder.CreateCall(Callee, {X, Y, Z});
Matt Arsenault56f008d2014-06-24 20:45:01 +00009020
9021 llvm::Value *Result = Builder.CreateExtractValue(Tmp, 0);
9022 llvm::Value *Flag = Builder.CreateExtractValue(Tmp, 1);
9023
9024 llvm::Type *RealFlagType
John McCall7f416cc2015-09-08 08:05:57 +00009025 = FlagOutPtr.getPointer()->getType()->getPointerElementType();
Matt Arsenault56f008d2014-06-24 20:45:01 +00009026
9027 llvm::Value *FlagExt = Builder.CreateZExt(Flag, RealFlagType);
John McCall7f416cc2015-09-08 08:05:57 +00009028 Builder.CreateStore(FlagExt, FlagOutPtr);
Matt Arsenault56f008d2014-06-24 20:45:01 +00009029 return Result;
Matt Arsenault85877112014-07-15 17:23:46 +00009030 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009031 case AMDGPU::BI__builtin_amdgcn_div_fmas:
9032 case AMDGPU::BI__builtin_amdgcn_div_fmasf: {
Matt Arsenault2174a9d2014-10-21 22:21:41 +00009033 llvm::Value *Src0 = EmitScalarExpr(E->getArg(0));
9034 llvm::Value *Src1 = EmitScalarExpr(E->getArg(1));
9035 llvm::Value *Src2 = EmitScalarExpr(E->getArg(2));
9036 llvm::Value *Src3 = EmitScalarExpr(E->getArg(3));
9037
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009038 llvm::Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_div_fmas,
Matt Arsenault2174a9d2014-10-21 22:21:41 +00009039 Src0->getType());
9040 llvm::Value *Src3ToBool = Builder.CreateIsNotNull(Src3);
David Blaikie43f9bb72015-05-18 22:14:03 +00009041 return Builder.CreateCall(F, {Src0, Src1, Src2, Src3ToBool});
Matt Arsenault2174a9d2014-10-21 22:21:41 +00009042 }
Changpeng Fang03bdd8f2016-08-18 22:04:54 +00009043
9044 case AMDGPU::BI__builtin_amdgcn_ds_swizzle:
9045 return emitBinaryBuiltin(*this, E, Intrinsic::amdgcn_ds_swizzle);
Yaxun Liu4d867992017-03-10 01:30:46 +00009046 case AMDGPU::BI__builtin_amdgcn_mov_dpp: {
9047 llvm::SmallVector<llvm::Value *, 5> Args;
9048 for (unsigned I = 0; I != 5; ++I)
9049 Args.push_back(EmitScalarExpr(E->getArg(I)));
9050 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_mov_dpp,
9051 Args[0]->getType());
9052 return Builder.CreateCall(F, Args);
9053 }
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009054 case AMDGPU::BI__builtin_amdgcn_div_fixup:
9055 case AMDGPU::BI__builtin_amdgcn_div_fixupf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009056 case AMDGPU::BI__builtin_amdgcn_div_fixuph:
Matt Arsenaultf652cae2016-07-01 17:38:14 +00009057 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_div_fixup);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009058 case AMDGPU::BI__builtin_amdgcn_trig_preop:
9059 case AMDGPU::BI__builtin_amdgcn_trig_preopf:
9060 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_trig_preop);
9061 case AMDGPU::BI__builtin_amdgcn_rcp:
9062 case AMDGPU::BI__builtin_amdgcn_rcpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009063 case AMDGPU::BI__builtin_amdgcn_rcph:
Matt Arsenault105e8922016-02-03 17:49:38 +00009064 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rcp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009065 case AMDGPU::BI__builtin_amdgcn_rsq:
9066 case AMDGPU::BI__builtin_amdgcn_rsqf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009067 case AMDGPU::BI__builtin_amdgcn_rsqh:
Matt Arsenault105e8922016-02-03 17:49:38 +00009068 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq);
Matt Arsenaultf5c1f472016-02-13 01:03:09 +00009069 case AMDGPU::BI__builtin_amdgcn_rsq_clamp:
9070 case AMDGPU::BI__builtin_amdgcn_rsq_clampf:
9071 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_rsq_clamp);
Matt Arsenault9b277b42016-02-13 01:21:09 +00009072 case AMDGPU::BI__builtin_amdgcn_sinf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009073 case AMDGPU::BI__builtin_amdgcn_sinh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00009074 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_sin);
9075 case AMDGPU::BI__builtin_amdgcn_cosf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009076 case AMDGPU::BI__builtin_amdgcn_cosh:
Matt Arsenault9b277b42016-02-13 01:21:09 +00009077 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_cos);
9078 case AMDGPU::BI__builtin_amdgcn_log_clampf:
9079 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_log_clamp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009080 case AMDGPU::BI__builtin_amdgcn_ldexp:
9081 case AMDGPU::BI__builtin_amdgcn_ldexpf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009082 case AMDGPU::BI__builtin_amdgcn_ldexph:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009083 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_ldexp);
Matt Arsenault3fb96332016-03-30 22:57:40 +00009084 case AMDGPU::BI__builtin_amdgcn_frexp_mant:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009085 case AMDGPU::BI__builtin_amdgcn_frexp_mantf:
9086 case AMDGPU::BI__builtin_amdgcn_frexp_manth:
Matt Arsenault3fb96332016-03-30 22:57:40 +00009087 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_frexp_mant);
Matt Arsenault3fb96332016-03-30 22:57:40 +00009088 case AMDGPU::BI__builtin_amdgcn_frexp_exp:
Konstantin Zhuravlyov62ae8f62016-11-18 22:31:51 +00009089 case AMDGPU::BI__builtin_amdgcn_frexp_expf: {
9090 Value *Src0 = EmitScalarExpr(E->getArg(0));
9091 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
9092 { Builder.getInt32Ty(), Src0->getType() });
9093 return Builder.CreateCall(F, Src0);
9094 }
9095 case AMDGPU::BI__builtin_amdgcn_frexp_exph: {
9096 Value *Src0 = EmitScalarExpr(E->getArg(0));
9097 Value *F = CGM.getIntrinsic(Intrinsic::amdgcn_frexp_exp,
9098 { Builder.getInt16Ty(), Src0->getType() });
9099 return Builder.CreateCall(F, Src0);
9100 }
Matt Arsenault2d510592016-05-28 00:43:27 +00009101 case AMDGPU::BI__builtin_amdgcn_fract:
9102 case AMDGPU::BI__builtin_amdgcn_fractf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009103 case AMDGPU::BI__builtin_amdgcn_fracth:
Matt Arsenault2d510592016-05-28 00:43:27 +00009104 return emitUnaryBuiltin(*this, E, Intrinsic::amdgcn_fract);
Wei Dingea41f352016-07-15 16:43:03 +00009105 case AMDGPU::BI__builtin_amdgcn_lerp:
9106 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_lerp);
Wei Ding91c84502016-08-05 15:38:46 +00009107 case AMDGPU::BI__builtin_amdgcn_uicmp:
9108 case AMDGPU::BI__builtin_amdgcn_uicmpl:
9109 case AMDGPU::BI__builtin_amdgcn_sicmp:
9110 case AMDGPU::BI__builtin_amdgcn_sicmpl:
9111 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_icmp);
9112 case AMDGPU::BI__builtin_amdgcn_fcmp:
9113 case AMDGPU::BI__builtin_amdgcn_fcmpf:
9114 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fcmp);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009115 case AMDGPU::BI__builtin_amdgcn_class:
9116 case AMDGPU::BI__builtin_amdgcn_classf:
Konstantin Zhuravlyov81a78bb2016-11-13 02:37:05 +00009117 case AMDGPU::BI__builtin_amdgcn_classh:
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009118 return emitFPIntBuiltin(*this, E, Intrinsic::amdgcn_class);
Matt Arsenaulta274b202017-01-31 03:42:07 +00009119 case AMDGPU::BI__builtin_amdgcn_fmed3f:
Matt Arsenaulta0c6dca2017-02-22 20:55:59 +00009120 case AMDGPU::BI__builtin_amdgcn_fmed3h:
Matt Arsenaulta274b202017-01-31 03:42:07 +00009121 return emitTernaryBuiltin(*this, E, Intrinsic::amdgcn_fmed3);
Matt Arsenault64665bc2016-06-28 00:13:17 +00009122 case AMDGPU::BI__builtin_amdgcn_read_exec: {
9123 CallInst *CI = cast<CallInst>(
9124 EmitSpecialRegisterBuiltin(*this, E, Int64Ty, Int64Ty, true, "exec"));
9125 CI->setConvergent();
9126 return CI;
9127 }
Matt Arsenaultf12e3b82017-10-09 20:06:37 +00009128 case AMDGPU::BI__builtin_amdgcn_read_exec_lo:
9129 case AMDGPU::BI__builtin_amdgcn_read_exec_hi: {
9130 StringRef RegName = BuiltinID == AMDGPU::BI__builtin_amdgcn_read_exec_lo ?
9131 "exec_lo" : "exec_hi";
9132 CallInst *CI = cast<CallInst>(
9133 EmitSpecialRegisterBuiltin(*this, E, Int32Ty, Int32Ty, true, RegName));
9134 CI->setConvergent();
9135 return CI;
9136 }
Jan Veselyd7e03a52016-07-10 22:38:04 +00009137
9138 // amdgcn workitem
9139 case AMDGPU::BI__builtin_amdgcn_workitem_id_x:
9140 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_x, 0, 1024);
9141 case AMDGPU::BI__builtin_amdgcn_workitem_id_y:
9142 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_y, 0, 1024);
9143 case AMDGPU::BI__builtin_amdgcn_workitem_id_z:
9144 return emitRangedBuiltin(*this, Intrinsic::amdgcn_workitem_id_z, 0, 1024);
9145
Matt Arsenaultc86671d2016-07-15 21:33:02 +00009146 // r600 intrinsics
9147 case AMDGPU::BI__builtin_r600_recipsqrt_ieee:
9148 case AMDGPU::BI__builtin_r600_recipsqrt_ieeef:
9149 return emitUnaryBuiltin(*this, E, Intrinsic::r600_recipsqrt_ieee);
Jan Veselyd7e03a52016-07-10 22:38:04 +00009150 case AMDGPU::BI__builtin_r600_read_tidig_x:
9151 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_x, 0, 1024);
9152 case AMDGPU::BI__builtin_r600_read_tidig_y:
9153 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_y, 0, 1024);
9154 case AMDGPU::BI__builtin_r600_read_tidig_z:
9155 return emitRangedBuiltin(*this, Intrinsic::r600_read_tidig_z, 0, 1024);
Matt Arsenault8a4078c2016-01-22 21:30:53 +00009156 default:
Matt Arsenault56f008d2014-06-24 20:45:01 +00009157 return nullptr;
9158 }
9159}
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009160
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009161/// Handle a SystemZ function in which the final argument is a pointer
9162/// to an int that receives the post-instruction CC value. At the LLVM level
9163/// this is represented as a function that returns a {result, cc} pair.
9164static Value *EmitSystemZIntrinsicWithCC(CodeGenFunction &CGF,
9165 unsigned IntrinsicID,
9166 const CallExpr *E) {
9167 unsigned NumArgs = E->getNumArgs() - 1;
9168 SmallVector<Value *, 8> Args(NumArgs);
9169 for (unsigned I = 0; I < NumArgs; ++I)
9170 Args[I] = CGF.EmitScalarExpr(E->getArg(I));
John McCall7f416cc2015-09-08 08:05:57 +00009171 Address CCPtr = CGF.EmitPointerWithAlignment(E->getArg(NumArgs));
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009172 Value *F = CGF.CGM.getIntrinsic(IntrinsicID);
9173 Value *Call = CGF.Builder.CreateCall(F, Args);
9174 Value *CC = CGF.Builder.CreateExtractValue(Call, 1);
9175 CGF.Builder.CreateStore(CC, CCPtr);
9176 return CGF.Builder.CreateExtractValue(Call, 0);
9177}
9178
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009179Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
9180 const CallExpr *E) {
9181 switch (BuiltinID) {
9182 case SystemZ::BI__builtin_tbegin: {
9183 Value *TDB = EmitScalarExpr(E->getArg(0));
9184 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
9185 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin);
David Blaikie43f9bb72015-05-18 22:14:03 +00009186 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009187 }
9188 case SystemZ::BI__builtin_tbegin_nofloat: {
9189 Value *TDB = EmitScalarExpr(E->getArg(0));
9190 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff0c);
9191 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbegin_nofloat);
David Blaikie43f9bb72015-05-18 22:14:03 +00009192 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009193 }
9194 case SystemZ::BI__builtin_tbeginc: {
9195 Value *TDB = llvm::ConstantPointerNull::get(Int8PtrTy);
9196 Value *Control = llvm::ConstantInt::get(Int32Ty, 0xff08);
9197 Value *F = CGM.getIntrinsic(Intrinsic::s390_tbeginc);
David Blaikie43f9bb72015-05-18 22:14:03 +00009198 return Builder.CreateCall(F, {TDB, Control});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009199 }
9200 case SystemZ::BI__builtin_tabort: {
9201 Value *Data = EmitScalarExpr(E->getArg(0));
9202 Value *F = CGM.getIntrinsic(Intrinsic::s390_tabort);
9203 return Builder.CreateCall(F, Builder.CreateSExt(Data, Int64Ty, "tabort"));
9204 }
9205 case SystemZ::BI__builtin_non_tx_store: {
9206 Value *Address = EmitScalarExpr(E->getArg(0));
9207 Value *Data = EmitScalarExpr(E->getArg(1));
9208 Value *F = CGM.getIntrinsic(Intrinsic::s390_ntstg);
David Blaikie43f9bb72015-05-18 22:14:03 +00009209 return Builder.CreateCall(F, {Data, Address});
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009210 }
9211
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009212 // Vector builtins. Note that most vector builtins are mapped automatically
9213 // to target-specific LLVM intrinsics. The ones handled specially here can
9214 // be represented via standard LLVM IR, which is preferable to enable common
9215 // LLVM optimizations.
9216
9217 case SystemZ::BI__builtin_s390_vpopctb:
9218 case SystemZ::BI__builtin_s390_vpopcth:
9219 case SystemZ::BI__builtin_s390_vpopctf:
9220 case SystemZ::BI__builtin_s390_vpopctg: {
9221 llvm::Type *ResultType = ConvertType(E->getType());
9222 Value *X = EmitScalarExpr(E->getArg(0));
9223 Function *F = CGM.getIntrinsic(Intrinsic::ctpop, ResultType);
9224 return Builder.CreateCall(F, X);
9225 }
9226
9227 case SystemZ::BI__builtin_s390_vclzb:
9228 case SystemZ::BI__builtin_s390_vclzh:
9229 case SystemZ::BI__builtin_s390_vclzf:
9230 case SystemZ::BI__builtin_s390_vclzg: {
9231 llvm::Type *ResultType = ConvertType(E->getType());
9232 Value *X = EmitScalarExpr(E->getArg(0));
9233 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
9234 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009235 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009236 }
9237
9238 case SystemZ::BI__builtin_s390_vctzb:
9239 case SystemZ::BI__builtin_s390_vctzh:
9240 case SystemZ::BI__builtin_s390_vctzf:
9241 case SystemZ::BI__builtin_s390_vctzg: {
9242 llvm::Type *ResultType = ConvertType(E->getType());
9243 Value *X = EmitScalarExpr(E->getArg(0));
9244 Value *Undef = ConstantInt::get(Builder.getInt1Ty(), false);
9245 Function *F = CGM.getIntrinsic(Intrinsic::cttz, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009246 return Builder.CreateCall(F, {X, Undef});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009247 }
9248
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009249 case SystemZ::BI__builtin_s390_vfsqsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009250 case SystemZ::BI__builtin_s390_vfsqdb: {
9251 llvm::Type *ResultType = ConvertType(E->getType());
9252 Value *X = EmitScalarExpr(E->getArg(0));
9253 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
9254 return Builder.CreateCall(F, X);
9255 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009256 case SystemZ::BI__builtin_s390_vfmasb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009257 case SystemZ::BI__builtin_s390_vfmadb: {
9258 llvm::Type *ResultType = ConvertType(E->getType());
9259 Value *X = EmitScalarExpr(E->getArg(0));
9260 Value *Y = EmitScalarExpr(E->getArg(1));
9261 Value *Z = EmitScalarExpr(E->getArg(2));
9262 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009263 return Builder.CreateCall(F, {X, Y, Z});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009264 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009265 case SystemZ::BI__builtin_s390_vfmssb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009266 case SystemZ::BI__builtin_s390_vfmsdb: {
9267 llvm::Type *ResultType = ConvertType(E->getType());
9268 Value *X = EmitScalarExpr(E->getArg(0));
9269 Value *Y = EmitScalarExpr(E->getArg(1));
9270 Value *Z = EmitScalarExpr(E->getArg(2));
9271 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9272 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
David Blaikie43f9bb72015-05-18 22:14:03 +00009273 return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009274 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009275 case SystemZ::BI__builtin_s390_vfnmasb:
9276 case SystemZ::BI__builtin_s390_vfnmadb: {
9277 llvm::Type *ResultType = ConvertType(E->getType());
9278 Value *X = EmitScalarExpr(E->getArg(0));
9279 Value *Y = EmitScalarExpr(E->getArg(1));
9280 Value *Z = EmitScalarExpr(E->getArg(2));
9281 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9282 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9283 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub");
9284 }
9285 case SystemZ::BI__builtin_s390_vfnmssb:
9286 case SystemZ::BI__builtin_s390_vfnmsdb: {
9287 llvm::Type *ResultType = ConvertType(E->getType());
9288 Value *X = EmitScalarExpr(E->getArg(0));
9289 Value *Y = EmitScalarExpr(E->getArg(1));
9290 Value *Z = EmitScalarExpr(E->getArg(2));
9291 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9292 Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
9293 Value *NegZ = Builder.CreateFSub(Zero, Z, "sub");
9294 return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ}));
9295 }
9296 case SystemZ::BI__builtin_s390_vflpsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009297 case SystemZ::BI__builtin_s390_vflpdb: {
9298 llvm::Type *ResultType = ConvertType(E->getType());
9299 Value *X = EmitScalarExpr(E->getArg(0));
9300 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9301 return Builder.CreateCall(F, X);
9302 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009303 case SystemZ::BI__builtin_s390_vflnsb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009304 case SystemZ::BI__builtin_s390_vflndb: {
9305 llvm::Type *ResultType = ConvertType(E->getType());
9306 Value *X = EmitScalarExpr(E->getArg(0));
9307 Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
9308 Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
9309 return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub");
9310 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009311 case SystemZ::BI__builtin_s390_vfisb:
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009312 case SystemZ::BI__builtin_s390_vfidb: {
9313 llvm::Type *ResultType = ConvertType(E->getType());
9314 Value *X = EmitScalarExpr(E->getArg(0));
9315 // Constant-fold the M4 and M5 mask arguments.
9316 llvm::APSInt M4, M5;
9317 bool IsConstM4 = E->getArg(1)->isIntegerConstantExpr(M4, getContext());
9318 bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext());
9319 assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?");
9320 (void)IsConstM4; (void)IsConstM5;
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009321 // Check whether this instance can be represented via a LLVM standard
9322 // intrinsic. We only support some combinations of M4 and M5.
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009323 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9324 switch (M4.getZExtValue()) {
9325 default: break;
9326 case 0: // IEEE-inexact exception allowed
9327 switch (M5.getZExtValue()) {
9328 default: break;
9329 case 0: ID = Intrinsic::rint; break;
9330 }
9331 break;
9332 case 4: // IEEE-inexact exception suppressed
9333 switch (M5.getZExtValue()) {
9334 default: break;
9335 case 0: ID = Intrinsic::nearbyint; break;
9336 case 1: ID = Intrinsic::round; break;
9337 case 5: ID = Intrinsic::trunc; break;
9338 case 6: ID = Intrinsic::ceil; break;
9339 case 7: ID = Intrinsic::floor; break;
9340 }
9341 break;
9342 }
9343 if (ID != Intrinsic::not_intrinsic) {
9344 Function *F = CGM.getIntrinsic(ID, ResultType);
9345 return Builder.CreateCall(F, X);
9346 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009347 switch (BuiltinID) {
9348 case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break;
9349 case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break;
9350 default: llvm_unreachable("Unknown BuiltinID");
9351 }
9352 Function *F = CGM.getIntrinsic(ID);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009353 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9354 Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5);
David Blaikie43f9bb72015-05-18 22:14:03 +00009355 return Builder.CreateCall(F, {X, M4Value, M5Value});
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009356 }
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009357 case SystemZ::BI__builtin_s390_vfmaxsb:
9358 case SystemZ::BI__builtin_s390_vfmaxdb: {
9359 llvm::Type *ResultType = ConvertType(E->getType());
9360 Value *X = EmitScalarExpr(E->getArg(0));
9361 Value *Y = EmitScalarExpr(E->getArg(1));
9362 // Constant-fold the M4 mask argument.
9363 llvm::APSInt M4;
9364 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9365 assert(IsConstM4 && "Constant arg isn't actually constant?");
9366 (void)IsConstM4;
9367 // Check whether this instance can be represented via a LLVM standard
9368 // intrinsic. We only support some values of M4.
9369 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9370 switch (M4.getZExtValue()) {
9371 default: break;
9372 case 4: ID = Intrinsic::maxnum; break;
9373 }
9374 if (ID != Intrinsic::not_intrinsic) {
9375 Function *F = CGM.getIntrinsic(ID, ResultType);
9376 return Builder.CreateCall(F, {X, Y});
9377 }
9378 switch (BuiltinID) {
9379 case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break;
9380 case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break;
9381 default: llvm_unreachable("Unknown BuiltinID");
9382 }
9383 Function *F = CGM.getIntrinsic(ID);
9384 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9385 return Builder.CreateCall(F, {X, Y, M4Value});
9386 }
9387 case SystemZ::BI__builtin_s390_vfminsb:
9388 case SystemZ::BI__builtin_s390_vfmindb: {
9389 llvm::Type *ResultType = ConvertType(E->getType());
9390 Value *X = EmitScalarExpr(E->getArg(0));
9391 Value *Y = EmitScalarExpr(E->getArg(1));
9392 // Constant-fold the M4 mask argument.
9393 llvm::APSInt M4;
9394 bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
9395 assert(IsConstM4 && "Constant arg isn't actually constant?");
9396 (void)IsConstM4;
9397 // Check whether this instance can be represented via a LLVM standard
9398 // intrinsic. We only support some values of M4.
9399 Intrinsic::ID ID = Intrinsic::not_intrinsic;
9400 switch (M4.getZExtValue()) {
9401 default: break;
9402 case 4: ID = Intrinsic::minnum; break;
9403 }
9404 if (ID != Intrinsic::not_intrinsic) {
9405 Function *F = CGM.getIntrinsic(ID, ResultType);
9406 return Builder.CreateCall(F, {X, Y});
9407 }
9408 switch (BuiltinID) {
9409 case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break;
9410 case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break;
9411 default: llvm_unreachable("Unknown BuiltinID");
9412 }
9413 Function *F = CGM.getIntrinsic(ID);
9414 Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
9415 return Builder.CreateCall(F, {X, Y, M4Value});
9416 }
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009417
9418 // Vector intrisincs that output the post-instruction CC value.
9419
9420#define INTRINSIC_WITH_CC(NAME) \
9421 case SystemZ::BI__builtin_##NAME: \
9422 return EmitSystemZIntrinsicWithCC(*this, Intrinsic::NAME, E)
9423
9424 INTRINSIC_WITH_CC(s390_vpkshs);
9425 INTRINSIC_WITH_CC(s390_vpksfs);
9426 INTRINSIC_WITH_CC(s390_vpksgs);
9427
9428 INTRINSIC_WITH_CC(s390_vpklshs);
9429 INTRINSIC_WITH_CC(s390_vpklsfs);
9430 INTRINSIC_WITH_CC(s390_vpklsgs);
9431
9432 INTRINSIC_WITH_CC(s390_vceqbs);
9433 INTRINSIC_WITH_CC(s390_vceqhs);
9434 INTRINSIC_WITH_CC(s390_vceqfs);
9435 INTRINSIC_WITH_CC(s390_vceqgs);
9436
9437 INTRINSIC_WITH_CC(s390_vchbs);
9438 INTRINSIC_WITH_CC(s390_vchhs);
9439 INTRINSIC_WITH_CC(s390_vchfs);
9440 INTRINSIC_WITH_CC(s390_vchgs);
9441
9442 INTRINSIC_WITH_CC(s390_vchlbs);
9443 INTRINSIC_WITH_CC(s390_vchlhs);
9444 INTRINSIC_WITH_CC(s390_vchlfs);
9445 INTRINSIC_WITH_CC(s390_vchlgs);
9446
9447 INTRINSIC_WITH_CC(s390_vfaebs);
9448 INTRINSIC_WITH_CC(s390_vfaehs);
9449 INTRINSIC_WITH_CC(s390_vfaefs);
9450
9451 INTRINSIC_WITH_CC(s390_vfaezbs);
9452 INTRINSIC_WITH_CC(s390_vfaezhs);
9453 INTRINSIC_WITH_CC(s390_vfaezfs);
9454
9455 INTRINSIC_WITH_CC(s390_vfeebs);
9456 INTRINSIC_WITH_CC(s390_vfeehs);
9457 INTRINSIC_WITH_CC(s390_vfeefs);
9458
9459 INTRINSIC_WITH_CC(s390_vfeezbs);
9460 INTRINSIC_WITH_CC(s390_vfeezhs);
9461 INTRINSIC_WITH_CC(s390_vfeezfs);
9462
9463 INTRINSIC_WITH_CC(s390_vfenebs);
9464 INTRINSIC_WITH_CC(s390_vfenehs);
9465 INTRINSIC_WITH_CC(s390_vfenefs);
9466
9467 INTRINSIC_WITH_CC(s390_vfenezbs);
9468 INTRINSIC_WITH_CC(s390_vfenezhs);
9469 INTRINSIC_WITH_CC(s390_vfenezfs);
9470
9471 INTRINSIC_WITH_CC(s390_vistrbs);
9472 INTRINSIC_WITH_CC(s390_vistrhs);
9473 INTRINSIC_WITH_CC(s390_vistrfs);
9474
9475 INTRINSIC_WITH_CC(s390_vstrcbs);
9476 INTRINSIC_WITH_CC(s390_vstrchs);
9477 INTRINSIC_WITH_CC(s390_vstrcfs);
9478
9479 INTRINSIC_WITH_CC(s390_vstrczbs);
9480 INTRINSIC_WITH_CC(s390_vstrczhs);
9481 INTRINSIC_WITH_CC(s390_vstrczfs);
9482
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009483 INTRINSIC_WITH_CC(s390_vfcesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009484 INTRINSIC_WITH_CC(s390_vfcedbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009485 INTRINSIC_WITH_CC(s390_vfchsbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009486 INTRINSIC_WITH_CC(s390_vfchdbs);
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009487 INTRINSIC_WITH_CC(s390_vfchesbs);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009488 INTRINSIC_WITH_CC(s390_vfchedbs);
9489
Ulrich Weigandcac24ab2017-07-17 17:45:57 +00009490 INTRINSIC_WITH_CC(s390_vftcisb);
Ulrich Weigand5722c0f2015-05-05 19:36:42 +00009491 INTRINSIC_WITH_CC(s390_vftcidb);
9492
9493#undef INTRINSIC_WITH_CC
9494
Ulrich Weigand3a610eb2015-04-01 12:54:25 +00009495 default:
9496 return nullptr;
9497 }
9498}
Artem Belevichd21e5c62015-06-25 18:29:42 +00009499
9500Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID,
9501 const CallExpr *E) {
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009502 auto MakeLdg = [&](unsigned IntrinsicID) {
9503 Value *Ptr = EmitScalarExpr(E->getArg(0));
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009504 clang::CharUnits Align =
Krzysztof Parzyszek8f248232017-05-18 17:07:11 +00009505 getNaturalPointeeTypeAlignment(E->getArg(0)->getType());
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009506 return Builder.CreateCall(
9507 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9508 Ptr->getType()}),
9509 {Ptr, ConstantInt::get(Builder.getInt32Ty(), Align.getQuantity())});
9510 };
Artem Belevichfda99052016-09-28 17:47:35 +00009511 auto MakeScopedAtomic = [&](unsigned IntrinsicID) {
9512 Value *Ptr = EmitScalarExpr(E->getArg(0));
9513 return Builder.CreateCall(
9514 CGM.getIntrinsic(IntrinsicID, {Ptr->getType()->getPointerElementType(),
9515 Ptr->getType()}),
9516 {Ptr, EmitScalarExpr(E->getArg(1))});
9517 };
Artem Belevichd21e5c62015-06-25 18:29:42 +00009518 switch (BuiltinID) {
9519 case NVPTX::BI__nvvm_atom_add_gen_i:
9520 case NVPTX::BI__nvvm_atom_add_gen_l:
9521 case NVPTX::BI__nvvm_atom_add_gen_ll:
9522 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Add, E);
9523
9524 case NVPTX::BI__nvvm_atom_sub_gen_i:
9525 case NVPTX::BI__nvvm_atom_sub_gen_l:
9526 case NVPTX::BI__nvvm_atom_sub_gen_ll:
9527 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Sub, E);
9528
9529 case NVPTX::BI__nvvm_atom_and_gen_i:
9530 case NVPTX::BI__nvvm_atom_and_gen_l:
9531 case NVPTX::BI__nvvm_atom_and_gen_ll:
9532 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::And, E);
9533
9534 case NVPTX::BI__nvvm_atom_or_gen_i:
9535 case NVPTX::BI__nvvm_atom_or_gen_l:
9536 case NVPTX::BI__nvvm_atom_or_gen_ll:
9537 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Or, E);
9538
9539 case NVPTX::BI__nvvm_atom_xor_gen_i:
9540 case NVPTX::BI__nvvm_atom_xor_gen_l:
9541 case NVPTX::BI__nvvm_atom_xor_gen_ll:
9542 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xor, E);
9543
9544 case NVPTX::BI__nvvm_atom_xchg_gen_i:
9545 case NVPTX::BI__nvvm_atom_xchg_gen_l:
9546 case NVPTX::BI__nvvm_atom_xchg_gen_ll:
9547 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Xchg, E);
9548
9549 case NVPTX::BI__nvvm_atom_max_gen_i:
9550 case NVPTX::BI__nvvm_atom_max_gen_l:
9551 case NVPTX::BI__nvvm_atom_max_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009552 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Max, E);
9553
Artem Belevichd21e5c62015-06-25 18:29:42 +00009554 case NVPTX::BI__nvvm_atom_max_gen_ui:
9555 case NVPTX::BI__nvvm_atom_max_gen_ul:
9556 case NVPTX::BI__nvvm_atom_max_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009557 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMax, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009558
9559 case NVPTX::BI__nvvm_atom_min_gen_i:
9560 case NVPTX::BI__nvvm_atom_min_gen_l:
9561 case NVPTX::BI__nvvm_atom_min_gen_ll:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009562 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::Min, E);
9563
Artem Belevichd21e5c62015-06-25 18:29:42 +00009564 case NVPTX::BI__nvvm_atom_min_gen_ui:
9565 case NVPTX::BI__nvvm_atom_min_gen_ul:
9566 case NVPTX::BI__nvvm_atom_min_gen_ull:
Jingyue Wu2d69f962015-08-31 17:25:51 +00009567 return MakeBinaryAtomicValue(*this, llvm::AtomicRMWInst::UMin, E);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009568
9569 case NVPTX::BI__nvvm_atom_cas_gen_i:
9570 case NVPTX::BI__nvvm_atom_cas_gen_l:
9571 case NVPTX::BI__nvvm_atom_cas_gen_ll:
Jingyue Wuf1eca252015-09-30 21:49:32 +00009572 // __nvvm_atom_cas_gen_* should return the old value rather than the
9573 // success flag.
9574 return MakeAtomicCmpXchgValue(*this, E, /*ReturnBool=*/false);
Artem Belevichd21e5c62015-06-25 18:29:42 +00009575
9576 case NVPTX::BI__nvvm_atom_add_gen_f: {
9577 Value *Ptr = EmitScalarExpr(E->getArg(0));
9578 Value *Val = EmitScalarExpr(E->getArg(1));
9579 // atomicrmw only deals with integer arguments so we need to use
9580 // LLVM's nvvm_atomic_load_add_f32 intrinsic for that.
9581 Value *FnALAF32 =
9582 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f32, Ptr->getType());
9583 return Builder.CreateCall(FnALAF32, {Ptr, Val});
9584 }
9585
Justin Lebar717d2b02016-03-22 00:09:28 +00009586 case NVPTX::BI__nvvm_atom_inc_gen_ui: {
9587 Value *Ptr = EmitScalarExpr(E->getArg(0));
9588 Value *Val = EmitScalarExpr(E->getArg(1));
9589 Value *FnALI32 =
9590 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_inc_32, Ptr->getType());
9591 return Builder.CreateCall(FnALI32, {Ptr, Val});
9592 }
9593
9594 case NVPTX::BI__nvvm_atom_dec_gen_ui: {
9595 Value *Ptr = EmitScalarExpr(E->getArg(0));
9596 Value *Val = EmitScalarExpr(E->getArg(1));
9597 Value *FnALD32 =
9598 CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_dec_32, Ptr->getType());
9599 return Builder.CreateCall(FnALD32, {Ptr, Val});
9600 }
9601
Justin Lebar2e4ecfd2016-05-19 22:49:13 +00009602 case NVPTX::BI__nvvm_ldg_c:
9603 case NVPTX::BI__nvvm_ldg_c2:
9604 case NVPTX::BI__nvvm_ldg_c4:
9605 case NVPTX::BI__nvvm_ldg_s:
9606 case NVPTX::BI__nvvm_ldg_s2:
9607 case NVPTX::BI__nvvm_ldg_s4:
9608 case NVPTX::BI__nvvm_ldg_i:
9609 case NVPTX::BI__nvvm_ldg_i2:
9610 case NVPTX::BI__nvvm_ldg_i4:
9611 case NVPTX::BI__nvvm_ldg_l:
9612 case NVPTX::BI__nvvm_ldg_ll:
9613 case NVPTX::BI__nvvm_ldg_ll2:
9614 case NVPTX::BI__nvvm_ldg_uc:
9615 case NVPTX::BI__nvvm_ldg_uc2:
9616 case NVPTX::BI__nvvm_ldg_uc4:
9617 case NVPTX::BI__nvvm_ldg_us:
9618 case NVPTX::BI__nvvm_ldg_us2:
9619 case NVPTX::BI__nvvm_ldg_us4:
9620 case NVPTX::BI__nvvm_ldg_ui:
9621 case NVPTX::BI__nvvm_ldg_ui2:
9622 case NVPTX::BI__nvvm_ldg_ui4:
9623 case NVPTX::BI__nvvm_ldg_ul:
9624 case NVPTX::BI__nvvm_ldg_ull:
9625 case NVPTX::BI__nvvm_ldg_ull2:
9626 // PTX Interoperability section 2.2: "For a vector with an even number of
9627 // elements, its alignment is set to number of elements times the alignment
9628 // of its member: n*alignof(t)."
9629 return MakeLdg(Intrinsic::nvvm_ldg_global_i);
9630 case NVPTX::BI__nvvm_ldg_f:
9631 case NVPTX::BI__nvvm_ldg_f2:
9632 case NVPTX::BI__nvvm_ldg_f4:
9633 case NVPTX::BI__nvvm_ldg_d:
9634 case NVPTX::BI__nvvm_ldg_d2:
9635 return MakeLdg(Intrinsic::nvvm_ldg_global_f);
Artem Belevichfda99052016-09-28 17:47:35 +00009636
9637 case NVPTX::BI__nvvm_atom_cta_add_gen_i:
9638 case NVPTX::BI__nvvm_atom_cta_add_gen_l:
9639 case NVPTX::BI__nvvm_atom_cta_add_gen_ll:
9640 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_cta);
9641 case NVPTX::BI__nvvm_atom_sys_add_gen_i:
9642 case NVPTX::BI__nvvm_atom_sys_add_gen_l:
9643 case NVPTX::BI__nvvm_atom_sys_add_gen_ll:
9644 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_i_sys);
9645 case NVPTX::BI__nvvm_atom_cta_add_gen_f:
9646 case NVPTX::BI__nvvm_atom_cta_add_gen_d:
9647 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_cta);
9648 case NVPTX::BI__nvvm_atom_sys_add_gen_f:
9649 case NVPTX::BI__nvvm_atom_sys_add_gen_d:
9650 return MakeScopedAtomic(Intrinsic::nvvm_atomic_add_gen_f_sys);
9651 case NVPTX::BI__nvvm_atom_cta_xchg_gen_i:
9652 case NVPTX::BI__nvvm_atom_cta_xchg_gen_l:
9653 case NVPTX::BI__nvvm_atom_cta_xchg_gen_ll:
9654 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_cta);
9655 case NVPTX::BI__nvvm_atom_sys_xchg_gen_i:
9656 case NVPTX::BI__nvvm_atom_sys_xchg_gen_l:
9657 case NVPTX::BI__nvvm_atom_sys_xchg_gen_ll:
9658 return MakeScopedAtomic(Intrinsic::nvvm_atomic_exch_gen_i_sys);
9659 case NVPTX::BI__nvvm_atom_cta_max_gen_i:
9660 case NVPTX::BI__nvvm_atom_cta_max_gen_ui:
9661 case NVPTX::BI__nvvm_atom_cta_max_gen_l:
9662 case NVPTX::BI__nvvm_atom_cta_max_gen_ul:
9663 case NVPTX::BI__nvvm_atom_cta_max_gen_ll:
9664 case NVPTX::BI__nvvm_atom_cta_max_gen_ull:
9665 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_cta);
9666 case NVPTX::BI__nvvm_atom_sys_max_gen_i:
9667 case NVPTX::BI__nvvm_atom_sys_max_gen_ui:
9668 case NVPTX::BI__nvvm_atom_sys_max_gen_l:
9669 case NVPTX::BI__nvvm_atom_sys_max_gen_ul:
9670 case NVPTX::BI__nvvm_atom_sys_max_gen_ll:
9671 case NVPTX::BI__nvvm_atom_sys_max_gen_ull:
9672 return MakeScopedAtomic(Intrinsic::nvvm_atomic_max_gen_i_sys);
9673 case NVPTX::BI__nvvm_atom_cta_min_gen_i:
9674 case NVPTX::BI__nvvm_atom_cta_min_gen_ui:
9675 case NVPTX::BI__nvvm_atom_cta_min_gen_l:
9676 case NVPTX::BI__nvvm_atom_cta_min_gen_ul:
9677 case NVPTX::BI__nvvm_atom_cta_min_gen_ll:
9678 case NVPTX::BI__nvvm_atom_cta_min_gen_ull:
9679 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_cta);
9680 case NVPTX::BI__nvvm_atom_sys_min_gen_i:
9681 case NVPTX::BI__nvvm_atom_sys_min_gen_ui:
9682 case NVPTX::BI__nvvm_atom_sys_min_gen_l:
9683 case NVPTX::BI__nvvm_atom_sys_min_gen_ul:
9684 case NVPTX::BI__nvvm_atom_sys_min_gen_ll:
9685 case NVPTX::BI__nvvm_atom_sys_min_gen_ull:
9686 return MakeScopedAtomic(Intrinsic::nvvm_atomic_min_gen_i_sys);
9687 case NVPTX::BI__nvvm_atom_cta_inc_gen_ui:
9688 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_cta);
9689 case NVPTX::BI__nvvm_atom_cta_dec_gen_ui:
9690 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_cta);
9691 case NVPTX::BI__nvvm_atom_sys_inc_gen_ui:
9692 return MakeScopedAtomic(Intrinsic::nvvm_atomic_inc_gen_i_sys);
9693 case NVPTX::BI__nvvm_atom_sys_dec_gen_ui:
9694 return MakeScopedAtomic(Intrinsic::nvvm_atomic_dec_gen_i_sys);
9695 case NVPTX::BI__nvvm_atom_cta_and_gen_i:
9696 case NVPTX::BI__nvvm_atom_cta_and_gen_l:
9697 case NVPTX::BI__nvvm_atom_cta_and_gen_ll:
9698 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_cta);
9699 case NVPTX::BI__nvvm_atom_sys_and_gen_i:
9700 case NVPTX::BI__nvvm_atom_sys_and_gen_l:
9701 case NVPTX::BI__nvvm_atom_sys_and_gen_ll:
9702 return MakeScopedAtomic(Intrinsic::nvvm_atomic_and_gen_i_sys);
9703 case NVPTX::BI__nvvm_atom_cta_or_gen_i:
9704 case NVPTX::BI__nvvm_atom_cta_or_gen_l:
9705 case NVPTX::BI__nvvm_atom_cta_or_gen_ll:
9706 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_cta);
9707 case NVPTX::BI__nvvm_atom_sys_or_gen_i:
9708 case NVPTX::BI__nvvm_atom_sys_or_gen_l:
9709 case NVPTX::BI__nvvm_atom_sys_or_gen_ll:
9710 return MakeScopedAtomic(Intrinsic::nvvm_atomic_or_gen_i_sys);
9711 case NVPTX::BI__nvvm_atom_cta_xor_gen_i:
9712 case NVPTX::BI__nvvm_atom_cta_xor_gen_l:
9713 case NVPTX::BI__nvvm_atom_cta_xor_gen_ll:
9714 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_cta);
9715 case NVPTX::BI__nvvm_atom_sys_xor_gen_i:
9716 case NVPTX::BI__nvvm_atom_sys_xor_gen_l:
9717 case NVPTX::BI__nvvm_atom_sys_xor_gen_ll:
9718 return MakeScopedAtomic(Intrinsic::nvvm_atomic_xor_gen_i_sys);
9719 case NVPTX::BI__nvvm_atom_cta_cas_gen_i:
9720 case NVPTX::BI__nvvm_atom_cta_cas_gen_l:
9721 case NVPTX::BI__nvvm_atom_cta_cas_gen_ll: {
9722 Value *Ptr = EmitScalarExpr(E->getArg(0));
9723 return Builder.CreateCall(
9724 CGM.getIntrinsic(
9725 Intrinsic::nvvm_atomic_cas_gen_i_cta,
9726 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9727 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9728 }
9729 case NVPTX::BI__nvvm_atom_sys_cas_gen_i:
9730 case NVPTX::BI__nvvm_atom_sys_cas_gen_l:
9731 case NVPTX::BI__nvvm_atom_sys_cas_gen_ll: {
9732 Value *Ptr = EmitScalarExpr(E->getArg(0));
9733 return Builder.CreateCall(
9734 CGM.getIntrinsic(
9735 Intrinsic::nvvm_atomic_cas_gen_i_sys,
9736 {Ptr->getType()->getPointerElementType(), Ptr->getType()}),
9737 {Ptr, EmitScalarExpr(E->getArg(1)), EmitScalarExpr(E->getArg(2))});
9738 }
Artem Belevichbab95c72017-09-26 17:07:23 +00009739 case NVPTX::BI__nvvm_match_all_sync_i32p:
9740 case NVPTX::BI__nvvm_match_all_sync_i64p: {
9741 Value *Mask = EmitScalarExpr(E->getArg(0));
9742 Value *Val = EmitScalarExpr(E->getArg(1));
9743 Address PredOutPtr = EmitPointerWithAlignment(E->getArg(2));
9744 Value *ResultPair = Builder.CreateCall(
9745 CGM.getIntrinsic(BuiltinID == NVPTX::BI__nvvm_match_all_sync_i32p
9746 ? Intrinsic::nvvm_match_all_sync_i32p
9747 : Intrinsic::nvvm_match_all_sync_i64p),
9748 {Mask, Val});
9749 Value *Pred = Builder.CreateZExt(Builder.CreateExtractValue(ResultPair, 1),
9750 PredOutPtr.getElementType());
9751 Builder.CreateStore(Pred, PredOutPtr);
9752 return Builder.CreateExtractValue(ResultPair, 0);
9753 }
Artem Belevich91cc00b2017-10-12 21:32:19 +00009754 case NVPTX::BI__hmma_m16n16k16_ld_a:
9755 case NVPTX::BI__hmma_m16n16k16_ld_b:
9756 case NVPTX::BI__hmma_m16n16k16_ld_c_f16:
9757 case NVPTX::BI__hmma_m16n16k16_ld_c_f32: {
9758 Address Dst = EmitPointerWithAlignment(E->getArg(0));
9759 Value *Src = EmitScalarExpr(E->getArg(1));
9760 Value *Ldm = EmitScalarExpr(E->getArg(2));
9761 llvm::APSInt isColMajorArg;
9762 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext()))
9763 return nullptr;
9764 bool isColMajor = isColMajorArg.getSExtValue();
9765 unsigned IID;
9766 unsigned NumResults;
9767 switch (BuiltinID) {
9768 case NVPTX::BI__hmma_m16n16k16_ld_a:
9769 IID = isColMajor ? Intrinsic::nvvm_wmma_load_a_f16_col_stride
9770 : Intrinsic::nvvm_wmma_load_a_f16_row_stride;
9771 NumResults = 8;
9772 break;
9773 case NVPTX::BI__hmma_m16n16k16_ld_b:
9774 IID = isColMajor ? Intrinsic::nvvm_wmma_load_b_f16_col_stride
9775 : Intrinsic::nvvm_wmma_load_b_f16_row_stride;
9776 NumResults = 8;
9777 break;
9778 case NVPTX::BI__hmma_m16n16k16_ld_c_f16:
9779 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f16_col_stride
9780 : Intrinsic::nvvm_wmma_load_c_f16_row_stride;
9781 NumResults = 4;
9782 break;
9783 case NVPTX::BI__hmma_m16n16k16_ld_c_f32:
9784 IID = isColMajor ? Intrinsic::nvvm_wmma_load_c_f32_col_stride
9785 : Intrinsic::nvvm_wmma_load_c_f32_row_stride;
9786 NumResults = 8;
9787 break;
9788 default:
9789 llvm_unreachable("Unexpected builtin ID.");
9790 }
9791 Value *Result =
9792 Builder.CreateCall(CGM.getIntrinsic(IID),
9793 {Builder.CreatePointerCast(Src, VoidPtrTy), Ldm});
9794
9795 // Save returned values.
9796 for (unsigned i = 0; i < NumResults; ++i) {
9797 Builder.CreateAlignedStore(
9798 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i),
9799 Dst.getElementType()),
9800 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)),
9801 CharUnits::fromQuantity(4));
9802 }
9803 return Result;
9804 }
9805
9806 case NVPTX::BI__hmma_m16n16k16_st_c_f16:
9807 case NVPTX::BI__hmma_m16n16k16_st_c_f32: {
9808 Value *Dst = EmitScalarExpr(E->getArg(0));
9809 Address Src = EmitPointerWithAlignment(E->getArg(1));
9810 Value *Ldm = EmitScalarExpr(E->getArg(2));
9811 llvm::APSInt isColMajorArg;
9812 if (!E->getArg(3)->isIntegerConstantExpr(isColMajorArg, getContext()))
9813 return nullptr;
9814 bool isColMajor = isColMajorArg.getSExtValue();
9815 unsigned IID;
9816 unsigned NumResults = 8;
9817 // PTX Instructions (and LLVM instrinsics) are defined for slice _d_, yet
9818 // for some reason nvcc builtins use _c_.
9819 switch (BuiltinID) {
9820 case NVPTX::BI__hmma_m16n16k16_st_c_f16:
9821 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f16_col_stride
9822 : Intrinsic::nvvm_wmma_store_d_f16_row_stride;
9823 NumResults = 4;
9824 break;
9825 case NVPTX::BI__hmma_m16n16k16_st_c_f32:
9826 IID = isColMajor ? Intrinsic::nvvm_wmma_store_d_f32_col_stride
9827 : Intrinsic::nvvm_wmma_store_d_f32_row_stride;
9828 break;
9829 default:
9830 llvm_unreachable("Unexpected builtin ID.");
9831 }
9832 Function *Intrinsic = CGM.getIntrinsic(IID);
9833 llvm::Type *ParamType = Intrinsic->getFunctionType()->getParamType(1);
9834 SmallVector<Value *, 10> Values;
9835 Values.push_back(Builder.CreatePointerCast(Dst, VoidPtrTy));
9836 for (unsigned i = 0; i < NumResults; ++i) {
9837 Value *V = Builder.CreateAlignedLoad(
9838 Builder.CreateGEP(Src.getPointer(), llvm::ConstantInt::get(IntTy, i)),
9839 CharUnits::fromQuantity(4));
9840 Values.push_back(Builder.CreateBitCast(V, ParamType));
9841 }
9842 Values.push_back(Ldm);
9843 Value *Result = Builder.CreateCall(Intrinsic, Values);
9844 return Result;
9845 }
9846
9847 // BI__hmma_m16n16k16_mma_<Dtype><CType>(d, a, b, c, layout, satf)
9848 // --> Intrinsic::nvvm_wmma_mma_sync<layout A,B><DType><CType><Satf>
9849 case NVPTX::BI__hmma_m16n16k16_mma_f16f16:
9850 case NVPTX::BI__hmma_m16n16k16_mma_f32f16:
9851 case NVPTX::BI__hmma_m16n16k16_mma_f32f32:
9852 case NVPTX::BI__hmma_m16n16k16_mma_f16f32: {
9853 Address Dst = EmitPointerWithAlignment(E->getArg(0));
9854 Address SrcA = EmitPointerWithAlignment(E->getArg(1));
9855 Address SrcB = EmitPointerWithAlignment(E->getArg(2));
9856 Address SrcC = EmitPointerWithAlignment(E->getArg(3));
9857 llvm::APSInt LayoutArg;
9858 if (!E->getArg(4)->isIntegerConstantExpr(LayoutArg, getContext()))
9859 return nullptr;
9860 int Layout = LayoutArg.getSExtValue();
9861 if (Layout < 0 || Layout > 3)
9862 return nullptr;
9863 llvm::APSInt SatfArg;
9864 if (!E->getArg(5)->isIntegerConstantExpr(SatfArg, getContext()))
9865 return nullptr;
9866 bool Satf = SatfArg.getSExtValue();
9867
9868 // clang-format off
9869#define MMA_VARIANTS(type) {{ \
9870 Intrinsic::nvvm_wmma_mma_sync_row_row_##type, \
9871 Intrinsic::nvvm_wmma_mma_sync_row_row_##type##_satfinite, \
9872 Intrinsic::nvvm_wmma_mma_sync_row_col_##type, \
9873 Intrinsic::nvvm_wmma_mma_sync_row_col_##type##_satfinite, \
9874 Intrinsic::nvvm_wmma_mma_sync_col_row_##type, \
9875 Intrinsic::nvvm_wmma_mma_sync_col_row_##type##_satfinite, \
9876 Intrinsic::nvvm_wmma_mma_sync_col_col_##type, \
9877 Intrinsic::nvvm_wmma_mma_sync_col_col_##type##_satfinite \
9878 }}
9879 // clang-format on
9880
9881 auto getMMAIntrinsic = [Layout, Satf](std::array<unsigned, 8> Variants) {
9882 unsigned Index = Layout * 2 + Satf;
9883 assert(Index < 8);
9884 return Variants[Index];
9885 };
9886 unsigned IID;
9887 unsigned NumEltsC;
9888 unsigned NumEltsD;
9889 switch (BuiltinID) {
9890 case NVPTX::BI__hmma_m16n16k16_mma_f16f16:
9891 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f16));
9892 NumEltsC = 4;
9893 NumEltsD = 4;
9894 break;
9895 case NVPTX::BI__hmma_m16n16k16_mma_f32f16:
9896 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f16));
9897 NumEltsC = 4;
9898 NumEltsD = 8;
9899 break;
9900 case NVPTX::BI__hmma_m16n16k16_mma_f16f32:
9901 IID = getMMAIntrinsic(MMA_VARIANTS(f16_f32));
9902 NumEltsC = 8;
9903 NumEltsD = 4;
9904 break;
9905 case NVPTX::BI__hmma_m16n16k16_mma_f32f32:
9906 IID = getMMAIntrinsic(MMA_VARIANTS(f32_f32));
9907 NumEltsC = 8;
9908 NumEltsD = 8;
9909 break;
9910 default:
9911 llvm_unreachable("Unexpected builtin ID.");
9912 }
9913#undef MMA_VARIANTS
9914
9915 SmallVector<Value *, 24> Values;
9916 Function *Intrinsic = CGM.getIntrinsic(IID);
9917 llvm::Type *ABType = Intrinsic->getFunctionType()->getParamType(0);
9918 // Load A
9919 for (unsigned i = 0; i < 8; ++i) {
9920 Value *V = Builder.CreateAlignedLoad(
9921 Builder.CreateGEP(SrcA.getPointer(),
9922 llvm::ConstantInt::get(IntTy, i)),
9923 CharUnits::fromQuantity(4));
9924 Values.push_back(Builder.CreateBitCast(V, ABType));
9925 }
9926 // Load B
9927 for (unsigned i = 0; i < 8; ++i) {
9928 Value *V = Builder.CreateAlignedLoad(
9929 Builder.CreateGEP(SrcB.getPointer(),
9930 llvm::ConstantInt::get(IntTy, i)),
9931 CharUnits::fromQuantity(4));
9932 Values.push_back(Builder.CreateBitCast(V, ABType));
9933 }
9934 // Load C
9935 llvm::Type *CType = Intrinsic->getFunctionType()->getParamType(16);
9936 for (unsigned i = 0; i < NumEltsC; ++i) {
9937 Value *V = Builder.CreateAlignedLoad(
9938 Builder.CreateGEP(SrcC.getPointer(),
9939 llvm::ConstantInt::get(IntTy, i)),
9940 CharUnits::fromQuantity(4));
9941 Values.push_back(Builder.CreateBitCast(V, CType));
9942 }
9943 Value *Result = Builder.CreateCall(Intrinsic, Values);
9944 llvm::Type *DType = Dst.getElementType();
9945 for (unsigned i = 0; i < NumEltsD; ++i)
9946 Builder.CreateAlignedStore(
9947 Builder.CreateBitCast(Builder.CreateExtractValue(Result, i), DType),
9948 Builder.CreateGEP(Dst.getPointer(), llvm::ConstantInt::get(IntTy, i)),
9949 CharUnits::fromQuantity(4));
9950 return Result;
9951 }
Artem Belevichd21e5c62015-06-25 18:29:42 +00009952 default:
9953 return nullptr;
9954 }
9955}
Dan Gohmanc2853072015-09-03 22:51:53 +00009956
9957Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
9958 const CallExpr *E) {
9959 switch (BuiltinID) {
Derek Schuffdbd24b42016-05-02 17:26:19 +00009960 case WebAssembly::BI__builtin_wasm_current_memory: {
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009961 llvm::Type *ResultType = ConvertType(E->getType());
Derek Schuffdbd24b42016-05-02 17:26:19 +00009962 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_current_memory, ResultType);
Dan Gohmand4c5fb52015-10-02 19:38:47 +00009963 return Builder.CreateCall(Callee);
9964 }
Dan Gohman24f0a082015-11-05 20:16:37 +00009965 case WebAssembly::BI__builtin_wasm_grow_memory: {
Dan Gohman266b38a2015-10-02 20:20:01 +00009966 Value *X = EmitScalarExpr(E->getArg(0));
Dan Gohman24f0a082015-11-05 20:16:37 +00009967 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_grow_memory, X->getType());
Dan Gohman266b38a2015-10-02 20:20:01 +00009968 return Builder.CreateCall(Callee, X);
9969 }
Heejin Ahnb92440e2017-06-30 00:44:01 +00009970 case WebAssembly::BI__builtin_wasm_throw: {
9971 Value *Tag = EmitScalarExpr(E->getArg(0));
9972 Value *Obj = EmitScalarExpr(E->getArg(1));
9973 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_throw);
9974 return Builder.CreateCall(Callee, {Tag, Obj});
9975 }
Heejin Ahnb29a17b2017-09-16 01:07:43 +00009976 case WebAssembly::BI__builtin_wasm_rethrow: {
9977 Value *Callee = CGM.getIntrinsic(Intrinsic::wasm_rethrow);
9978 return Builder.CreateCall(Callee);
9979 }
Dan Gohmanc2853072015-09-03 22:51:53 +00009980
9981 default:
9982 return nullptr;
9983 }
9984}