clang 24.0.0git
X86.cpp
Go to the documentation of this file.
1//===---------- X86.cpp - Emit LLVM Code for builtins ---------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code to emit Builtin calls as LLVM code.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CGBuiltin.h"
16#include "llvm/IR/InlineAsm.h"
17#include "llvm/IR/IntrinsicsX86.h"
18#include "llvm/TargetParser/X86TargetParser.h"
19
20using namespace clang;
21using namespace CodeGen;
22using namespace llvm;
23
24// Convert the mask from an integer type to a vector of i1.
26 unsigned NumElts) {
27
28 auto *MaskTy = llvm::FixedVectorType::get(
29 CGF.Builder.getInt1Ty(),
30 cast<IntegerType>(Mask->getType())->getBitWidth());
31 Value *MaskVec = CGF.Builder.CreateBitCast(Mask, MaskTy);
32
33 // If we have less than 8 elements, then the starting mask was an i8 and
34 // we need to extract down to the right number of elements.
35 if (NumElts < 8) {
36 int Indices[4];
37 for (unsigned i = 0; i != NumElts; ++i)
38 Indices[i] = i;
39 MaskVec = CGF.Builder.CreateShuffleVector(
40 MaskVec, MaskVec, ArrayRef(Indices, NumElts), "extract");
41 }
42 return MaskVec;
43}
44
45/// Emit rounding for the value \p X according to the rounding \p
46/// RoundingControl based on bits 0 and 1.
48 unsigned RoundingControl) {
49 unsigned RoundingMask = 0b11;
50 unsigned RoundingMode = RoundingControl & RoundingMask;
51
52 Intrinsic::ID ID = Intrinsic::not_intrinsic;
53 LLVMContext &Ctx = CGF.CGM.getLLVMContext();
54 if (CGF.Builder.getIsFPConstrained()) {
55
56 Value *ExceptMode =
57 MetadataAsValue::get(Ctx, MDString::get(Ctx, "fpexcept.ignore"));
58
59 switch (RoundingMode) {
60 case 0b00:
61 ID = Intrinsic::experimental_constrained_roundeven;
62 break;
63 case 0b01:
64 ID = Intrinsic::experimental_constrained_floor;
65 break;
66 case 0b10:
67 ID = Intrinsic::experimental_constrained_ceil;
68 break;
69 case 0b11:
70 ID = Intrinsic::experimental_constrained_trunc;
71 break;
72 default:
73 llvm_unreachable("Invalid rounding mode");
74 }
75
76 Function *F = CGF.CGM.getIntrinsic(ID, X->getType());
77 return CGF.Builder.CreateCall(F, {X, ExceptMode});
78 }
79
80 switch (RoundingMode) {
81 case 0b00:
82 ID = Intrinsic::roundeven;
83 break;
84 case 0b01:
85 ID = Intrinsic::floor;
86 break;
87 case 0b10:
88 ID = Intrinsic::ceil;
89 break;
90 case 0b11:
91 ID = Intrinsic::trunc;
92 break;
93 default:
94 llvm_unreachable("Invalid rounding mode");
95 }
96
97 Function *F = CGF.CGM.getIntrinsic(ID, X->getType());
98 return CGF.Builder.CreateCall(F, {X});
99}
100
102 Align Alignment) {
103 Value *Ptr = Ops[0];
104
105 Value *MaskVec = getMaskVecValue(
106 CGF, Ops[2],
107 cast<llvm::FixedVectorType>(Ops[1]->getType())->getNumElements());
108
109 return CGF.Builder.CreateMaskedStore(Ops[1], Ptr, Alignment, MaskVec);
110}
111
113 Align Alignment) {
114 llvm::Type *Ty = Ops[1]->getType();
115 Value *Ptr = Ops[0];
116
117 Value *MaskVec = getMaskVecValue(
118 CGF, Ops[2], cast<llvm::FixedVectorType>(Ty)->getNumElements());
119
120 return CGF.Builder.CreateMaskedLoad(Ty, Ptr, Alignment, MaskVec, Ops[1]);
121}
122
124 ArrayRef<Value *> Ops) {
125 auto *ResultTy = cast<llvm::VectorType>(Ops[1]->getType());
126 Value *Ptr = Ops[0];
127
128 Value *MaskVec = getMaskVecValue(
129 CGF, Ops[2], cast<FixedVectorType>(ResultTy)->getNumElements());
130
131 return CGF.Builder.CreateMaskedExpandLoad(ResultTy, Ptr, MaybeAlign(),
132 MaskVec, Ops[1]);
133}
134
137 bool IsCompress) {
138 auto *ResultTy = cast<llvm::FixedVectorType>(Ops[1]->getType());
139
140 Value *MaskVec = getMaskVecValue(CGF, Ops[2], ResultTy->getNumElements());
141
142 Intrinsic::ID IID = IsCompress ? Intrinsic::x86_avx512_mask_compress
143 : Intrinsic::x86_avx512_mask_expand;
144 llvm::Function *F = CGF.CGM.getIntrinsic(IID, ResultTy);
145 return CGF.Builder.CreateCall(F, { Ops[0], Ops[1], MaskVec });
146}
147
149 ArrayRef<Value *> Ops) {
150 auto *ResultTy = cast<llvm::FixedVectorType>(Ops[1]->getType());
151 Value *Ptr = Ops[0];
152
153 Value *MaskVec = getMaskVecValue(CGF, Ops[2], ResultTy->getNumElements());
154
155 return CGF.Builder.CreateMaskedCompressStore(Ops[1], Ptr, MaybeAlign(),
156 MaskVec);
157}
158
159static Value *EmitX86MaskLogic(CodeGenFunction &CGF, Instruction::BinaryOps Opc,
161 bool InvertLHS = false) {
162 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
163 Value *LHS = getMaskVecValue(CGF, Ops[0], NumElts);
164 Value *RHS = getMaskVecValue(CGF, Ops[1], NumElts);
165
166 if (InvertLHS)
167 LHS = CGF.Builder.CreateNot(LHS);
168
169 return CGF.Builder.CreateBitCast(CGF.Builder.CreateBinOp(Opc, LHS, RHS),
170 Ops[0]->getType());
171}
172
174 Value *Amt, bool IsRight) {
175 llvm::Type *Ty = Op0->getType();
176
177 // Amount may be scalar immediate, in which case create a splat vector.
178 // Funnel shifts amounts are treated as modulo and types are all power-of-2 so
179 // we only care about the lowest log2 bits anyway.
180 if (Amt->getType() != Ty) {
181 unsigned NumElts = cast<llvm::FixedVectorType>(Ty)->getNumElements();
182 Amt = CGF.Builder.CreateIntCast(Amt, Ty->getScalarType(), false);
183 Amt = CGF.Builder.CreateVectorSplat(NumElts, Amt);
184 }
185
186 unsigned IID = IsRight ? Intrinsic::fshr : Intrinsic::fshl;
187 Function *F = CGF.CGM.getIntrinsic(IID, Ty);
188 return CGF.Builder.CreateCall(F, {Op0, Op1, Amt});
189}
190
192 bool IsSigned) {
193 Value *Op0 = Ops[0];
194 Value *Op1 = Ops[1];
195 llvm::Type *Ty = Op0->getType();
196 uint64_t Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
197
198 CmpInst::Predicate Pred;
199 switch (Imm) {
200 case 0x0:
201 Pred = IsSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
202 break;
203 case 0x1:
204 Pred = IsSigned ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE;
205 break;
206 case 0x2:
207 Pred = IsSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
208 break;
209 case 0x3:
210 Pred = IsSigned ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE;
211 break;
212 case 0x4:
213 Pred = ICmpInst::ICMP_EQ;
214 break;
215 case 0x5:
216 Pred = ICmpInst::ICMP_NE;
217 break;
218 case 0x6:
219 return llvm::Constant::getNullValue(Ty); // FALSE
220 case 0x7:
221 return llvm::Constant::getAllOnesValue(Ty); // TRUE
222 default:
223 llvm_unreachable("Unexpected XOP vpcom/vpcomu predicate");
224 }
225
226 Value *Cmp = CGF.Builder.CreateICmp(Pred, Op0, Op1);
227 Value *Res = CGF.Builder.CreateSExt(Cmp, Ty);
228 return Res;
229}
230
232 Value *Mask, Value *Op0, Value *Op1) {
233
234 // If the mask is all ones just return first argument.
235 if (const auto *C = dyn_cast<Constant>(Mask))
236 if (C->isAllOnesValue())
237 return Op0;
238
239 Mask = getMaskVecValue(
240 CGF, Mask, cast<llvm::FixedVectorType>(Op0->getType())->getNumElements());
241
242 return CGF.Builder.CreateSelect(Mask, Op0, Op1);
243}
244
246 Value *Mask, Value *Op0, Value *Op1) {
247 // If the mask is all ones just return first argument.
248 if (const auto *C = dyn_cast<Constant>(Mask))
249 if (C->isAllOnesValue())
250 return Op0;
251
252 auto *MaskTy = llvm::FixedVectorType::get(
253 CGF.Builder.getInt1Ty(), Mask->getType()->getIntegerBitWidth());
254 Mask = CGF.Builder.CreateBitCast(Mask, MaskTy);
255 Mask = CGF.Builder.CreateExtractElement(Mask, (uint64_t)0);
256 return CGF.Builder.CreateSelect(Mask, Op0, Op1);
257}
258
260 unsigned NumElts, Value *MaskIn) {
261 if (MaskIn) {
262 const auto *C = dyn_cast<Constant>(MaskIn);
263 if (!C || !C->isAllOnesValue())
264 Cmp = CGF.Builder.CreateAnd(Cmp, getMaskVecValue(CGF, MaskIn, NumElts));
265 }
266
267 if (NumElts < 8) {
268 int Indices[8];
269 for (unsigned i = 0; i != NumElts; ++i)
270 Indices[i] = i;
271 for (unsigned i = NumElts; i != 8; ++i)
272 Indices[i] = i % NumElts + NumElts;
273 Cmp = CGF.Builder.CreateShuffleVector(
274 Cmp, llvm::Constant::getNullValue(Cmp->getType()), Indices);
275 }
276
277 return CGF.Builder.CreateBitCast(Cmp,
278 IntegerType::get(CGF.getLLVMContext(),
279 std::max(NumElts, 8U)));
280}
281
283 bool Signed, ArrayRef<Value *> Ops) {
284 assert((Ops.size() == 2 || Ops.size() == 4) &&
285 "Unexpected number of arguments");
286 unsigned NumElts =
287 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
288 Value *Cmp;
289
290 if (CC == 3) {
291 Cmp = Constant::getNullValue(
292 llvm::FixedVectorType::get(CGF.Builder.getInt1Ty(), NumElts));
293 } else if (CC == 7) {
294 Cmp = Constant::getAllOnesValue(
295 llvm::FixedVectorType::get(CGF.Builder.getInt1Ty(), NumElts));
296 } else {
297 ICmpInst::Predicate Pred;
298 switch (CC) {
299 default: llvm_unreachable("Unknown condition code");
300 case 0: Pred = ICmpInst::ICMP_EQ; break;
301 case 1: Pred = Signed ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
302 case 2: Pred = Signed ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
303 case 4: Pred = ICmpInst::ICMP_NE; break;
304 case 5: Pred = Signed ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
305 case 6: Pred = Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
306 }
307 Cmp = CGF.Builder.CreateICmp(Pred, Ops[0], Ops[1]);
308 }
309
310 Value *MaskIn = nullptr;
311 if (Ops.size() == 4)
312 MaskIn = Ops[3];
313
314 return EmitX86MaskedCompareResult(CGF, Cmp, NumElts, MaskIn);
315}
316
318 Value *Zero = Constant::getNullValue(In->getType());
319 return EmitX86MaskedCompare(CGF, 1, true, { In, Zero });
320}
321
323 ArrayRef<Value *> Ops, bool IsSigned) {
324 unsigned Rnd = cast<llvm::ConstantInt>(Ops[3])->getZExtValue();
325 llvm::Type *Ty = Ops[1]->getType();
326
327 Value *Res;
328 if (Rnd != 4) {
329 Intrinsic::ID IID = IsSigned ? Intrinsic::x86_avx512_sitofp_round
330 : Intrinsic::x86_avx512_uitofp_round;
331 Function *F = CGF.CGM.getIntrinsic(IID, { Ty, Ops[0]->getType() });
332 Res = CGF.Builder.CreateCall(F, { Ops[0], Ops[3] });
333 } else {
334 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
335 Res = IsSigned ? CGF.Builder.CreateSIToFP(Ops[0], Ty)
336 : CGF.Builder.CreateUIToFP(Ops[0], Ty);
337 }
338
339 return EmitX86Select(CGF, Ops[2], Res, Ops[1]);
340}
341
342// Lowers X86 FMA intrinsics to IR.
344 ArrayRef<Value *> Ops, unsigned BuiltinID,
345 bool IsAddSub) {
346
347 bool Subtract = false;
348 Intrinsic::ID IID = Intrinsic::not_intrinsic;
349 switch (BuiltinID) {
350 default: break;
351 case clang::X86::BI__builtin_ia32_vfmsubph512_mask3:
352 Subtract = true;
353 [[fallthrough]];
354 case clang::X86::BI__builtin_ia32_vfmaddph512_mask:
355 case clang::X86::BI__builtin_ia32_vfmaddph512_maskz:
356 case clang::X86::BI__builtin_ia32_vfmaddph512_mask3:
357 IID = Intrinsic::x86_avx512fp16_vfmadd_ph_512;
358 break;
359 case clang::X86::BI__builtin_ia32_vfmsubaddph512_mask3:
360 Subtract = true;
361 [[fallthrough]];
362 case clang::X86::BI__builtin_ia32_vfmaddsubph512_mask:
363 case clang::X86::BI__builtin_ia32_vfmaddsubph512_maskz:
364 case clang::X86::BI__builtin_ia32_vfmaddsubph512_mask3:
365 IID = Intrinsic::x86_avx512fp16_vfmaddsub_ph_512;
366 break;
367 case clang::X86::BI__builtin_ia32_vfmsubps512_mask3:
368 Subtract = true;
369 [[fallthrough]];
370 case clang::X86::BI__builtin_ia32_vfmaddps512_mask:
371 case clang::X86::BI__builtin_ia32_vfmaddps512_maskz:
372 case clang::X86::BI__builtin_ia32_vfmaddps512_mask3:
373 IID = Intrinsic::x86_avx512_vfmadd_ps_512; break;
374 case clang::X86::BI__builtin_ia32_vfmsubpd512_mask3:
375 Subtract = true;
376 [[fallthrough]];
377 case clang::X86::BI__builtin_ia32_vfmaddpd512_mask:
378 case clang::X86::BI__builtin_ia32_vfmaddpd512_maskz:
379 case clang::X86::BI__builtin_ia32_vfmaddpd512_mask3:
380 IID = Intrinsic::x86_avx512_vfmadd_pd_512; break;
381 case clang::X86::BI__builtin_ia32_vfmsubaddps512_mask3:
382 Subtract = true;
383 [[fallthrough]];
384 case clang::X86::BI__builtin_ia32_vfmaddsubps512_mask:
385 case clang::X86::BI__builtin_ia32_vfmaddsubps512_maskz:
386 case clang::X86::BI__builtin_ia32_vfmaddsubps512_mask3:
387 IID = Intrinsic::x86_avx512_vfmaddsub_ps_512;
388 break;
389 case clang::X86::BI__builtin_ia32_vfmsubaddpd512_mask3:
390 Subtract = true;
391 [[fallthrough]];
392 case clang::X86::BI__builtin_ia32_vfmaddsubpd512_mask:
393 case clang::X86::BI__builtin_ia32_vfmaddsubpd512_maskz:
394 case clang::X86::BI__builtin_ia32_vfmaddsubpd512_mask3:
395 IID = Intrinsic::x86_avx512_vfmaddsub_pd_512;
396 break;
397 }
398
399 Value *A = Ops[0];
400 Value *B = Ops[1];
401 Value *C = Ops[2];
402
403 if (Subtract)
404 C = CGF.Builder.CreateFNeg(C);
405
406 Value *Res;
407
408 // Only handle in case of _MM_FROUND_CUR_DIRECTION/4 (no rounding).
409 if (IID != Intrinsic::not_intrinsic &&
410 (cast<llvm::ConstantInt>(Ops.back())->getZExtValue() != (uint64_t)4 ||
411 IsAddSub)) {
412 Function *Intr = CGF.CGM.getIntrinsic(IID);
413 Res = CGF.Builder.CreateCall(Intr, {A, B, C, Ops.back() });
414 } else {
415 llvm::Type *Ty = A->getType();
416 Function *FMA;
417 if (CGF.Builder.getIsFPConstrained()) {
418 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
419 FMA = CGF.CGM.getIntrinsic(Intrinsic::experimental_constrained_fma, Ty);
420 Res = CGF.Builder.CreateConstrainedFPCall(FMA, {A, B, C});
421 } else {
422 FMA = CGF.CGM.getIntrinsic(Intrinsic::fma, Ty);
423 Res = CGF.Builder.CreateCall(FMA, {A, B, C});
424 }
425 }
426
427 // Handle any required masking.
428 Value *MaskFalseVal = nullptr;
429 switch (BuiltinID) {
430 case clang::X86::BI__builtin_ia32_vfmaddph512_mask:
431 case clang::X86::BI__builtin_ia32_vfmaddps512_mask:
432 case clang::X86::BI__builtin_ia32_vfmaddpd512_mask:
433 case clang::X86::BI__builtin_ia32_vfmaddsubph512_mask:
434 case clang::X86::BI__builtin_ia32_vfmaddsubps512_mask:
435 case clang::X86::BI__builtin_ia32_vfmaddsubpd512_mask:
436 MaskFalseVal = Ops[0];
437 break;
438 case clang::X86::BI__builtin_ia32_vfmaddph512_maskz:
439 case clang::X86::BI__builtin_ia32_vfmaddps512_maskz:
440 case clang::X86::BI__builtin_ia32_vfmaddpd512_maskz:
441 case clang::X86::BI__builtin_ia32_vfmaddsubph512_maskz:
442 case clang::X86::BI__builtin_ia32_vfmaddsubps512_maskz:
443 case clang::X86::BI__builtin_ia32_vfmaddsubpd512_maskz:
444 MaskFalseVal = Constant::getNullValue(Ops[0]->getType());
445 break;
446 case clang::X86::BI__builtin_ia32_vfmsubph512_mask3:
447 case clang::X86::BI__builtin_ia32_vfmaddph512_mask3:
448 case clang::X86::BI__builtin_ia32_vfmsubps512_mask3:
449 case clang::X86::BI__builtin_ia32_vfmaddps512_mask3:
450 case clang::X86::BI__builtin_ia32_vfmsubpd512_mask3:
451 case clang::X86::BI__builtin_ia32_vfmaddpd512_mask3:
452 case clang::X86::BI__builtin_ia32_vfmsubaddph512_mask3:
453 case clang::X86::BI__builtin_ia32_vfmaddsubph512_mask3:
454 case clang::X86::BI__builtin_ia32_vfmsubaddps512_mask3:
455 case clang::X86::BI__builtin_ia32_vfmaddsubps512_mask3:
456 case clang::X86::BI__builtin_ia32_vfmsubaddpd512_mask3:
457 case clang::X86::BI__builtin_ia32_vfmaddsubpd512_mask3:
458 MaskFalseVal = Ops[2];
459 break;
460 }
461
462 if (MaskFalseVal)
463 return EmitX86Select(CGF, Ops[3], Res, MaskFalseVal);
464
465 return Res;
466}
467
470 bool ZeroMask = false, unsigned PTIdx = 0,
471 bool NegAcc = false) {
472 unsigned Rnd = 4;
473 if (Ops.size() > 4)
474 Rnd = cast<llvm::ConstantInt>(Ops[4])->getZExtValue();
475
476 if (NegAcc)
477 Ops[2] = CGF.Builder.CreateFNeg(Ops[2]);
478
479 Ops[0] = CGF.Builder.CreateExtractElement(Ops[0], (uint64_t)0);
480 Ops[1] = CGF.Builder.CreateExtractElement(Ops[1], (uint64_t)0);
481 Ops[2] = CGF.Builder.CreateExtractElement(Ops[2], (uint64_t)0);
482 Value *Res;
483 if (Rnd != 4) {
484 Intrinsic::ID IID;
485
486 switch (Ops[0]->getType()->getPrimitiveSizeInBits()) {
487 case 16:
488 IID = Intrinsic::x86_avx512fp16_vfmadd_f16;
489 break;
490 case 32:
491 IID = Intrinsic::x86_avx512_vfmadd_f32;
492 break;
493 case 64:
494 IID = Intrinsic::x86_avx512_vfmadd_f64;
495 break;
496 default:
497 llvm_unreachable("Unexpected size");
498 }
499 Res = CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(IID),
500 {Ops[0], Ops[1], Ops[2], Ops[4]});
501 } else if (CGF.Builder.getIsFPConstrained()) {
502 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E);
503 Function *FMA = CGF.CGM.getIntrinsic(
504 Intrinsic::experimental_constrained_fma, Ops[0]->getType());
505 Res = CGF.Builder.CreateConstrainedFPCall(FMA, Ops.slice(0, 3));
506 } else {
507 Function *FMA = CGF.CGM.getIntrinsic(Intrinsic::fma, Ops[0]->getType());
508 Res = CGF.Builder.CreateCall(FMA, Ops.slice(0, 3));
509 }
510 // If we have more than 3 arguments, we need to do masking.
511 if (Ops.size() > 3) {
512 Value *PassThru = ZeroMask ? Constant::getNullValue(Res->getType())
513 : Ops[PTIdx];
514
515 // If we negated the accumulator and the its the PassThru value we need to
516 // bypass the negate. Conveniently Upper should be the same thing in this
517 // case.
518 if (NegAcc && PTIdx == 2)
519 PassThru = CGF.Builder.CreateExtractElement(Upper, (uint64_t)0);
520
521 Res = EmitX86ScalarSelect(CGF, Ops[3], Res, PassThru);
522 }
523 return CGF.Builder.CreateInsertElement(Upper, Res, (uint64_t)0);
524}
525
526static Value *EmitX86Muldq(CodeGenFunction &CGF, bool IsSigned,
527 ArrayRef<Value *> Ops) {
528 llvm::Type *Ty = Ops[0]->getType();
529 // Arguments have a vXi32 type so cast to vXi64.
530 Ty = llvm::FixedVectorType::get(CGF.Int64Ty,
531 Ty->getPrimitiveSizeInBits() / 64);
532 Value *LHS = CGF.Builder.CreateBitCast(Ops[0], Ty);
533 Value *RHS = CGF.Builder.CreateBitCast(Ops[1], Ty);
534
535 if (IsSigned) {
536 // Shift left then arithmetic shift right.
537 Constant *ShiftAmt = ConstantInt::get(Ty, 32);
538 LHS = CGF.Builder.CreateShl(LHS, ShiftAmt);
539 LHS = CGF.Builder.CreateAShr(LHS, ShiftAmt);
540 RHS = CGF.Builder.CreateShl(RHS, ShiftAmt);
541 RHS = CGF.Builder.CreateAShr(RHS, ShiftAmt);
542 } else {
543 // Clear the upper bits.
544 Constant *Mask = ConstantInt::get(Ty, 0xffffffff);
545 LHS = CGF.Builder.CreateAnd(LHS, Mask);
546 RHS = CGF.Builder.CreateAnd(RHS, Mask);
547 }
548
549 return CGF.Builder.CreateMul(LHS, RHS);
550}
551
552// Emit a masked pternlog intrinsic. This only exists because the header has to
553// use a macro and we aren't able to pass the input argument to a pternlog
554// builtin and a select builtin without evaluating it twice.
555static Value *EmitX86Ternlog(CodeGenFunction &CGF, bool ZeroMask,
556 ArrayRef<Value *> Ops) {
557 llvm::Type *Ty = Ops[0]->getType();
558
559 unsigned VecWidth = Ty->getPrimitiveSizeInBits();
560 unsigned EltWidth = Ty->getScalarSizeInBits();
561 Intrinsic::ID IID;
562 if (VecWidth == 128 && EltWidth == 32)
563 IID = Intrinsic::x86_avx512_pternlog_d_128;
564 else if (VecWidth == 256 && EltWidth == 32)
565 IID = Intrinsic::x86_avx512_pternlog_d_256;
566 else if (VecWidth == 512 && EltWidth == 32)
567 IID = Intrinsic::x86_avx512_pternlog_d_512;
568 else if (VecWidth == 128 && EltWidth == 64)
569 IID = Intrinsic::x86_avx512_pternlog_q_128;
570 else if (VecWidth == 256 && EltWidth == 64)
571 IID = Intrinsic::x86_avx512_pternlog_q_256;
572 else if (VecWidth == 512 && EltWidth == 64)
573 IID = Intrinsic::x86_avx512_pternlog_q_512;
574 else
575 llvm_unreachable("Unexpected intrinsic");
576
577 Value *Ternlog = CGF.Builder.CreateCall(CGF.CGM.getIntrinsic(IID),
578 Ops.drop_back());
579 Value *PassThru = ZeroMask ? ConstantAggregateZero::get(Ty) : Ops[0];
580 return EmitX86Select(CGF, Ops[4], Ternlog, PassThru);
581}
582
584 llvm::Type *DstTy) {
585 unsigned NumberOfElements =
586 cast<llvm::FixedVectorType>(DstTy)->getNumElements();
587 Value *Mask = getMaskVecValue(CGF, Op, NumberOfElements);
588 return CGF.Builder.CreateSExt(Mask, DstTy, "vpmovm2");
589}
590
591Value *CodeGenFunction::EmitX86CpuIs(const CallExpr *E) {
592 const Expr *CPUExpr = E->getArg(0)->IgnoreParenCasts();
593 StringRef CPUStr = cast<clang::StringLiteral>(CPUExpr)->getString();
594 return EmitX86CpuIs(CPUStr);
595}
596
597// Convert F16 halfs to floats.
600 llvm::Type *DstTy) {
601 assert((Ops.size() == 1 || Ops.size() == 3 || Ops.size() == 4) &&
602 "Unknown cvtph2ps intrinsic");
603
604 // If the SAE intrinsic doesn't use default rounding then we can't upgrade.
605 if (Ops.size() == 4 && cast<llvm::ConstantInt>(Ops[3])->getZExtValue() != 4) {
606 Function *F =
607 CGF.CGM.getIntrinsic(Intrinsic::x86_avx512_mask_vcvtph2ps_512);
608 return CGF.Builder.CreateCall(F, {Ops[0], Ops[1], Ops[2], Ops[3]});
609 }
610
611 unsigned NumDstElts = cast<llvm::FixedVectorType>(DstTy)->getNumElements();
612 Value *Src = Ops[0];
613
614 // Extract the subvector.
615 if (NumDstElts !=
616 cast<llvm::FixedVectorType>(Src->getType())->getNumElements()) {
617 assert(NumDstElts == 4 && "Unexpected vector size");
618 Src = CGF.Builder.CreateShuffleVector(Src, {0, 1, 2, 3});
619 }
620
621 // Bitcast from vXi16 to vXf16.
622 auto *HalfTy = llvm::FixedVectorType::get(
623 llvm::Type::getHalfTy(CGF.getLLVMContext()), NumDstElts);
624 Src = CGF.Builder.CreateBitCast(Src, HalfTy);
625
626 // Perform the fp-extension.
627 Value *Res = CGF.Builder.CreateFPExt(Src, DstTy, "cvtph2ps");
628
629 if (Ops.size() >= 3)
630 Res = EmitX86Select(CGF, Ops[2], Res, Ops[1]);
631 return Res;
632}
633
634Value *CodeGenFunction::EmitX86CpuIs(StringRef CPUStr) {
635
636 llvm::Type *Int32Ty = Builder.getInt32Ty();
637
638 // Matching the struct layout from the compiler-rt/libgcc structure that is
639 // filled in:
640 // unsigned int __cpu_vendor;
641 // unsigned int __cpu_type;
642 // unsigned int __cpu_subtype;
643 // unsigned int __cpu_features[1];
644 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
645 llvm::ArrayType::get(Int32Ty, 1));
646
647 // Grab the global __cpu_model.
648 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
649 cast<llvm::GlobalValue>(CpuModel)->setDSOLocal(true);
650
651 // Calculate the index needed to access the correct field based on the
652 // range. ABI_VALUE matches with compiler-rt/libgcc values.
653 auto [Index, Value] = StringSwitch<std::pair<unsigned, unsigned>>(CPUStr)
654#define X86_VENDOR(ENUM, STRING, ABI_VALUE) .Case(STRING, {0u, ABI_VALUE})
655#define X86_CPU_TYPE(ENUM, STR, ABI_VALUE) .Case(STR, {1u, ABI_VALUE})
656#define X86_CPU_SUBTYPE(ENUM, STR, ABI_VALUE) .Case(STR, {2u, ABI_VALUE})
657#include "llvm/TargetParser/X86TargetParser.def"
658 .Default({0, 0});
659 assert(Value != 0 && "Invalid CPUStr passed to CpuIs");
660
661 // Grab the appropriate field from __cpu_model.
662 llvm::Value *Idxs[] = {ConstantInt::get(Int32Ty, 0),
663 ConstantInt::get(Int32Ty, Index)};
664 llvm::Value *CpuValue = Builder.CreateInBoundsGEP(STy, CpuModel, Idxs);
665 CpuValue = Builder.CreateAlignedLoad(Int32Ty, CpuValue,
667
668 // Check the value of the field against the requested value.
669 return Builder.CreateICmpEQ(CpuValue,
670 llvm::ConstantInt::get(Int32Ty, Value));
671}
672
673Value *CodeGenFunction::EmitX86CpuSupports(const CallExpr *E) {
674 const Expr *FeatureExpr = E->getArg(0)->IgnoreParenCasts();
675 StringRef FeatureStr = cast<StringLiteral>(FeatureExpr)->getString();
676 if (!getContext().getTargetInfo().validateCpuSupports(FeatureStr))
677 return Builder.getFalse();
678 return EmitX86CpuSupports(FeatureStr);
679}
680
681Value *CodeGenFunction::EmitX86CpuSupports(ArrayRef<StringRef> FeatureStrs) {
682 return EmitX86CpuSupports(llvm::X86::getCpuSupportsMask(FeatureStrs));
683}
684
685llvm::Value *
686CodeGenFunction::EmitX86CpuSupports(std::array<uint32_t, 4> FeatureMask) {
687 Value *Result = Builder.getTrue();
688 if (FeatureMask[0] != 0) {
689 // Matching the struct layout from the compiler-rt/libgcc structure that is
690 // filled in:
691 // unsigned int __cpu_vendor;
692 // unsigned int __cpu_type;
693 // unsigned int __cpu_subtype;
694 // unsigned int __cpu_features[1];
695 llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
696 llvm::ArrayType::get(Int32Ty, 1));
697
698 // Grab the global __cpu_model.
699 llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
700 cast<llvm::GlobalValue>(CpuModel)->setDSOLocal(true);
701
702 // Grab the first (0th) element from the field __cpu_features off of the
703 // global in the struct STy.
704 Value *Idxs[] = {Builder.getInt32(0), Builder.getInt32(3),
705 Builder.getInt32(0)};
706 Value *CpuFeatures = Builder.CreateInBoundsGEP(STy, CpuModel, Idxs);
707 Value *Features = Builder.CreateAlignedLoad(Int32Ty, CpuFeatures,
709
710 // Check the value of the bit corresponding to the feature requested.
711 Value *Mask = Builder.getInt32(FeatureMask[0]);
712 Value *Bitset = Builder.CreateAnd(Features, Mask);
713 Value *Cmp = Builder.CreateICmpEQ(Bitset, Mask);
714 Result = Builder.CreateAnd(Result, Cmp);
715 }
716
717 llvm::Type *ATy = llvm::ArrayType::get(Int32Ty, 3);
718 llvm::Constant *CpuFeatures2 =
719 CGM.CreateRuntimeVariable(ATy, "__cpu_features2");
720 cast<llvm::GlobalValue>(CpuFeatures2)->setDSOLocal(true);
721 for (int i = 1; i != 4; ++i) {
722 const uint32_t M = FeatureMask[i];
723 if (!M)
724 continue;
725 Value *Idxs[] = {Builder.getInt32(0), Builder.getInt32(i - 1)};
726 Value *Features = Builder.CreateAlignedLoad(
727 Int32Ty, Builder.CreateInBoundsGEP(ATy, CpuFeatures2, Idxs),
729 // Check the value of the bit corresponding to the feature requested.
730 Value *Mask = Builder.getInt32(M);
731 Value *Bitset = Builder.CreateAnd(Features, Mask);
732 Value *Cmp = Builder.CreateICmpEQ(Bitset, Mask);
733 Result = Builder.CreateAnd(Result, Cmp);
734 }
735
736 return Result;
737}
738
739Value *CodeGenFunction::EmitX86CpuInit() {
740 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy,
741 /*Variadic*/ false);
742 llvm::FunctionCallee Func =
743 CGM.CreateRuntimeFunction(FTy, "__cpu_indicator_init");
744 cast<llvm::GlobalValue>(Func.getCallee())->setDSOLocal(true);
745 cast<llvm::GlobalValue>(Func.getCallee())
746 ->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
747 return Builder.CreateCall(Func);
748}
749
750
752 const CallExpr *E) {
753 if (BuiltinID == Builtin::BI__builtin_cpu_is)
754 return EmitX86CpuIs(E);
755 if (BuiltinID == Builtin::BI__builtin_cpu_supports)
756 return EmitX86CpuSupports(E);
757 if (BuiltinID == Builtin::BI__builtin_cpu_init)
758 return EmitX86CpuInit();
759
760 // Handle MSVC intrinsics before argument evaluation to prevent double
761 // evaluation.
762 if (std::optional<CodeGenUtils::MSVCIntrin> MsvcIntId =
764 return EmitMSVCBuiltinExpr(*MsvcIntId, E);
765
767 bool IsMaskFCmp = false;
768 bool IsConjFMA = false;
769
770 // Find out if any arguments are required to be integer constant expressions.
771 unsigned ICEArguments = 0;
773 getContext().GetBuiltinType(BuiltinID, Error, &ICEArguments);
774 assert(Error == ASTContext::GE_None && "Should not codegen an error");
775
776 for (unsigned i = 0, e = E->getNumArgs(); i != e; i++) {
777 Ops.push_back(EmitScalarOrConstFoldImmArg(ICEArguments, i, E));
778 }
779
780 // These exist so that the builtin that takes an immediate can be bounds
781 // checked by clang to avoid passing bad immediates to the backend. Since
782 // AVX has a larger immediate than SSE we would need separate builtins to
783 // do the different bounds checking. Rather than create a clang specific
784 // SSE only builtin, this implements eight separate builtins to match gcc
785 // implementation.
786 auto getCmpIntrinsicCall = [this, &Ops](Intrinsic::ID ID, unsigned Imm) {
787 Ops.push_back(llvm::ConstantInt::get(Int8Ty, Imm));
788 llvm::Function *F = CGM.getIntrinsic(ID);
789 return Builder.CreateCall(F, Ops);
790 };
791
792 // For the vector forms of FP comparisons, translate the builtins directly to
793 // IR.
794 // TODO: The builtins could be removed if the SSE header files used vector
795 // extension comparisons directly (vector ordered/unordered may need
796 // additional support via __builtin_isnan()).
797 auto getVectorFCmpIR = [this, &Ops, E](CmpInst::Predicate Pred,
798 bool IsSignaling) {
799 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
800 Value *Cmp;
801 if (IsSignaling)
802 Cmp = Builder.CreateFCmpS(Pred, Ops[0], Ops[1]);
803 else
804 Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]);
805 llvm::VectorType *FPVecTy = cast<llvm::VectorType>(Ops[0]->getType());
806 llvm::VectorType *IntVecTy = llvm::VectorType::getInteger(FPVecTy);
807 Value *Sext = Builder.CreateSExt(Cmp, IntVecTy);
808 return Builder.CreateBitCast(Sext, FPVecTy);
809 };
810
811 switch (BuiltinID) {
812 default: return nullptr;
813 case X86::BI_mm_prefetch: {
814 Value *Address = Ops[0];
815 ConstantInt *C = cast<ConstantInt>(Ops[1]);
816 Value *RW = ConstantInt::get(Int32Ty, (C->getZExtValue() >> 2) & 0x1);
817 Value *Locality = ConstantInt::get(Int32Ty, C->getZExtValue() & 0x3);
818 Value *Data = ConstantInt::get(Int32Ty, 1);
819 Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
820 return Builder.CreateCall(F, {Address, RW, Locality, Data});
821 }
822 case X86::BI_m_prefetch:
823 case X86::BI_m_prefetchw: {
824 Value *Address = Ops[0];
825 // The 'w' suffix implies write.
826 Value *RW =
827 ConstantInt::get(Int32Ty, BuiltinID == X86::BI_m_prefetchw ? 1 : 0);
828 Value *Locality = ConstantInt::get(Int32Ty, 0x3);
829 Value *Data = ConstantInt::get(Int32Ty, 1);
830 Function *F = CGM.getIntrinsic(Intrinsic::prefetch, Address->getType());
831 return Builder.CreateCall(F, {Address, RW, Locality, Data});
832 }
833 case X86::BI_mm_clflush: {
834 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_clflush),
835 Ops[0]);
836 }
837 case X86::BI_mm_lfence: {
838 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_lfence));
839 }
840 case X86::BI_mm_mfence: {
841 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_mfence));
842 }
843 case X86::BI_mm_sfence: {
844 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_sfence));
845 }
846 case X86::BI_mm_pause: {
847 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse2_pause));
848 }
849 case X86::BI__rdtsc: {
850 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtsc));
851 }
852 case X86::BI__builtin_ia32_rdtscp: {
853 Value *Call = Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_rdtscp));
854 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 1),
855 Ops[0]);
856 return Builder.CreateExtractValue(Call, 0);
857 }
858 case X86::BI__builtin_ia32_roundps:
859 case X86::BI__builtin_ia32_roundpd:
860 case X86::BI__builtin_ia32_roundps256:
861 case X86::BI__builtin_ia32_roundpd256: {
862 unsigned M = cast<ConstantInt>(Ops[1])->getZExtValue();
863 unsigned MXCSRMask = 0b100;
864 unsigned FRoundNoExcMask = 0b1000;
865 unsigned UseMXCSR = MXCSRMask & M;
866 unsigned FRoundNoExc = FRoundNoExcMask & M;
867
868 if (UseMXCSR || !FRoundNoExc) {
869
870 Intrinsic::ID ID = Intrinsic::not_intrinsic;
871
872 switch (BuiltinID) {
873 case X86::BI__builtin_ia32_roundps:
874 ID = Intrinsic::x86_sse41_round_ps;
875 break;
876 case X86::BI__builtin_ia32_roundps256:
877 ID = Intrinsic::x86_avx_round_ps_256;
878 break;
879 case X86::BI__builtin_ia32_roundpd:
880 ID = Intrinsic::x86_sse41_round_pd;
881 break;
882 case X86::BI__builtin_ia32_roundpd256:
883 ID = Intrinsic::x86_avx_round_pd_256;
884 break;
885 default:
886 llvm_unreachable("must return from switch");
887 }
888
889 Function *F = CGM.getIntrinsic(ID);
890 return Builder.CreateCall(F, Ops);
891 }
892
893 return emitX86RoundImmediate(*this, Ops[0], M);
894 }
895 case X86::BI__builtin_ia32_roundss:
896 case X86::BI__builtin_ia32_roundsd: {
897 unsigned M = cast<ConstantInt>(Ops[2])->getZExtValue();
898 unsigned MXCSRMask = 0b100;
899 unsigned FRoundNoExcMask = 0b1000;
900 unsigned UseMXCSR = MXCSRMask & M;
901 unsigned FRoundNoExc = FRoundNoExcMask & M;
902
903 if (UseMXCSR || !FRoundNoExc) {
904
905 Intrinsic::ID ID = Intrinsic::not_intrinsic;
906
907 switch (BuiltinID) {
908 case X86::BI__builtin_ia32_roundss:
909 ID = Intrinsic::x86_sse41_round_ss;
910 break;
911 case X86::BI__builtin_ia32_roundsd:
912 ID = Intrinsic::x86_sse41_round_sd;
913 break;
914 default:
915 llvm_unreachable("must return from switch");
916 }
917
918 Function *F = CGM.getIntrinsic(ID);
919 return Builder.CreateCall(F, Ops);
920 }
921
922 Value *Idx = Builder.getInt32(0);
923 Value *ValAt0 = Builder.CreateExtractElement(Ops[1], Idx);
924 Value *RoundedAt0 = emitX86RoundImmediate(*this, ValAt0, M);
925
926 return Builder.CreateInsertElement(Ops[0], RoundedAt0, Idx);
927 }
928 case X86::BI__builtin_ia32_lzcnt_u16:
929 case X86::BI__builtin_ia32_lzcnt_u32:
930 case X86::BI__builtin_ia32_lzcnt_u64: {
931 Function *F = CGM.getIntrinsic(Intrinsic::ctlz, Ops[0]->getType());
932 return Builder.CreateCall(F, {Ops[0], Builder.getInt1(false)});
933 }
934 case X86::BI__builtin_ia32_tzcnt_u16:
935 case X86::BI__builtin_ia32_tzcnt_u32:
936 case X86::BI__builtin_ia32_tzcnt_u64: {
937 Function *F = CGM.getIntrinsic(Intrinsic::cttz, Ops[0]->getType());
938 return Builder.CreateCall(F, {Ops[0], Builder.getInt1(false)});
939 }
940 case X86::BI__builtin_ia32_undef128:
941 case X86::BI__builtin_ia32_undef256:
942 case X86::BI__builtin_ia32_undef512:
943 // The x86 definition of "undef" is not the same as the LLVM definition
944 // (PR32176). We leave optimizing away an unnecessary zero constant to the
945 // IR optimizer and backend.
946 // TODO: If we had a "freeze" IR instruction to generate a fixed undef
947 // value, we should use that here instead of a zero.
948 return llvm::Constant::getNullValue(ConvertType(E->getType()));
949 case X86::BI__builtin_ia32_vec_ext_v4hi:
950 case X86::BI__builtin_ia32_vec_ext_v16qi:
951 case X86::BI__builtin_ia32_vec_ext_v8hi:
952 case X86::BI__builtin_ia32_vec_ext_v4si:
953 case X86::BI__builtin_ia32_vec_ext_v4sf:
954 case X86::BI__builtin_ia32_vec_ext_v2di:
955 case X86::BI__builtin_ia32_vec_ext_v32qi:
956 case X86::BI__builtin_ia32_vec_ext_v16hi:
957 case X86::BI__builtin_ia32_vec_ext_v8si:
958 case X86::BI__builtin_ia32_vec_ext_v4di: {
959 unsigned NumElts =
960 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
961 uint64_t Index = cast<ConstantInt>(Ops[1])->getZExtValue();
962 Index &= NumElts - 1;
963 // These builtins exist so we can ensure the index is an ICE and in range.
964 // Otherwise we could just do this in the header file.
965 return Builder.CreateExtractElement(Ops[0], Index);
966 }
967 case X86::BI__builtin_ia32_vec_set_v4hi:
968 case X86::BI__builtin_ia32_vec_set_v16qi:
969 case X86::BI__builtin_ia32_vec_set_v8hi:
970 case X86::BI__builtin_ia32_vec_set_v4si:
971 case X86::BI__builtin_ia32_vec_set_v2di:
972 case X86::BI__builtin_ia32_vec_set_v32qi:
973 case X86::BI__builtin_ia32_vec_set_v16hi:
974 case X86::BI__builtin_ia32_vec_set_v8si:
975 case X86::BI__builtin_ia32_vec_set_v4di: {
976 unsigned NumElts =
977 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
978 unsigned Index = cast<ConstantInt>(Ops[2])->getZExtValue();
979 Index &= NumElts - 1;
980 // These builtins exist so we can ensure the index is an ICE and in range.
981 // Otherwise we could just do this in the header file.
982 return Builder.CreateInsertElement(Ops[0], Ops[1], Index);
983 }
984 case X86::BI_mm_setcsr:
985 case X86::BI__builtin_ia32_ldmxcsr: {
987 Builder.CreateStore(Ops[0], Tmp);
988 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_ldmxcsr),
989 Tmp.getPointer());
990 }
991 case X86::BI_mm_getcsr:
992 case X86::BI__builtin_ia32_stmxcsr: {
994 Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_sse_stmxcsr),
995 Tmp.getPointer());
996 return Builder.CreateLoad(Tmp, "stmxcsr");
997 }
998 case X86::BI__builtin_ia32_xsave:
999 case X86::BI__builtin_ia32_xsave64:
1000 case X86::BI__builtin_ia32_xrstor:
1001 case X86::BI__builtin_ia32_xrstor64:
1002 case X86::BI__builtin_ia32_xsaveopt:
1003 case X86::BI__builtin_ia32_xsaveopt64:
1004 case X86::BI__builtin_ia32_xrstors:
1005 case X86::BI__builtin_ia32_xrstors64:
1006 case X86::BI__builtin_ia32_xsavec:
1007 case X86::BI__builtin_ia32_xsavec64:
1008 case X86::BI__builtin_ia32_xsaves:
1009 case X86::BI__builtin_ia32_xsaves64:
1010 case X86::BI__builtin_ia32_xsetbv:
1011 case X86::BI_xsetbv: {
1012 Intrinsic::ID ID;
1013#define INTRINSIC_X86_XSAVE_ID(NAME) \
1014 case X86::BI__builtin_ia32_##NAME: \
1015 ID = Intrinsic::x86_##NAME; \
1016 break
1017 switch (BuiltinID) {
1018 default: llvm_unreachable("Unsupported intrinsic!");
1020 INTRINSIC_X86_XSAVE_ID(xsave64);
1021 INTRINSIC_X86_XSAVE_ID(xrstor);
1022 INTRINSIC_X86_XSAVE_ID(xrstor64);
1023 INTRINSIC_X86_XSAVE_ID(xsaveopt);
1024 INTRINSIC_X86_XSAVE_ID(xsaveopt64);
1025 INTRINSIC_X86_XSAVE_ID(xrstors);
1026 INTRINSIC_X86_XSAVE_ID(xrstors64);
1027 INTRINSIC_X86_XSAVE_ID(xsavec);
1028 INTRINSIC_X86_XSAVE_ID(xsavec64);
1029 INTRINSIC_X86_XSAVE_ID(xsaves);
1030 INTRINSIC_X86_XSAVE_ID(xsaves64);
1031 INTRINSIC_X86_XSAVE_ID(xsetbv);
1032 case X86::BI_xsetbv:
1033 ID = Intrinsic::x86_xsetbv;
1034 break;
1035 }
1036#undef INTRINSIC_X86_XSAVE_ID
1037 Value *Mhi = Builder.CreateTrunc(
1038 Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty);
1039 Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty);
1040 Ops[1] = Mhi;
1041 Ops.push_back(Mlo);
1042 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
1043 }
1044 case X86::BI__builtin_ia32_xgetbv:
1045 case X86::BI_xgetbv:
1046 return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::x86_xgetbv), Ops);
1047 case X86::BI__builtin_ia32_storedqudi128_mask:
1048 case X86::BI__builtin_ia32_storedqusi128_mask:
1049 case X86::BI__builtin_ia32_storedquhi128_mask:
1050 case X86::BI__builtin_ia32_storedquqi128_mask:
1051 case X86::BI__builtin_ia32_storeupd128_mask:
1052 case X86::BI__builtin_ia32_storeups128_mask:
1053 case X86::BI__builtin_ia32_storedqudi256_mask:
1054 case X86::BI__builtin_ia32_storedqusi256_mask:
1055 case X86::BI__builtin_ia32_storedquhi256_mask:
1056 case X86::BI__builtin_ia32_storedquqi256_mask:
1057 case X86::BI__builtin_ia32_storeupd256_mask:
1058 case X86::BI__builtin_ia32_storeups256_mask:
1059 case X86::BI__builtin_ia32_storedqudi512_mask:
1060 case X86::BI__builtin_ia32_storedqusi512_mask:
1061 case X86::BI__builtin_ia32_storedquhi512_mask:
1062 case X86::BI__builtin_ia32_storedquqi512_mask:
1063 case X86::BI__builtin_ia32_storeupd512_mask:
1064 case X86::BI__builtin_ia32_storeups512_mask:
1065 return EmitX86MaskedStore(*this, Ops, Align(1));
1066
1067 case X86::BI__builtin_ia32_storesbf16128_mask:
1068 case X86::BI__builtin_ia32_storesh128_mask:
1069 case X86::BI__builtin_ia32_storess128_mask:
1070 case X86::BI__builtin_ia32_storesd128_mask:
1071 return EmitX86MaskedStore(*this, Ops, Align(1));
1072
1073 case X86::BI__builtin_ia32_cvtmask2b128:
1074 case X86::BI__builtin_ia32_cvtmask2b256:
1075 case X86::BI__builtin_ia32_cvtmask2b512:
1076 case X86::BI__builtin_ia32_cvtmask2w128:
1077 case X86::BI__builtin_ia32_cvtmask2w256:
1078 case X86::BI__builtin_ia32_cvtmask2w512:
1079 case X86::BI__builtin_ia32_cvtmask2d128:
1080 case X86::BI__builtin_ia32_cvtmask2d256:
1081 case X86::BI__builtin_ia32_cvtmask2d512:
1082 case X86::BI__builtin_ia32_cvtmask2q128:
1083 case X86::BI__builtin_ia32_cvtmask2q256:
1084 case X86::BI__builtin_ia32_cvtmask2q512:
1085 return EmitX86SExtMask(*this, Ops[0], ConvertType(E->getType()));
1086
1087 case X86::BI__builtin_ia32_cvtb2mask128:
1088 case X86::BI__builtin_ia32_cvtb2mask256:
1089 case X86::BI__builtin_ia32_cvtb2mask512:
1090 case X86::BI__builtin_ia32_cvtw2mask128:
1091 case X86::BI__builtin_ia32_cvtw2mask256:
1092 case X86::BI__builtin_ia32_cvtw2mask512:
1093 case X86::BI__builtin_ia32_cvtd2mask128:
1094 case X86::BI__builtin_ia32_cvtd2mask256:
1095 case X86::BI__builtin_ia32_cvtd2mask512:
1096 case X86::BI__builtin_ia32_cvtq2mask128:
1097 case X86::BI__builtin_ia32_cvtq2mask256:
1098 case X86::BI__builtin_ia32_cvtq2mask512:
1099 return EmitX86ConvertToMask(*this, Ops[0]);
1100
1101 case X86::BI__builtin_ia32_cvtdq2ps512_mask:
1102 case X86::BI__builtin_ia32_cvtqq2ps512_mask:
1103 case X86::BI__builtin_ia32_cvtqq2pd512_mask:
1104 case X86::BI__builtin_ia32_vcvtw2ph512_mask:
1105 case X86::BI__builtin_ia32_vcvtdq2ph512_mask:
1106 case X86::BI__builtin_ia32_vcvtqq2ph512_mask:
1107 return EmitX86ConvertIntToFp(*this, E, Ops, /*IsSigned*/ true);
1108 case X86::BI__builtin_ia32_cvtudq2ps512_mask:
1109 case X86::BI__builtin_ia32_cvtuqq2ps512_mask:
1110 case X86::BI__builtin_ia32_cvtuqq2pd512_mask:
1111 case X86::BI__builtin_ia32_vcvtuw2ph512_mask:
1112 case X86::BI__builtin_ia32_vcvtudq2ph512_mask:
1113 case X86::BI__builtin_ia32_vcvtuqq2ph512_mask:
1114 return EmitX86ConvertIntToFp(*this, E, Ops, /*IsSigned*/ false);
1115
1116 case X86::BI__builtin_ia32_vfmaddsh3_mask:
1117 case X86::BI__builtin_ia32_vfmaddss3_mask:
1118 case X86::BI__builtin_ia32_vfmaddsd3_mask:
1119 return EmitScalarFMAExpr(*this, E, Ops, Ops[0]);
1120 case X86::BI__builtin_ia32_vfmaddsh3_maskz:
1121 case X86::BI__builtin_ia32_vfmaddss3_maskz:
1122 case X86::BI__builtin_ia32_vfmaddsd3_maskz:
1123 return EmitScalarFMAExpr(*this, E, Ops, Ops[0], /*ZeroMask*/ true);
1124 case X86::BI__builtin_ia32_vfmaddsh3_mask3:
1125 case X86::BI__builtin_ia32_vfmaddss3_mask3:
1126 case X86::BI__builtin_ia32_vfmaddsd3_mask3:
1127 return EmitScalarFMAExpr(*this, E, Ops, Ops[2], /*ZeroMask*/ false, 2);
1128 case X86::BI__builtin_ia32_vfmsubsh3_mask3:
1129 case X86::BI__builtin_ia32_vfmsubss3_mask3:
1130 case X86::BI__builtin_ia32_vfmsubsd3_mask3:
1131 return EmitScalarFMAExpr(*this, E, Ops, Ops[2], /*ZeroMask*/ false, 2,
1132 /*NegAcc*/ true);
1133 case X86::BI__builtin_ia32_vfmaddph512_mask:
1134 case X86::BI__builtin_ia32_vfmaddph512_maskz:
1135 case X86::BI__builtin_ia32_vfmaddph512_mask3:
1136 case X86::BI__builtin_ia32_vfmaddps512_mask:
1137 case X86::BI__builtin_ia32_vfmaddps512_maskz:
1138 case X86::BI__builtin_ia32_vfmaddps512_mask3:
1139 case X86::BI__builtin_ia32_vfmsubps512_mask3:
1140 case X86::BI__builtin_ia32_vfmaddpd512_mask:
1141 case X86::BI__builtin_ia32_vfmaddpd512_maskz:
1142 case X86::BI__builtin_ia32_vfmaddpd512_mask3:
1143 case X86::BI__builtin_ia32_vfmsubpd512_mask3:
1144 case X86::BI__builtin_ia32_vfmsubph512_mask3:
1145 return EmitX86FMAExpr(*this, E, Ops, BuiltinID, /*IsAddSub*/ false);
1146 case X86::BI__builtin_ia32_vfmaddsubph512_mask:
1147 case X86::BI__builtin_ia32_vfmaddsubph512_maskz:
1148 case X86::BI__builtin_ia32_vfmaddsubph512_mask3:
1149 case X86::BI__builtin_ia32_vfmsubaddph512_mask3:
1150 case X86::BI__builtin_ia32_vfmaddsubps512_mask:
1151 case X86::BI__builtin_ia32_vfmaddsubps512_maskz:
1152 case X86::BI__builtin_ia32_vfmaddsubps512_mask3:
1153 case X86::BI__builtin_ia32_vfmsubaddps512_mask3:
1154 case X86::BI__builtin_ia32_vfmaddsubpd512_mask:
1155 case X86::BI__builtin_ia32_vfmaddsubpd512_maskz:
1156 case X86::BI__builtin_ia32_vfmaddsubpd512_mask3:
1157 case X86::BI__builtin_ia32_vfmsubaddpd512_mask3:
1158 return EmitX86FMAExpr(*this, E, Ops, BuiltinID, /*IsAddSub*/ true);
1159
1160 case X86::BI__builtin_ia32_movdqa32store128_mask:
1161 case X86::BI__builtin_ia32_movdqa64store128_mask:
1162 case X86::BI__builtin_ia32_storeaps128_mask:
1163 case X86::BI__builtin_ia32_storeapd128_mask:
1164 case X86::BI__builtin_ia32_movdqa32store256_mask:
1165 case X86::BI__builtin_ia32_movdqa64store256_mask:
1166 case X86::BI__builtin_ia32_storeaps256_mask:
1167 case X86::BI__builtin_ia32_storeapd256_mask:
1168 case X86::BI__builtin_ia32_movdqa32store512_mask:
1169 case X86::BI__builtin_ia32_movdqa64store512_mask:
1170 case X86::BI__builtin_ia32_storeaps512_mask:
1171 case X86::BI__builtin_ia32_storeapd512_mask:
1172 return EmitX86MaskedStore(
1173 *this, Ops,
1174 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getAsAlign());
1175
1176 case X86::BI__builtin_ia32_loadups128_mask:
1177 case X86::BI__builtin_ia32_loadups256_mask:
1178 case X86::BI__builtin_ia32_loadups512_mask:
1179 case X86::BI__builtin_ia32_loadupd128_mask:
1180 case X86::BI__builtin_ia32_loadupd256_mask:
1181 case X86::BI__builtin_ia32_loadupd512_mask:
1182 case X86::BI__builtin_ia32_loaddquqi128_mask:
1183 case X86::BI__builtin_ia32_loaddquqi256_mask:
1184 case X86::BI__builtin_ia32_loaddquqi512_mask:
1185 case X86::BI__builtin_ia32_loaddquhi128_mask:
1186 case X86::BI__builtin_ia32_loaddquhi256_mask:
1187 case X86::BI__builtin_ia32_loaddquhi512_mask:
1188 case X86::BI__builtin_ia32_loaddqusi128_mask:
1189 case X86::BI__builtin_ia32_loaddqusi256_mask:
1190 case X86::BI__builtin_ia32_loaddqusi512_mask:
1191 case X86::BI__builtin_ia32_loaddqudi128_mask:
1192 case X86::BI__builtin_ia32_loaddqudi256_mask:
1193 case X86::BI__builtin_ia32_loaddqudi512_mask:
1194 return EmitX86MaskedLoad(*this, Ops, Align(1));
1195
1196 case X86::BI__builtin_ia32_loadsbf16128_mask:
1197 case X86::BI__builtin_ia32_loadsh128_mask:
1198 case X86::BI__builtin_ia32_loadss128_mask:
1199 case X86::BI__builtin_ia32_loadsd128_mask:
1200 return EmitX86MaskedLoad(*this, Ops, Align(1));
1201
1202 case X86::BI__builtin_ia32_loadaps128_mask:
1203 case X86::BI__builtin_ia32_loadaps256_mask:
1204 case X86::BI__builtin_ia32_loadaps512_mask:
1205 case X86::BI__builtin_ia32_loadapd128_mask:
1206 case X86::BI__builtin_ia32_loadapd256_mask:
1207 case X86::BI__builtin_ia32_loadapd512_mask:
1208 case X86::BI__builtin_ia32_movdqa32load128_mask:
1209 case X86::BI__builtin_ia32_movdqa32load256_mask:
1210 case X86::BI__builtin_ia32_movdqa32load512_mask:
1211 case X86::BI__builtin_ia32_movdqa64load128_mask:
1212 case X86::BI__builtin_ia32_movdqa64load256_mask:
1213 case X86::BI__builtin_ia32_movdqa64load512_mask:
1214 return EmitX86MaskedLoad(
1215 *this, Ops,
1216 getContext().getTypeAlignInChars(E->getArg(1)->getType()).getAsAlign());
1217
1218 case X86::BI__builtin_ia32_expandloaddf128_mask:
1219 case X86::BI__builtin_ia32_expandloaddf256_mask:
1220 case X86::BI__builtin_ia32_expandloaddf512_mask:
1221 case X86::BI__builtin_ia32_expandloadsf128_mask:
1222 case X86::BI__builtin_ia32_expandloadsf256_mask:
1223 case X86::BI__builtin_ia32_expandloadsf512_mask:
1224 case X86::BI__builtin_ia32_expandloaddi128_mask:
1225 case X86::BI__builtin_ia32_expandloaddi256_mask:
1226 case X86::BI__builtin_ia32_expandloaddi512_mask:
1227 case X86::BI__builtin_ia32_expandloadsi128_mask:
1228 case X86::BI__builtin_ia32_expandloadsi256_mask:
1229 case X86::BI__builtin_ia32_expandloadsi512_mask:
1230 case X86::BI__builtin_ia32_expandloadhi128_mask:
1231 case X86::BI__builtin_ia32_expandloadhi256_mask:
1232 case X86::BI__builtin_ia32_expandloadhi512_mask:
1233 case X86::BI__builtin_ia32_expandloadqi128_mask:
1234 case X86::BI__builtin_ia32_expandloadqi256_mask:
1235 case X86::BI__builtin_ia32_expandloadqi512_mask:
1236 return EmitX86ExpandLoad(*this, Ops);
1237
1238 case X86::BI__builtin_ia32_compressstoredf128_mask:
1239 case X86::BI__builtin_ia32_compressstoredf256_mask:
1240 case X86::BI__builtin_ia32_compressstoredf512_mask:
1241 case X86::BI__builtin_ia32_compressstoresf128_mask:
1242 case X86::BI__builtin_ia32_compressstoresf256_mask:
1243 case X86::BI__builtin_ia32_compressstoresf512_mask:
1244 case X86::BI__builtin_ia32_compressstoredi128_mask:
1245 case X86::BI__builtin_ia32_compressstoredi256_mask:
1246 case X86::BI__builtin_ia32_compressstoredi512_mask:
1247 case X86::BI__builtin_ia32_compressstoresi128_mask:
1248 case X86::BI__builtin_ia32_compressstoresi256_mask:
1249 case X86::BI__builtin_ia32_compressstoresi512_mask:
1250 case X86::BI__builtin_ia32_compressstorehi128_mask:
1251 case X86::BI__builtin_ia32_compressstorehi256_mask:
1252 case X86::BI__builtin_ia32_compressstorehi512_mask:
1253 case X86::BI__builtin_ia32_compressstoreqi128_mask:
1254 case X86::BI__builtin_ia32_compressstoreqi256_mask:
1255 case X86::BI__builtin_ia32_compressstoreqi512_mask:
1256 return EmitX86CompressStore(*this, Ops);
1257
1258 case X86::BI__builtin_ia32_expanddf128_mask:
1259 case X86::BI__builtin_ia32_expanddf256_mask:
1260 case X86::BI__builtin_ia32_expanddf512_mask:
1261 case X86::BI__builtin_ia32_expandsf128_mask:
1262 case X86::BI__builtin_ia32_expandsf256_mask:
1263 case X86::BI__builtin_ia32_expandsf512_mask:
1264 case X86::BI__builtin_ia32_expanddi128_mask:
1265 case X86::BI__builtin_ia32_expanddi256_mask:
1266 case X86::BI__builtin_ia32_expanddi512_mask:
1267 case X86::BI__builtin_ia32_expandsi128_mask:
1268 case X86::BI__builtin_ia32_expandsi256_mask:
1269 case X86::BI__builtin_ia32_expandsi512_mask:
1270 case X86::BI__builtin_ia32_expandhi128_mask:
1271 case X86::BI__builtin_ia32_expandhi256_mask:
1272 case X86::BI__builtin_ia32_expandhi512_mask:
1273 case X86::BI__builtin_ia32_expandqi128_mask:
1274 case X86::BI__builtin_ia32_expandqi256_mask:
1275 case X86::BI__builtin_ia32_expandqi512_mask:
1276 return EmitX86CompressExpand(*this, Ops, /*IsCompress*/false);
1277
1278 case X86::BI__builtin_ia32_compressdf128_mask:
1279 case X86::BI__builtin_ia32_compressdf256_mask:
1280 case X86::BI__builtin_ia32_compressdf512_mask:
1281 case X86::BI__builtin_ia32_compresssf128_mask:
1282 case X86::BI__builtin_ia32_compresssf256_mask:
1283 case X86::BI__builtin_ia32_compresssf512_mask:
1284 case X86::BI__builtin_ia32_compressdi128_mask:
1285 case X86::BI__builtin_ia32_compressdi256_mask:
1286 case X86::BI__builtin_ia32_compressdi512_mask:
1287 case X86::BI__builtin_ia32_compresssi128_mask:
1288 case X86::BI__builtin_ia32_compresssi256_mask:
1289 case X86::BI__builtin_ia32_compresssi512_mask:
1290 case X86::BI__builtin_ia32_compresshi128_mask:
1291 case X86::BI__builtin_ia32_compresshi256_mask:
1292 case X86::BI__builtin_ia32_compresshi512_mask:
1293 case X86::BI__builtin_ia32_compressqi128_mask:
1294 case X86::BI__builtin_ia32_compressqi256_mask:
1295 case X86::BI__builtin_ia32_compressqi512_mask:
1296 return EmitX86CompressExpand(*this, Ops, /*IsCompress*/true);
1297
1298 case X86::BI__builtin_ia32_gather3div2df:
1299 case X86::BI__builtin_ia32_gather3div2di:
1300 case X86::BI__builtin_ia32_gather3div4df:
1301 case X86::BI__builtin_ia32_gather3div4di:
1302 case X86::BI__builtin_ia32_gather3div4sf:
1303 case X86::BI__builtin_ia32_gather3div4si:
1304 case X86::BI__builtin_ia32_gather3div8sf:
1305 case X86::BI__builtin_ia32_gather3div8si:
1306 case X86::BI__builtin_ia32_gather3siv2df:
1307 case X86::BI__builtin_ia32_gather3siv2di:
1308 case X86::BI__builtin_ia32_gather3siv4df:
1309 case X86::BI__builtin_ia32_gather3siv4di:
1310 case X86::BI__builtin_ia32_gather3siv4sf:
1311 case X86::BI__builtin_ia32_gather3siv4si:
1312 case X86::BI__builtin_ia32_gather3siv8sf:
1313 case X86::BI__builtin_ia32_gather3siv8si:
1314 case X86::BI__builtin_ia32_gathersiv8df:
1315 case X86::BI__builtin_ia32_gathersiv16sf:
1316 case X86::BI__builtin_ia32_gatherdiv8df:
1317 case X86::BI__builtin_ia32_gatherdiv16sf:
1318 case X86::BI__builtin_ia32_gathersiv8di:
1319 case X86::BI__builtin_ia32_gathersiv16si:
1320 case X86::BI__builtin_ia32_gatherdiv8di:
1321 case X86::BI__builtin_ia32_gatherdiv16si: {
1322 Intrinsic::ID IID;
1323 switch (BuiltinID) {
1324 default: llvm_unreachable("Unexpected builtin");
1325 case X86::BI__builtin_ia32_gather3div2df:
1326 IID = Intrinsic::x86_avx512_mask_gather3div2_df;
1327 break;
1328 case X86::BI__builtin_ia32_gather3div2di:
1329 IID = Intrinsic::x86_avx512_mask_gather3div2_di;
1330 break;
1331 case X86::BI__builtin_ia32_gather3div4df:
1332 IID = Intrinsic::x86_avx512_mask_gather3div4_df;
1333 break;
1334 case X86::BI__builtin_ia32_gather3div4di:
1335 IID = Intrinsic::x86_avx512_mask_gather3div4_di;
1336 break;
1337 case X86::BI__builtin_ia32_gather3div4sf:
1338 IID = Intrinsic::x86_avx512_mask_gather3div4_sf;
1339 break;
1340 case X86::BI__builtin_ia32_gather3div4si:
1341 IID = Intrinsic::x86_avx512_mask_gather3div4_si;
1342 break;
1343 case X86::BI__builtin_ia32_gather3div8sf:
1344 IID = Intrinsic::x86_avx512_mask_gather3div8_sf;
1345 break;
1346 case X86::BI__builtin_ia32_gather3div8si:
1347 IID = Intrinsic::x86_avx512_mask_gather3div8_si;
1348 break;
1349 case X86::BI__builtin_ia32_gather3siv2df:
1350 IID = Intrinsic::x86_avx512_mask_gather3siv2_df;
1351 break;
1352 case X86::BI__builtin_ia32_gather3siv2di:
1353 IID = Intrinsic::x86_avx512_mask_gather3siv2_di;
1354 break;
1355 case X86::BI__builtin_ia32_gather3siv4df:
1356 IID = Intrinsic::x86_avx512_mask_gather3siv4_df;
1357 break;
1358 case X86::BI__builtin_ia32_gather3siv4di:
1359 IID = Intrinsic::x86_avx512_mask_gather3siv4_di;
1360 break;
1361 case X86::BI__builtin_ia32_gather3siv4sf:
1362 IID = Intrinsic::x86_avx512_mask_gather3siv4_sf;
1363 break;
1364 case X86::BI__builtin_ia32_gather3siv4si:
1365 IID = Intrinsic::x86_avx512_mask_gather3siv4_si;
1366 break;
1367 case X86::BI__builtin_ia32_gather3siv8sf:
1368 IID = Intrinsic::x86_avx512_mask_gather3siv8_sf;
1369 break;
1370 case X86::BI__builtin_ia32_gather3siv8si:
1371 IID = Intrinsic::x86_avx512_mask_gather3siv8_si;
1372 break;
1373 case X86::BI__builtin_ia32_gathersiv8df:
1374 IID = Intrinsic::x86_avx512_mask_gather_dpd_512;
1375 break;
1376 case X86::BI__builtin_ia32_gathersiv16sf:
1377 IID = Intrinsic::x86_avx512_mask_gather_dps_512;
1378 break;
1379 case X86::BI__builtin_ia32_gatherdiv8df:
1380 IID = Intrinsic::x86_avx512_mask_gather_qpd_512;
1381 break;
1382 case X86::BI__builtin_ia32_gatherdiv16sf:
1383 IID = Intrinsic::x86_avx512_mask_gather_qps_512;
1384 break;
1385 case X86::BI__builtin_ia32_gathersiv8di:
1386 IID = Intrinsic::x86_avx512_mask_gather_dpq_512;
1387 break;
1388 case X86::BI__builtin_ia32_gathersiv16si:
1389 IID = Intrinsic::x86_avx512_mask_gather_dpi_512;
1390 break;
1391 case X86::BI__builtin_ia32_gatherdiv8di:
1392 IID = Intrinsic::x86_avx512_mask_gather_qpq_512;
1393 break;
1394 case X86::BI__builtin_ia32_gatherdiv16si:
1395 IID = Intrinsic::x86_avx512_mask_gather_qpi_512;
1396 break;
1397 }
1398
1399 unsigned MinElts = std::min(
1400 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements(),
1401 cast<llvm::FixedVectorType>(Ops[2]->getType())->getNumElements());
1402 Ops[3] = getMaskVecValue(*this, Ops[3], MinElts);
1403 Function *Intr = CGM.getIntrinsic(IID);
1404 return Builder.CreateCall(Intr, Ops);
1405 }
1406
1407 case X86::BI__builtin_ia32_scattersiv8df:
1408 case X86::BI__builtin_ia32_scattersiv16sf:
1409 case X86::BI__builtin_ia32_scatterdiv8df:
1410 case X86::BI__builtin_ia32_scatterdiv16sf:
1411 case X86::BI__builtin_ia32_scattersiv8di:
1412 case X86::BI__builtin_ia32_scattersiv16si:
1413 case X86::BI__builtin_ia32_scatterdiv8di:
1414 case X86::BI__builtin_ia32_scatterdiv16si:
1415 case X86::BI__builtin_ia32_scatterdiv2df:
1416 case X86::BI__builtin_ia32_scatterdiv2di:
1417 case X86::BI__builtin_ia32_scatterdiv4df:
1418 case X86::BI__builtin_ia32_scatterdiv4di:
1419 case X86::BI__builtin_ia32_scatterdiv4sf:
1420 case X86::BI__builtin_ia32_scatterdiv4si:
1421 case X86::BI__builtin_ia32_scatterdiv8sf:
1422 case X86::BI__builtin_ia32_scatterdiv8si:
1423 case X86::BI__builtin_ia32_scattersiv2df:
1424 case X86::BI__builtin_ia32_scattersiv2di:
1425 case X86::BI__builtin_ia32_scattersiv4df:
1426 case X86::BI__builtin_ia32_scattersiv4di:
1427 case X86::BI__builtin_ia32_scattersiv4sf:
1428 case X86::BI__builtin_ia32_scattersiv4si:
1429 case X86::BI__builtin_ia32_scattersiv8sf:
1430 case X86::BI__builtin_ia32_scattersiv8si: {
1431 Intrinsic::ID IID;
1432 switch (BuiltinID) {
1433 default: llvm_unreachable("Unexpected builtin");
1434 case X86::BI__builtin_ia32_scattersiv8df:
1435 IID = Intrinsic::x86_avx512_mask_scatter_dpd_512;
1436 break;
1437 case X86::BI__builtin_ia32_scattersiv16sf:
1438 IID = Intrinsic::x86_avx512_mask_scatter_dps_512;
1439 break;
1440 case X86::BI__builtin_ia32_scatterdiv8df:
1441 IID = Intrinsic::x86_avx512_mask_scatter_qpd_512;
1442 break;
1443 case X86::BI__builtin_ia32_scatterdiv16sf:
1444 IID = Intrinsic::x86_avx512_mask_scatter_qps_512;
1445 break;
1446 case X86::BI__builtin_ia32_scattersiv8di:
1447 IID = Intrinsic::x86_avx512_mask_scatter_dpq_512;
1448 break;
1449 case X86::BI__builtin_ia32_scattersiv16si:
1450 IID = Intrinsic::x86_avx512_mask_scatter_dpi_512;
1451 break;
1452 case X86::BI__builtin_ia32_scatterdiv8di:
1453 IID = Intrinsic::x86_avx512_mask_scatter_qpq_512;
1454 break;
1455 case X86::BI__builtin_ia32_scatterdiv16si:
1456 IID = Intrinsic::x86_avx512_mask_scatter_qpi_512;
1457 break;
1458 case X86::BI__builtin_ia32_scatterdiv2df:
1459 IID = Intrinsic::x86_avx512_mask_scatterdiv2_df;
1460 break;
1461 case X86::BI__builtin_ia32_scatterdiv2di:
1462 IID = Intrinsic::x86_avx512_mask_scatterdiv2_di;
1463 break;
1464 case X86::BI__builtin_ia32_scatterdiv4df:
1465 IID = Intrinsic::x86_avx512_mask_scatterdiv4_df;
1466 break;
1467 case X86::BI__builtin_ia32_scatterdiv4di:
1468 IID = Intrinsic::x86_avx512_mask_scatterdiv4_di;
1469 break;
1470 case X86::BI__builtin_ia32_scatterdiv4sf:
1471 IID = Intrinsic::x86_avx512_mask_scatterdiv4_sf;
1472 break;
1473 case X86::BI__builtin_ia32_scatterdiv4si:
1474 IID = Intrinsic::x86_avx512_mask_scatterdiv4_si;
1475 break;
1476 case X86::BI__builtin_ia32_scatterdiv8sf:
1477 IID = Intrinsic::x86_avx512_mask_scatterdiv8_sf;
1478 break;
1479 case X86::BI__builtin_ia32_scatterdiv8si:
1480 IID = Intrinsic::x86_avx512_mask_scatterdiv8_si;
1481 break;
1482 case X86::BI__builtin_ia32_scattersiv2df:
1483 IID = Intrinsic::x86_avx512_mask_scattersiv2_df;
1484 break;
1485 case X86::BI__builtin_ia32_scattersiv2di:
1486 IID = Intrinsic::x86_avx512_mask_scattersiv2_di;
1487 break;
1488 case X86::BI__builtin_ia32_scattersiv4df:
1489 IID = Intrinsic::x86_avx512_mask_scattersiv4_df;
1490 break;
1491 case X86::BI__builtin_ia32_scattersiv4di:
1492 IID = Intrinsic::x86_avx512_mask_scattersiv4_di;
1493 break;
1494 case X86::BI__builtin_ia32_scattersiv4sf:
1495 IID = Intrinsic::x86_avx512_mask_scattersiv4_sf;
1496 break;
1497 case X86::BI__builtin_ia32_scattersiv4si:
1498 IID = Intrinsic::x86_avx512_mask_scattersiv4_si;
1499 break;
1500 case X86::BI__builtin_ia32_scattersiv8sf:
1501 IID = Intrinsic::x86_avx512_mask_scattersiv8_sf;
1502 break;
1503 case X86::BI__builtin_ia32_scattersiv8si:
1504 IID = Intrinsic::x86_avx512_mask_scattersiv8_si;
1505 break;
1506 }
1507
1508 unsigned MinElts = std::min(
1509 cast<llvm::FixedVectorType>(Ops[2]->getType())->getNumElements(),
1510 cast<llvm::FixedVectorType>(Ops[3]->getType())->getNumElements());
1511 Ops[1] = getMaskVecValue(*this, Ops[1], MinElts);
1512 Function *Intr = CGM.getIntrinsic(IID);
1513 return Builder.CreateCall(Intr, Ops);
1514 }
1515
1516 case X86::BI__builtin_ia32_vextractf128_pd256:
1517 case X86::BI__builtin_ia32_vextractf128_ps256:
1518 case X86::BI__builtin_ia32_vextractf128_si256:
1519 case X86::BI__builtin_ia32_extract128i256:
1520 case X86::BI__builtin_ia32_extractf64x4_mask:
1521 case X86::BI__builtin_ia32_extractf32x4_mask:
1522 case X86::BI__builtin_ia32_extracti64x4_mask:
1523 case X86::BI__builtin_ia32_extracti32x4_mask:
1524 case X86::BI__builtin_ia32_extractf32x8_mask:
1525 case X86::BI__builtin_ia32_extracti32x8_mask:
1526 case X86::BI__builtin_ia32_extractf32x4_256_mask:
1527 case X86::BI__builtin_ia32_extracti32x4_256_mask:
1528 case X86::BI__builtin_ia32_extractf64x2_256_mask:
1529 case X86::BI__builtin_ia32_extracti64x2_256_mask:
1530 case X86::BI__builtin_ia32_extractf64x2_512_mask:
1531 case X86::BI__builtin_ia32_extracti64x2_512_mask: {
1532 auto *DstTy = cast<llvm::FixedVectorType>(ConvertType(E->getType()));
1533 unsigned NumElts = DstTy->getNumElements();
1534 unsigned SrcNumElts =
1535 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
1536 unsigned SubVectors = SrcNumElts / NumElts;
1537 unsigned Index = cast<ConstantInt>(Ops[1])->getZExtValue();
1538 assert(llvm::isPowerOf2_32(SubVectors) && "Expected power of 2 subvectors");
1539 Index &= SubVectors - 1; // Remove any extra bits.
1540 Index *= NumElts;
1541
1542 int Indices[16];
1543 for (unsigned i = 0; i != NumElts; ++i)
1544 Indices[i] = i + Index;
1545
1546 Value *Res = Builder.CreateShuffleVector(Ops[0], ArrayRef(Indices, NumElts),
1547 "extract");
1548
1549 if (Ops.size() == 4)
1550 Res = EmitX86Select(*this, Ops[3], Res, Ops[2]);
1551
1552 return Res;
1553 }
1554 case X86::BI__builtin_ia32_vinsertf128_pd256:
1555 case X86::BI__builtin_ia32_vinsertf128_ps256:
1556 case X86::BI__builtin_ia32_vinsertf128_si256:
1557 case X86::BI__builtin_ia32_insert128i256:
1558 case X86::BI__builtin_ia32_insertf64x4:
1559 case X86::BI__builtin_ia32_insertf32x4:
1560 case X86::BI__builtin_ia32_inserti64x4:
1561 case X86::BI__builtin_ia32_inserti32x4:
1562 case X86::BI__builtin_ia32_insertf32x8:
1563 case X86::BI__builtin_ia32_inserti32x8:
1564 case X86::BI__builtin_ia32_insertf32x4_256:
1565 case X86::BI__builtin_ia32_inserti32x4_256:
1566 case X86::BI__builtin_ia32_insertf64x2_256:
1567 case X86::BI__builtin_ia32_inserti64x2_256:
1568 case X86::BI__builtin_ia32_insertf64x2_512:
1569 case X86::BI__builtin_ia32_inserti64x2_512: {
1570 unsigned DstNumElts =
1571 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
1572 unsigned SrcNumElts =
1573 cast<llvm::FixedVectorType>(Ops[1]->getType())->getNumElements();
1574 unsigned SubVectors = DstNumElts / SrcNumElts;
1575 unsigned Index = cast<ConstantInt>(Ops[2])->getZExtValue();
1576 assert(llvm::isPowerOf2_32(SubVectors) && "Expected power of 2 subvectors");
1577 Index &= SubVectors - 1; // Remove any extra bits.
1578 Index *= SrcNumElts;
1579
1580 int Indices[16];
1581 for (unsigned i = 0; i != DstNumElts; ++i)
1582 Indices[i] = (i >= SrcNumElts) ? SrcNumElts + (i % SrcNumElts) : i;
1583
1584 Value *Op1 = Builder.CreateShuffleVector(
1585 Ops[1], ArrayRef(Indices, DstNumElts), "widen");
1586
1587 for (unsigned i = 0; i != DstNumElts; ++i) {
1588 if (i >= Index && i < (Index + SrcNumElts))
1589 Indices[i] = (i - Index) + DstNumElts;
1590 else
1591 Indices[i] = i;
1592 }
1593
1594 return Builder.CreateShuffleVector(Ops[0], Op1,
1595 ArrayRef(Indices, DstNumElts), "insert");
1596 }
1597 case X86::BI__builtin_ia32_pmovqd512_mask:
1598 case X86::BI__builtin_ia32_pmovwb512_mask: {
1599 Value *Res = Builder.CreateTrunc(Ops[0], Ops[1]->getType());
1600 return EmitX86Select(*this, Ops[2], Res, Ops[1]);
1601 }
1602 case X86::BI__builtin_ia32_pmovdb512_mask:
1603 case X86::BI__builtin_ia32_pmovdw512_mask:
1604 case X86::BI__builtin_ia32_pmovqw512_mask: {
1605 if (const auto *C = dyn_cast<Constant>(Ops[2]))
1606 if (C->isAllOnesValue())
1607 return Builder.CreateTrunc(Ops[0], Ops[1]->getType());
1608
1609 Intrinsic::ID IID;
1610 switch (BuiltinID) {
1611 default: llvm_unreachable("Unsupported intrinsic!");
1612 case X86::BI__builtin_ia32_pmovdb512_mask:
1613 IID = Intrinsic::x86_avx512_mask_pmov_db_512;
1614 break;
1615 case X86::BI__builtin_ia32_pmovdw512_mask:
1616 IID = Intrinsic::x86_avx512_mask_pmov_dw_512;
1617 break;
1618 case X86::BI__builtin_ia32_pmovqw512_mask:
1619 IID = Intrinsic::x86_avx512_mask_pmov_qw_512;
1620 break;
1621 }
1622
1623 Function *Intr = CGM.getIntrinsic(IID);
1624 return Builder.CreateCall(Intr, Ops);
1625 }
1626 case X86::BI__builtin_ia32_pblendw128:
1627 case X86::BI__builtin_ia32_blendpd:
1628 case X86::BI__builtin_ia32_blendps:
1629 case X86::BI__builtin_ia32_blendpd256:
1630 case X86::BI__builtin_ia32_blendps256:
1631 case X86::BI__builtin_ia32_pblendw256:
1632 case X86::BI__builtin_ia32_pblendd128:
1633 case X86::BI__builtin_ia32_pblendd256: {
1634 unsigned NumElts =
1635 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
1636 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
1637
1638 int Indices[16];
1639 // If there are more than 8 elements, the immediate is used twice so make
1640 // sure we handle that.
1641 for (unsigned i = 0; i != NumElts; ++i)
1642 Indices[i] = ((Imm >> (i % 8)) & 0x1) ? NumElts + i : i;
1643
1644 return Builder.CreateShuffleVector(Ops[0], Ops[1],
1645 ArrayRef(Indices, NumElts), "blend");
1646 }
1647 case X86::BI__builtin_ia32_pshuflw:
1648 case X86::BI__builtin_ia32_pshuflw256:
1649 case X86::BI__builtin_ia32_pshuflw512: {
1650 uint32_t Imm = cast<llvm::ConstantInt>(Ops[1])->getZExtValue();
1651 auto *Ty = cast<llvm::FixedVectorType>(Ops[0]->getType());
1652 unsigned NumElts = Ty->getNumElements();
1653
1654 // Splat the 8-bits of immediate 4 times to help the loop wrap around.
1655 Imm = (Imm & 0xff) * 0x01010101;
1656
1657 int Indices[32];
1658 for (unsigned l = 0; l != NumElts; l += 8) {
1659 for (unsigned i = 0; i != 4; ++i) {
1660 Indices[l + i] = l + (Imm & 3);
1661 Imm >>= 2;
1662 }
1663 for (unsigned i = 4; i != 8; ++i)
1664 Indices[l + i] = l + i;
1665 }
1666
1667 return Builder.CreateShuffleVector(Ops[0], ArrayRef(Indices, NumElts),
1668 "pshuflw");
1669 }
1670 case X86::BI__builtin_ia32_pshufhw:
1671 case X86::BI__builtin_ia32_pshufhw256:
1672 case X86::BI__builtin_ia32_pshufhw512: {
1673 uint32_t Imm = cast<llvm::ConstantInt>(Ops[1])->getZExtValue();
1674 auto *Ty = cast<llvm::FixedVectorType>(Ops[0]->getType());
1675 unsigned NumElts = Ty->getNumElements();
1676
1677 // Splat the 8-bits of immediate 4 times to help the loop wrap around.
1678 Imm = (Imm & 0xff) * 0x01010101;
1679
1680 int Indices[32];
1681 for (unsigned l = 0; l != NumElts; l += 8) {
1682 for (unsigned i = 0; i != 4; ++i)
1683 Indices[l + i] = l + i;
1684 for (unsigned i = 4; i != 8; ++i) {
1685 Indices[l + i] = l + 4 + (Imm & 3);
1686 Imm >>= 2;
1687 }
1688 }
1689
1690 return Builder.CreateShuffleVector(Ops[0], ArrayRef(Indices, NumElts),
1691 "pshufhw");
1692 }
1693 case X86::BI__builtin_ia32_pshufd:
1694 case X86::BI__builtin_ia32_pshufd256:
1695 case X86::BI__builtin_ia32_pshufd512:
1696 case X86::BI__builtin_ia32_vpermilpd:
1697 case X86::BI__builtin_ia32_vpermilps:
1698 case X86::BI__builtin_ia32_vpermilpd256:
1699 case X86::BI__builtin_ia32_vpermilps256:
1700 case X86::BI__builtin_ia32_vpermilpd512:
1701 case X86::BI__builtin_ia32_vpermilps512: {
1702 uint32_t Imm = cast<llvm::ConstantInt>(Ops[1])->getZExtValue();
1703 auto *Ty = cast<llvm::FixedVectorType>(Ops[0]->getType());
1704 unsigned NumElts = Ty->getNumElements();
1705 unsigned NumLanes = Ty->getPrimitiveSizeInBits() / 128;
1706 unsigned NumLaneElts = NumElts / NumLanes;
1707
1708 // Splat the 8-bits of immediate 4 times to help the loop wrap around.
1709 Imm = (Imm & 0xff) * 0x01010101;
1710
1711 int Indices[16];
1712 for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
1713 for (unsigned i = 0; i != NumLaneElts; ++i) {
1714 Indices[i + l] = (Imm % NumLaneElts) + l;
1715 Imm /= NumLaneElts;
1716 }
1717 }
1718
1719 return Builder.CreateShuffleVector(Ops[0], ArrayRef(Indices, NumElts),
1720 "permil");
1721 }
1722 case X86::BI__builtin_ia32_shufpd:
1723 case X86::BI__builtin_ia32_shufpd256:
1724 case X86::BI__builtin_ia32_shufpd512:
1725 case X86::BI__builtin_ia32_shufps:
1726 case X86::BI__builtin_ia32_shufps256:
1727 case X86::BI__builtin_ia32_shufps512: {
1728 uint32_t Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
1729 auto *Ty = cast<llvm::FixedVectorType>(Ops[0]->getType());
1730 unsigned NumElts = Ty->getNumElements();
1731 unsigned NumLanes = Ty->getPrimitiveSizeInBits() / 128;
1732 unsigned NumLaneElts = NumElts / NumLanes;
1733
1734 // Splat the 8-bits of immediate 4 times to help the loop wrap around.
1735 Imm = (Imm & 0xff) * 0x01010101;
1736
1737 int Indices[16];
1738 for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
1739 for (unsigned i = 0; i != NumLaneElts; ++i) {
1740 unsigned Index = Imm % NumLaneElts;
1741 Imm /= NumLaneElts;
1742 if (i >= (NumLaneElts / 2))
1743 Index += NumElts;
1744 Indices[l + i] = l + Index;
1745 }
1746 }
1747
1748 return Builder.CreateShuffleVector(Ops[0], Ops[1],
1749 ArrayRef(Indices, NumElts), "shufp");
1750 }
1751 case X86::BI__builtin_ia32_permdi256:
1752 case X86::BI__builtin_ia32_permdf256:
1753 case X86::BI__builtin_ia32_permdi512:
1754 case X86::BI__builtin_ia32_permdf512: {
1755 unsigned Imm = cast<llvm::ConstantInt>(Ops[1])->getZExtValue();
1756 auto *Ty = cast<llvm::FixedVectorType>(Ops[0]->getType());
1757 unsigned NumElts = Ty->getNumElements();
1758
1759 // These intrinsics operate on 256-bit lanes of four 64-bit elements.
1760 int Indices[8];
1761 for (unsigned l = 0; l != NumElts; l += 4)
1762 for (unsigned i = 0; i != 4; ++i)
1763 Indices[l + i] = l + ((Imm >> (2 * i)) & 0x3);
1764
1765 return Builder.CreateShuffleVector(Ops[0], ArrayRef(Indices, NumElts),
1766 "perm");
1767 }
1768 case X86::BI__builtin_ia32_palignr128:
1769 case X86::BI__builtin_ia32_palignr256:
1770 case X86::BI__builtin_ia32_palignr512: {
1771 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0xff;
1772
1773 unsigned NumElts =
1774 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
1775 assert(NumElts % 16 == 0);
1776
1777 // If palignr is shifting the pair of vectors more than the size of two
1778 // lanes, emit zero.
1779 if (ShiftVal >= 32)
1780 return llvm::Constant::getNullValue(ConvertType(E->getType()));
1781
1782 // If palignr is shifting the pair of input vectors more than one lane,
1783 // but less than two lanes, convert to shifting in zeroes.
1784 if (ShiftVal > 16) {
1785 ShiftVal -= 16;
1786 Ops[1] = Ops[0];
1787 Ops[0] = llvm::Constant::getNullValue(Ops[0]->getType());
1788 }
1789
1790 int Indices[64];
1791 // 256-bit palignr operates on 128-bit lanes so we need to handle that
1792 for (unsigned l = 0; l != NumElts; l += 16) {
1793 for (unsigned i = 0; i != 16; ++i) {
1794 unsigned Idx = ShiftVal + i;
1795 if (Idx >= 16)
1796 Idx += NumElts - 16; // End of lane, switch operand.
1797 Indices[l + i] = Idx + l;
1798 }
1799 }
1800
1801 return Builder.CreateShuffleVector(Ops[1], Ops[0],
1802 ArrayRef(Indices, NumElts), "palignr");
1803 }
1804 case X86::BI__builtin_ia32_alignd128:
1805 case X86::BI__builtin_ia32_alignd256:
1806 case X86::BI__builtin_ia32_alignd512:
1807 case X86::BI__builtin_ia32_alignq128:
1808 case X86::BI__builtin_ia32_alignq256:
1809 case X86::BI__builtin_ia32_alignq512: {
1810 unsigned NumElts =
1811 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
1812 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0xff;
1813
1814 // Mask the shift amount to width of a vector.
1815 ShiftVal &= NumElts - 1;
1816
1817 int Indices[16];
1818 for (unsigned i = 0; i != NumElts; ++i)
1819 Indices[i] = i + ShiftVal;
1820
1821 return Builder.CreateShuffleVector(Ops[1], Ops[0],
1822 ArrayRef(Indices, NumElts), "valign");
1823 }
1824 case X86::BI__builtin_ia32_shuf_f32x4_256:
1825 case X86::BI__builtin_ia32_shuf_f64x2_256:
1826 case X86::BI__builtin_ia32_shuf_i32x4_256:
1827 case X86::BI__builtin_ia32_shuf_i64x2_256:
1828 case X86::BI__builtin_ia32_shuf_f32x4:
1829 case X86::BI__builtin_ia32_shuf_f64x2:
1830 case X86::BI__builtin_ia32_shuf_i32x4:
1831 case X86::BI__builtin_ia32_shuf_i64x2: {
1832 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
1833 auto *Ty = cast<llvm::FixedVectorType>(Ops[0]->getType());
1834 unsigned NumElts = Ty->getNumElements();
1835 unsigned NumLanes = Ty->getPrimitiveSizeInBits() == 512 ? 4 : 2;
1836 unsigned NumLaneElts = NumElts / NumLanes;
1837
1838 int Indices[16];
1839 for (unsigned l = 0; l != NumElts; l += NumLaneElts) {
1840 unsigned Index = (Imm % NumLanes) * NumLaneElts;
1841 Imm /= NumLanes; // Discard the bits we just used.
1842 if (l >= (NumElts / 2))
1843 Index += NumElts; // Switch to other source.
1844 for (unsigned i = 0; i != NumLaneElts; ++i) {
1845 Indices[l + i] = Index + i;
1846 }
1847 }
1848
1849 return Builder.CreateShuffleVector(Ops[0], Ops[1],
1850 ArrayRef(Indices, NumElts), "shuf");
1851 }
1852
1853 case X86::BI__builtin_ia32_vperm2f128_pd256:
1854 case X86::BI__builtin_ia32_vperm2f128_ps256:
1855 case X86::BI__builtin_ia32_vperm2f128_si256:
1856 case X86::BI__builtin_ia32_permti256: {
1857 unsigned Imm = cast<llvm::ConstantInt>(Ops[2])->getZExtValue();
1858 unsigned NumElts =
1859 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
1860
1861 // This takes a very simple approach since there are two lanes and a
1862 // shuffle can have 2 inputs. So we reserve the first input for the first
1863 // lane and the second input for the second lane. This may result in
1864 // duplicate sources, but this can be dealt with in the backend.
1865
1866 Value *OutOps[2];
1867 int Indices[8];
1868 for (unsigned l = 0; l != 2; ++l) {
1869 // Determine the source for this lane.
1870 if (Imm & (1 << ((l * 4) + 3)))
1871 OutOps[l] = llvm::ConstantAggregateZero::get(Ops[0]->getType());
1872 else if (Imm & (1 << ((l * 4) + 1)))
1873 OutOps[l] = Ops[1];
1874 else
1875 OutOps[l] = Ops[0];
1876
1877 for (unsigned i = 0; i != NumElts/2; ++i) {
1878 // Start with ith element of the source for this lane.
1879 unsigned Idx = (l * NumElts) + i;
1880 // If bit 0 of the immediate half is set, switch to the high half of
1881 // the source.
1882 if (Imm & (1 << (l * 4)))
1883 Idx += NumElts/2;
1884 Indices[(l * (NumElts/2)) + i] = Idx;
1885 }
1886 }
1887
1888 return Builder.CreateShuffleVector(OutOps[0], OutOps[1],
1889 ArrayRef(Indices, NumElts), "vperm");
1890 }
1891
1892 case X86::BI__builtin_ia32_pslldqi128_byteshift:
1893 case X86::BI__builtin_ia32_pslldqi256_byteshift:
1894 case X86::BI__builtin_ia32_pslldqi512_byteshift: {
1895 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue() & 0xff;
1896 auto *VecTy = cast<llvm::FixedVectorType>(Ops[0]->getType());
1897 // Builtin type is vXi8.
1898 unsigned NumElts = VecTy->getNumElements();
1899 Value *Zero = llvm::Constant::getNullValue(VecTy);
1900
1901 // If pslldq is shifting the vector more than 15 bytes, emit zero.
1902 if (ShiftVal >= 16)
1903 return Zero;
1904
1905 int Indices[64];
1906 // 256/512-bit pslldq operates on 128-bit lanes so we need to handle that
1907 for (unsigned l = 0; l != NumElts; l += 16) {
1908 for (unsigned i = 0; i != 16; ++i) {
1909 unsigned Idx = NumElts + i - ShiftVal;
1910 if (Idx < NumElts)
1911 Idx -= NumElts - 16; // end of lane, switch operand.
1912 Indices[l + i] = Idx + l;
1913 }
1914 }
1915 return Builder.CreateShuffleVector(Zero, Ops[0], ArrayRef(Indices, NumElts),
1916 "pslldq");
1917 }
1918 case X86::BI__builtin_ia32_psrldqi128_byteshift:
1919 case X86::BI__builtin_ia32_psrldqi256_byteshift:
1920 case X86::BI__builtin_ia32_psrldqi512_byteshift: {
1921 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue() & 0xff;
1922 auto *VecTy = cast<llvm::FixedVectorType>(Ops[0]->getType());
1923 // Builtin type is vXi8.
1924 unsigned NumElts = VecTy->getNumElements();
1925 Value *Zero = llvm::Constant::getNullValue(VecTy);
1926
1927 // If psrldq is shifting the vector more than 15 bytes, emit zero.
1928 if (ShiftVal >= 16)
1929 return Zero;
1930
1931 int Indices[64];
1932 // 256/512-bit psrldq operates on 128-bit lanes so we need to handle that
1933 for (unsigned l = 0; l != NumElts; l += 16) {
1934 for (unsigned i = 0; i != 16; ++i) {
1935 unsigned Idx = i + ShiftVal;
1936 if (Idx >= 16)
1937 Idx += NumElts - 16; // end of lane, switch operand.
1938 Indices[l + i] = Idx + l;
1939 }
1940 }
1941 return Builder.CreateShuffleVector(Ops[0], Zero, ArrayRef(Indices, NumElts),
1942 "psrldq");
1943 }
1944 case X86::BI__builtin_ia32_kshiftliqi:
1945 case X86::BI__builtin_ia32_kshiftlihi:
1946 case X86::BI__builtin_ia32_kshiftlisi:
1947 case X86::BI__builtin_ia32_kshiftlidi: {
1948 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue() & 0xff;
1949 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
1950
1951 if (ShiftVal >= NumElts)
1952 return llvm::Constant::getNullValue(Ops[0]->getType());
1953
1954 Value *In = getMaskVecValue(*this, Ops[0], NumElts);
1955
1956 int Indices[64];
1957 for (unsigned i = 0; i != NumElts; ++i)
1958 Indices[i] = NumElts + i - ShiftVal;
1959
1960 Value *Zero = llvm::Constant::getNullValue(In->getType());
1961 Value *SV = Builder.CreateShuffleVector(
1962 Zero, In, ArrayRef(Indices, NumElts), "kshiftl");
1963 return Builder.CreateBitCast(SV, Ops[0]->getType());
1964 }
1965 case X86::BI__builtin_ia32_kshiftriqi:
1966 case X86::BI__builtin_ia32_kshiftrihi:
1967 case X86::BI__builtin_ia32_kshiftrisi:
1968 case X86::BI__builtin_ia32_kshiftridi: {
1969 unsigned ShiftVal = cast<llvm::ConstantInt>(Ops[1])->getZExtValue() & 0xff;
1970 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
1971
1972 if (ShiftVal >= NumElts)
1973 return llvm::Constant::getNullValue(Ops[0]->getType());
1974
1975 Value *In = getMaskVecValue(*this, Ops[0], NumElts);
1976
1977 int Indices[64];
1978 for (unsigned i = 0; i != NumElts; ++i)
1979 Indices[i] = i + ShiftVal;
1980
1981 Value *Zero = llvm::Constant::getNullValue(In->getType());
1982 Value *SV = Builder.CreateShuffleVector(
1983 In, Zero, ArrayRef(Indices, NumElts), "kshiftr");
1984 return Builder.CreateBitCast(SV, Ops[0]->getType());
1985 }
1986 case X86::BI__builtin_ia32_movnti:
1987 case X86::BI__builtin_ia32_movnti64:
1988 case X86::BI__builtin_ia32_movntsd:
1989 case X86::BI__builtin_ia32_movntss: {
1990 llvm::MDNode *Node = llvm::MDNode::get(
1991 getLLVMContext(), llvm::ConstantAsMetadata::get(Builder.getInt32(1)));
1992
1993 Value *Ptr = Ops[0];
1994 Value *Src = Ops[1];
1995
1996 // Extract the 0'th element of the source vector.
1997 if (BuiltinID == X86::BI__builtin_ia32_movntsd ||
1998 BuiltinID == X86::BI__builtin_ia32_movntss)
1999 Src = Builder.CreateExtractElement(Src, (uint64_t)0, "extract");
2000
2001 // Unaligned nontemporal store of the scalar value.
2002 StoreInst *SI = Builder.CreateDefaultAlignedStore(Src, Ptr);
2003 SI->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2004 SI->setAlignment(llvm::Align(1));
2005 return SI;
2006 }
2007 // Rotate is a special case of funnel shift - 1st 2 args are the same.
2008 case X86::BI__builtin_ia32_vprotbi:
2009 case X86::BI__builtin_ia32_vprotwi:
2010 case X86::BI__builtin_ia32_vprotdi:
2011 case X86::BI__builtin_ia32_vprotqi:
2012 case X86::BI__builtin_ia32_prold128:
2013 case X86::BI__builtin_ia32_prold256:
2014 case X86::BI__builtin_ia32_prold512:
2015 case X86::BI__builtin_ia32_prolq128:
2016 case X86::BI__builtin_ia32_prolq256:
2017 case X86::BI__builtin_ia32_prolq512:
2018 return EmitX86FunnelShift(*this, Ops[0], Ops[0], Ops[1], false);
2019 case X86::BI__builtin_ia32_prord128:
2020 case X86::BI__builtin_ia32_prord256:
2021 case X86::BI__builtin_ia32_prord512:
2022 case X86::BI__builtin_ia32_prorq128:
2023 case X86::BI__builtin_ia32_prorq256:
2024 case X86::BI__builtin_ia32_prorq512:
2025 return EmitX86FunnelShift(*this, Ops[0], Ops[0], Ops[1], true);
2026 case X86::BI__builtin_ia32_selectb_128:
2027 case X86::BI__builtin_ia32_selectb_256:
2028 case X86::BI__builtin_ia32_selectb_512:
2029 case X86::BI__builtin_ia32_selectw_128:
2030 case X86::BI__builtin_ia32_selectw_256:
2031 case X86::BI__builtin_ia32_selectw_512:
2032 case X86::BI__builtin_ia32_selectd_128:
2033 case X86::BI__builtin_ia32_selectd_256:
2034 case X86::BI__builtin_ia32_selectd_512:
2035 case X86::BI__builtin_ia32_selectq_128:
2036 case X86::BI__builtin_ia32_selectq_256:
2037 case X86::BI__builtin_ia32_selectq_512:
2038 case X86::BI__builtin_ia32_selectph_128:
2039 case X86::BI__builtin_ia32_selectph_256:
2040 case X86::BI__builtin_ia32_selectph_512:
2041 case X86::BI__builtin_ia32_selectpbf_128:
2042 case X86::BI__builtin_ia32_selectpbf_256:
2043 case X86::BI__builtin_ia32_selectpbf_512:
2044 case X86::BI__builtin_ia32_selectps_128:
2045 case X86::BI__builtin_ia32_selectps_256:
2046 case X86::BI__builtin_ia32_selectps_512:
2047 case X86::BI__builtin_ia32_selectpd_128:
2048 case X86::BI__builtin_ia32_selectpd_256:
2049 case X86::BI__builtin_ia32_selectpd_512:
2050 return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]);
2051 case X86::BI__builtin_ia32_selectsh_128:
2052 case X86::BI__builtin_ia32_selectsbf_128:
2053 case X86::BI__builtin_ia32_selectss_128:
2054 case X86::BI__builtin_ia32_selectsd_128: {
2055 Value *A = Builder.CreateExtractElement(Ops[1], (uint64_t)0);
2056 Value *B = Builder.CreateExtractElement(Ops[2], (uint64_t)0);
2057 A = EmitX86ScalarSelect(*this, Ops[0], A, B);
2058 return Builder.CreateInsertElement(Ops[1], A, (uint64_t)0);
2059 }
2060 case X86::BI__builtin_ia32_cmpb128_mask:
2061 case X86::BI__builtin_ia32_cmpb256_mask:
2062 case X86::BI__builtin_ia32_cmpb512_mask:
2063 case X86::BI__builtin_ia32_cmpw128_mask:
2064 case X86::BI__builtin_ia32_cmpw256_mask:
2065 case X86::BI__builtin_ia32_cmpw512_mask:
2066 case X86::BI__builtin_ia32_cmpd128_mask:
2067 case X86::BI__builtin_ia32_cmpd256_mask:
2068 case X86::BI__builtin_ia32_cmpd512_mask:
2069 case X86::BI__builtin_ia32_cmpq128_mask:
2070 case X86::BI__builtin_ia32_cmpq256_mask:
2071 case X86::BI__builtin_ia32_cmpq512_mask: {
2072 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
2073 return EmitX86MaskedCompare(*this, CC, true, Ops);
2074 }
2075 case X86::BI__builtin_ia32_ucmpb128_mask:
2076 case X86::BI__builtin_ia32_ucmpb256_mask:
2077 case X86::BI__builtin_ia32_ucmpb512_mask:
2078 case X86::BI__builtin_ia32_ucmpw128_mask:
2079 case X86::BI__builtin_ia32_ucmpw256_mask:
2080 case X86::BI__builtin_ia32_ucmpw512_mask:
2081 case X86::BI__builtin_ia32_ucmpd128_mask:
2082 case X86::BI__builtin_ia32_ucmpd256_mask:
2083 case X86::BI__builtin_ia32_ucmpd512_mask:
2084 case X86::BI__builtin_ia32_ucmpq128_mask:
2085 case X86::BI__builtin_ia32_ucmpq256_mask:
2086 case X86::BI__builtin_ia32_ucmpq512_mask: {
2087 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x7;
2088 return EmitX86MaskedCompare(*this, CC, false, Ops);
2089 }
2090 case X86::BI__builtin_ia32_vpcomb:
2091 case X86::BI__builtin_ia32_vpcomw:
2092 case X86::BI__builtin_ia32_vpcomd:
2093 case X86::BI__builtin_ia32_vpcomq:
2094 return EmitX86vpcom(*this, Ops, true);
2095 case X86::BI__builtin_ia32_vpcomub:
2096 case X86::BI__builtin_ia32_vpcomuw:
2097 case X86::BI__builtin_ia32_vpcomud:
2098 case X86::BI__builtin_ia32_vpcomuq:
2099 return EmitX86vpcom(*this, Ops, false);
2100
2101 case X86::BI__builtin_ia32_kortestcqi:
2102 case X86::BI__builtin_ia32_kortestchi:
2103 case X86::BI__builtin_ia32_kortestcsi:
2104 case X86::BI__builtin_ia32_kortestcdi: {
2105 Value *Or = EmitX86MaskLogic(*this, Instruction::Or, Ops);
2106 Value *C = llvm::Constant::getAllOnesValue(Ops[0]->getType());
2107 Value *Cmp = Builder.CreateICmpEQ(Or, C);
2108 return Builder.CreateZExt(Cmp, ConvertType(E->getType()));
2109 }
2110 case X86::BI__builtin_ia32_kortestzqi:
2111 case X86::BI__builtin_ia32_kortestzhi:
2112 case X86::BI__builtin_ia32_kortestzsi:
2113 case X86::BI__builtin_ia32_kortestzdi: {
2114 Value *Or = EmitX86MaskLogic(*this, Instruction::Or, Ops);
2115 Value *C = llvm::Constant::getNullValue(Ops[0]->getType());
2116 Value *Cmp = Builder.CreateICmpEQ(Or, C);
2117 return Builder.CreateZExt(Cmp, ConvertType(E->getType()));
2118 }
2119
2120 case X86::BI__builtin_ia32_ktestcqi:
2121 case X86::BI__builtin_ia32_ktestzqi:
2122 case X86::BI__builtin_ia32_ktestchi:
2123 case X86::BI__builtin_ia32_ktestzhi:
2124 case X86::BI__builtin_ia32_ktestcsi:
2125 case X86::BI__builtin_ia32_ktestzsi:
2126 case X86::BI__builtin_ia32_ktestcdi:
2127 case X86::BI__builtin_ia32_ktestzdi: {
2128 Intrinsic::ID IID;
2129 switch (BuiltinID) {
2130 default: llvm_unreachable("Unsupported intrinsic!");
2131 case X86::BI__builtin_ia32_ktestcqi:
2132 IID = Intrinsic::x86_avx512_ktestc_b;
2133 break;
2134 case X86::BI__builtin_ia32_ktestzqi:
2135 IID = Intrinsic::x86_avx512_ktestz_b;
2136 break;
2137 case X86::BI__builtin_ia32_ktestchi:
2138 IID = Intrinsic::x86_avx512_ktestc_w;
2139 break;
2140 case X86::BI__builtin_ia32_ktestzhi:
2141 IID = Intrinsic::x86_avx512_ktestz_w;
2142 break;
2143 case X86::BI__builtin_ia32_ktestcsi:
2144 IID = Intrinsic::x86_avx512_ktestc_d;
2145 break;
2146 case X86::BI__builtin_ia32_ktestzsi:
2147 IID = Intrinsic::x86_avx512_ktestz_d;
2148 break;
2149 case X86::BI__builtin_ia32_ktestcdi:
2150 IID = Intrinsic::x86_avx512_ktestc_q;
2151 break;
2152 case X86::BI__builtin_ia32_ktestzdi:
2153 IID = Intrinsic::x86_avx512_ktestz_q;
2154 break;
2155 }
2156
2157 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
2158 Value *LHS = getMaskVecValue(*this, Ops[0], NumElts);
2159 Value *RHS = getMaskVecValue(*this, Ops[1], NumElts);
2160 Function *Intr = CGM.getIntrinsic(IID);
2161 return Builder.CreateCall(Intr, {LHS, RHS});
2162 }
2163
2164 case X86::BI__builtin_ia32_kaddqi:
2165 case X86::BI__builtin_ia32_kaddhi:
2166 case X86::BI__builtin_ia32_kaddsi:
2167 case X86::BI__builtin_ia32_kadddi: {
2168 Intrinsic::ID IID;
2169 switch (BuiltinID) {
2170 default: llvm_unreachable("Unsupported intrinsic!");
2171 case X86::BI__builtin_ia32_kaddqi:
2172 IID = Intrinsic::x86_avx512_kadd_b;
2173 break;
2174 case X86::BI__builtin_ia32_kaddhi:
2175 IID = Intrinsic::x86_avx512_kadd_w;
2176 break;
2177 case X86::BI__builtin_ia32_kaddsi:
2178 IID = Intrinsic::x86_avx512_kadd_d;
2179 break;
2180 case X86::BI__builtin_ia32_kadddi:
2181 IID = Intrinsic::x86_avx512_kadd_q;
2182 break;
2183 }
2184
2185 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
2186 Value *LHS = getMaskVecValue(*this, Ops[0], NumElts);
2187 Value *RHS = getMaskVecValue(*this, Ops[1], NumElts);
2188 Function *Intr = CGM.getIntrinsic(IID);
2189 Value *Res = Builder.CreateCall(Intr, {LHS, RHS});
2190 return Builder.CreateBitCast(Res, Ops[0]->getType());
2191 }
2192 case X86::BI__builtin_ia32_kandqi:
2193 case X86::BI__builtin_ia32_kandhi:
2194 case X86::BI__builtin_ia32_kandsi:
2195 case X86::BI__builtin_ia32_kanddi:
2196 return EmitX86MaskLogic(*this, Instruction::And, Ops);
2197 case X86::BI__builtin_ia32_kandnqi:
2198 case X86::BI__builtin_ia32_kandnhi:
2199 case X86::BI__builtin_ia32_kandnsi:
2200 case X86::BI__builtin_ia32_kandndi:
2201 return EmitX86MaskLogic(*this, Instruction::And, Ops, true);
2202 case X86::BI__builtin_ia32_korqi:
2203 case X86::BI__builtin_ia32_korhi:
2204 case X86::BI__builtin_ia32_korsi:
2205 case X86::BI__builtin_ia32_kordi:
2206 return EmitX86MaskLogic(*this, Instruction::Or, Ops);
2207 case X86::BI__builtin_ia32_kxnorqi:
2208 case X86::BI__builtin_ia32_kxnorhi:
2209 case X86::BI__builtin_ia32_kxnorsi:
2210 case X86::BI__builtin_ia32_kxnordi:
2211 return EmitX86MaskLogic(*this, Instruction::Xor, Ops, true);
2212 case X86::BI__builtin_ia32_kxorqi:
2213 case X86::BI__builtin_ia32_kxorhi:
2214 case X86::BI__builtin_ia32_kxorsi:
2215 case X86::BI__builtin_ia32_kxordi:
2216 return EmitX86MaskLogic(*this, Instruction::Xor, Ops);
2217 case X86::BI__builtin_ia32_knotqi:
2218 case X86::BI__builtin_ia32_knothi:
2219 case X86::BI__builtin_ia32_knotsi:
2220 case X86::BI__builtin_ia32_knotdi: {
2221 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
2222 Value *Res = getMaskVecValue(*this, Ops[0], NumElts);
2223 return Builder.CreateBitCast(Builder.CreateNot(Res),
2224 Ops[0]->getType());
2225 }
2226 case X86::BI__builtin_ia32_kmovb:
2227 case X86::BI__builtin_ia32_kmovw:
2228 case X86::BI__builtin_ia32_kmovd:
2229 case X86::BI__builtin_ia32_kmovq: {
2230 // Bitcast to vXi1 type and then back to integer. This gets the mask
2231 // register type into the IR, but might be optimized out depending on
2232 // what's around it.
2233 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
2234 Value *Res = getMaskVecValue(*this, Ops[0], NumElts);
2235 return Builder.CreateBitCast(Res, Ops[0]->getType());
2236 }
2237
2238 case X86::BI__builtin_ia32_kunpckdi:
2239 case X86::BI__builtin_ia32_kunpcksi:
2240 case X86::BI__builtin_ia32_kunpckhi: {
2241 unsigned NumElts = Ops[0]->getType()->getIntegerBitWidth();
2242 Value *LHS = getMaskVecValue(*this, Ops[0], NumElts);
2243 Value *RHS = getMaskVecValue(*this, Ops[1], NumElts);
2244 int Indices[64];
2245 for (unsigned i = 0; i != NumElts; ++i)
2246 Indices[i] = i;
2247
2248 // First extract half of each vector. This gives better codegen than
2249 // doing it in a single shuffle.
2250 LHS = Builder.CreateShuffleVector(LHS, LHS, ArrayRef(Indices, NumElts / 2));
2251 RHS = Builder.CreateShuffleVector(RHS, RHS, ArrayRef(Indices, NumElts / 2));
2252 // Concat the vectors.
2253 // NOTE: Operands are swapped to match the intrinsic definition.
2254 Value *Res =
2255 Builder.CreateShuffleVector(RHS, LHS, ArrayRef(Indices, NumElts));
2256 return Builder.CreateBitCast(Res, Ops[0]->getType());
2257 }
2258
2259 case X86::BI__builtin_ia32_sqrtsh_round_mask:
2260 case X86::BI__builtin_ia32_sqrtsd_round_mask:
2261 case X86::BI__builtin_ia32_sqrtss_round_mask: {
2262 unsigned CC = cast<llvm::ConstantInt>(Ops[4])->getZExtValue();
2263 // Support only if the rounding mode is 4 (AKA CUR_DIRECTION),
2264 // otherwise keep the intrinsic.
2265 if (CC != 4) {
2266 Intrinsic::ID IID;
2267
2268 switch (BuiltinID) {
2269 default:
2270 llvm_unreachable("Unsupported intrinsic!");
2271 case X86::BI__builtin_ia32_sqrtsh_round_mask:
2272 IID = Intrinsic::x86_avx512fp16_mask_sqrt_sh;
2273 break;
2274 case X86::BI__builtin_ia32_sqrtsd_round_mask:
2275 IID = Intrinsic::x86_avx512_mask_sqrt_sd;
2276 break;
2277 case X86::BI__builtin_ia32_sqrtss_round_mask:
2278 IID = Intrinsic::x86_avx512_mask_sqrt_ss;
2279 break;
2280 }
2281 return Builder.CreateCall(CGM.getIntrinsic(IID), Ops);
2282 }
2283 Value *A = Builder.CreateExtractElement(Ops[1], (uint64_t)0);
2284 Function *F;
2285 if (Builder.getIsFPConstrained()) {
2286 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
2287 F = CGM.getIntrinsic(Intrinsic::experimental_constrained_sqrt,
2288 A->getType());
2289 A = Builder.CreateConstrainedFPCall(F, A);
2290 } else {
2291 F = CGM.getIntrinsic(Intrinsic::sqrt, A->getType());
2292 A = Builder.CreateCall(F, A);
2293 }
2294 Value *Src = Builder.CreateExtractElement(Ops[2], (uint64_t)0);
2295 A = EmitX86ScalarSelect(*this, Ops[3], A, Src);
2296 return Builder.CreateInsertElement(Ops[0], A, (uint64_t)0);
2297 }
2298 case X86::BI__builtin_ia32_sqrtph512:
2299 case X86::BI__builtin_ia32_sqrtps512:
2300 case X86::BI__builtin_ia32_sqrtpd512: {
2301 unsigned CC = cast<llvm::ConstantInt>(Ops[1])->getZExtValue();
2302 // Support only if the rounding mode is 4 (AKA CUR_DIRECTION),
2303 // otherwise keep the intrinsic.
2304 if (CC != 4) {
2305 Intrinsic::ID IID;
2306
2307 switch (BuiltinID) {
2308 default:
2309 llvm_unreachable("Unsupported intrinsic!");
2310 case X86::BI__builtin_ia32_sqrtph512:
2311 IID = Intrinsic::x86_avx512fp16_sqrt_ph_512;
2312 break;
2313 case X86::BI__builtin_ia32_sqrtps512:
2314 IID = Intrinsic::x86_avx512_sqrt_ps_512;
2315 break;
2316 case X86::BI__builtin_ia32_sqrtpd512:
2317 IID = Intrinsic::x86_avx512_sqrt_pd_512;
2318 break;
2319 }
2320 return Builder.CreateCall(CGM.getIntrinsic(IID), Ops);
2321 }
2322 if (Builder.getIsFPConstrained()) {
2323 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
2324 Function *F = CGM.getIntrinsic(Intrinsic::experimental_constrained_sqrt,
2325 Ops[0]->getType());
2326 return Builder.CreateConstrainedFPCall(F, Ops[0]);
2327 } else {
2328 Function *F = CGM.getIntrinsic(Intrinsic::sqrt, Ops[0]->getType());
2329 return Builder.CreateCall(F, Ops[0]);
2330 }
2331 }
2332
2333 case X86::BI__builtin_ia32_pmulhw128:
2334 case X86::BI__builtin_ia32_pmulhw256:
2335 case X86::BI__builtin_ia32_pmulhw512: {
2336 Function *F = CGM.getIntrinsic(Intrinsic::smulh, Ops[0]->getType());
2337 return Builder.CreateCall(F, {Ops[0], Ops[1]});
2338 }
2339
2340 case X86::BI__builtin_ia32_pmulhuw128:
2341 case X86::BI__builtin_ia32_pmulhuw256:
2342 case X86::BI__builtin_ia32_pmulhuw512: {
2343 Function *F = CGM.getIntrinsic(Intrinsic::umulh, Ops[0]->getType());
2344 return Builder.CreateCall(F, {Ops[0], Ops[1]});
2345 }
2346
2347 case X86::BI__builtin_ia32_pmuludq128:
2348 case X86::BI__builtin_ia32_pmuludq256:
2349 case X86::BI__builtin_ia32_pmuludq512:
2350 return EmitX86Muldq(*this, /*IsSigned*/false, Ops);
2351
2352 case X86::BI__builtin_ia32_pmuldq128:
2353 case X86::BI__builtin_ia32_pmuldq256:
2354 case X86::BI__builtin_ia32_pmuldq512:
2355 return EmitX86Muldq(*this, /*IsSigned*/true, Ops);
2356
2357 case X86::BI__builtin_ia32_pternlogd512_mask:
2358 case X86::BI__builtin_ia32_pternlogq512_mask:
2359 case X86::BI__builtin_ia32_pternlogd128_mask:
2360 case X86::BI__builtin_ia32_pternlogd256_mask:
2361 case X86::BI__builtin_ia32_pternlogq128_mask:
2362 case X86::BI__builtin_ia32_pternlogq256_mask:
2363 return EmitX86Ternlog(*this, /*ZeroMask*/false, Ops);
2364
2365 case X86::BI__builtin_ia32_pternlogd512_maskz:
2366 case X86::BI__builtin_ia32_pternlogq512_maskz:
2367 case X86::BI__builtin_ia32_pternlogd128_maskz:
2368 case X86::BI__builtin_ia32_pternlogd256_maskz:
2369 case X86::BI__builtin_ia32_pternlogq128_maskz:
2370 case X86::BI__builtin_ia32_pternlogq256_maskz:
2371 return EmitX86Ternlog(*this, /*ZeroMask*/true, Ops);
2372
2373 case X86::BI__builtin_ia32_vpshldd128:
2374 case X86::BI__builtin_ia32_vpshldd256:
2375 case X86::BI__builtin_ia32_vpshldd512:
2376 case X86::BI__builtin_ia32_vpshldq128:
2377 case X86::BI__builtin_ia32_vpshldq256:
2378 case X86::BI__builtin_ia32_vpshldq512:
2379 case X86::BI__builtin_ia32_vpshldw128:
2380 case X86::BI__builtin_ia32_vpshldw256:
2381 case X86::BI__builtin_ia32_vpshldw512:
2382 return EmitX86FunnelShift(*this, Ops[0], Ops[1], Ops[2], false);
2383
2384 case X86::BI__builtin_ia32_vpshrdd128:
2385 case X86::BI__builtin_ia32_vpshrdd256:
2386 case X86::BI__builtin_ia32_vpshrdd512:
2387 case X86::BI__builtin_ia32_vpshrdq128:
2388 case X86::BI__builtin_ia32_vpshrdq256:
2389 case X86::BI__builtin_ia32_vpshrdq512:
2390 case X86::BI__builtin_ia32_vpshrdw128:
2391 case X86::BI__builtin_ia32_vpshrdw256:
2392 case X86::BI__builtin_ia32_vpshrdw512:
2393 // Ops 0 and 1 are swapped.
2394 return EmitX86FunnelShift(*this, Ops[1], Ops[0], Ops[2], true);
2395
2396 // Reductions
2397 case X86::BI__builtin_ia32_reduce_fadd_pd512:
2398 case X86::BI__builtin_ia32_reduce_fadd_ps512:
2399 case X86::BI__builtin_ia32_reduce_fadd_ph512:
2400 case X86::BI__builtin_ia32_reduce_fadd_ph256:
2401 case X86::BI__builtin_ia32_reduce_fadd_ph128: {
2402 Function *F =
2403 CGM.getIntrinsic(Intrinsic::vector_reduce_fadd, Ops[1]->getType());
2404 IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2405 Builder.getFastMathFlags().setAllowReassoc();
2406 return Builder.CreateCall(F, {Ops[0], Ops[1]});
2407 }
2408 case X86::BI__builtin_ia32_reduce_fmul_pd512:
2409 case X86::BI__builtin_ia32_reduce_fmul_ps512:
2410 case X86::BI__builtin_ia32_reduce_fmul_ph512:
2411 case X86::BI__builtin_ia32_reduce_fmul_ph256:
2412 case X86::BI__builtin_ia32_reduce_fmul_ph128: {
2413 Function *F =
2414 CGM.getIntrinsic(Intrinsic::vector_reduce_fmul, Ops[1]->getType());
2415 IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2416 Builder.getFastMathFlags().setAllowReassoc();
2417 return Builder.CreateCall(F, {Ops[0], Ops[1]});
2418 }
2419 case X86::BI__builtin_ia32_reduce_fmax_pd512:
2420 case X86::BI__builtin_ia32_reduce_fmax_ps512:
2421 case X86::BI__builtin_ia32_reduce_fmax_ph512:
2422 case X86::BI__builtin_ia32_reduce_fmax_ph256:
2423 case X86::BI__builtin_ia32_reduce_fmax_ph128: {
2424 Function *F =
2425 CGM.getIntrinsic(Intrinsic::vector_reduce_fmax, Ops[0]->getType());
2426 IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2427 Builder.getFastMathFlags().setNoNaNs();
2428 return Builder.CreateCall(F, {Ops[0]});
2429 }
2430 case X86::BI__builtin_ia32_reduce_fmin_pd512:
2431 case X86::BI__builtin_ia32_reduce_fmin_ps512:
2432 case X86::BI__builtin_ia32_reduce_fmin_ph512:
2433 case X86::BI__builtin_ia32_reduce_fmin_ph256:
2434 case X86::BI__builtin_ia32_reduce_fmin_ph128: {
2435 Function *F =
2436 CGM.getIntrinsic(Intrinsic::vector_reduce_fmin, Ops[0]->getType());
2437 IRBuilder<>::FastMathFlagGuard FMFGuard(Builder);
2438 Builder.getFastMathFlags().setNoNaNs();
2439 return Builder.CreateCall(F, {Ops[0]});
2440 }
2441
2442 case X86::BI__builtin_ia32_rdrand16_step:
2443 case X86::BI__builtin_ia32_rdrand32_step:
2444 case X86::BI__builtin_ia32_rdrand64_step:
2445 case X86::BI__builtin_ia32_rdseed16_step:
2446 case X86::BI__builtin_ia32_rdseed32_step:
2447 case X86::BI__builtin_ia32_rdseed64_step: {
2448 Intrinsic::ID ID;
2449 switch (BuiltinID) {
2450 default: llvm_unreachable("Unsupported intrinsic!");
2451 case X86::BI__builtin_ia32_rdrand16_step:
2452 ID = Intrinsic::x86_rdrand_16;
2453 break;
2454 case X86::BI__builtin_ia32_rdrand32_step:
2455 ID = Intrinsic::x86_rdrand_32;
2456 break;
2457 case X86::BI__builtin_ia32_rdrand64_step:
2458 ID = Intrinsic::x86_rdrand_64;
2459 break;
2460 case X86::BI__builtin_ia32_rdseed16_step:
2461 ID = Intrinsic::x86_rdseed_16;
2462 break;
2463 case X86::BI__builtin_ia32_rdseed32_step:
2464 ID = Intrinsic::x86_rdseed_32;
2465 break;
2466 case X86::BI__builtin_ia32_rdseed64_step:
2467 ID = Intrinsic::x86_rdseed_64;
2468 break;
2469 }
2470
2471 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID));
2472 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 0),
2473 Ops[0]);
2474 return Builder.CreateExtractValue(Call, 1);
2475 }
2476 case X86::BI__builtin_ia32_addcarryx_u32:
2477 case X86::BI__builtin_ia32_addcarryx_u64:
2478 case X86::BI__builtin_ia32_subborrow_u32:
2479 case X86::BI__builtin_ia32_subborrow_u64: {
2480 Intrinsic::ID IID;
2481 switch (BuiltinID) {
2482 default: llvm_unreachable("Unsupported intrinsic!");
2483 case X86::BI__builtin_ia32_addcarryx_u32:
2484 IID = Intrinsic::x86_addcarry_32;
2485 break;
2486 case X86::BI__builtin_ia32_addcarryx_u64:
2487 IID = Intrinsic::x86_addcarry_64;
2488 break;
2489 case X86::BI__builtin_ia32_subborrow_u32:
2490 IID = Intrinsic::x86_subborrow_32;
2491 break;
2492 case X86::BI__builtin_ia32_subborrow_u64:
2493 IID = Intrinsic::x86_subborrow_64;
2494 break;
2495 }
2496
2497 Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID),
2498 { Ops[0], Ops[1], Ops[2] });
2499 Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, 1),
2500 Ops[3]);
2501 return Builder.CreateExtractValue(Call, 0);
2502 }
2503
2504 case X86::BI__builtin_ia32_fpclassps128_mask:
2505 case X86::BI__builtin_ia32_fpclassps256_mask:
2506 case X86::BI__builtin_ia32_fpclassps512_mask:
2507 case X86::BI__builtin_ia32_vfpclassbf16128_mask:
2508 case X86::BI__builtin_ia32_vfpclassbf16256_mask:
2509 case X86::BI__builtin_ia32_vfpclassbf16512_mask:
2510 case X86::BI__builtin_ia32_fpclassph128_mask:
2511 case X86::BI__builtin_ia32_fpclassph256_mask:
2512 case X86::BI__builtin_ia32_fpclassph512_mask:
2513 case X86::BI__builtin_ia32_fpclasspd128_mask:
2514 case X86::BI__builtin_ia32_fpclasspd256_mask:
2515 case X86::BI__builtin_ia32_fpclasspd512_mask: {
2516 unsigned NumElts =
2517 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
2518 Value *MaskIn = Ops[2];
2519 Ops.erase(&Ops[2]);
2520
2521 Intrinsic::ID ID;
2522 switch (BuiltinID) {
2523 default: llvm_unreachable("Unsupported intrinsic!");
2524 case X86::BI__builtin_ia32_vfpclassbf16128_mask:
2525 ID = Intrinsic::x86_avx10_fpclass_bf16_128;
2526 break;
2527 case X86::BI__builtin_ia32_vfpclassbf16256_mask:
2528 ID = Intrinsic::x86_avx10_fpclass_bf16_256;
2529 break;
2530 case X86::BI__builtin_ia32_vfpclassbf16512_mask:
2531 ID = Intrinsic::x86_avx10_fpclass_bf16_512;
2532 break;
2533 case X86::BI__builtin_ia32_fpclassph128_mask:
2534 ID = Intrinsic::x86_avx512fp16_fpclass_ph_128;
2535 break;
2536 case X86::BI__builtin_ia32_fpclassph256_mask:
2537 ID = Intrinsic::x86_avx512fp16_fpclass_ph_256;
2538 break;
2539 case X86::BI__builtin_ia32_fpclassph512_mask:
2540 ID = Intrinsic::x86_avx512fp16_fpclass_ph_512;
2541 break;
2542 case X86::BI__builtin_ia32_fpclassps128_mask:
2543 ID = Intrinsic::x86_avx512_fpclass_ps_128;
2544 break;
2545 case X86::BI__builtin_ia32_fpclassps256_mask:
2546 ID = Intrinsic::x86_avx512_fpclass_ps_256;
2547 break;
2548 case X86::BI__builtin_ia32_fpclassps512_mask:
2549 ID = Intrinsic::x86_avx512_fpclass_ps_512;
2550 break;
2551 case X86::BI__builtin_ia32_fpclasspd128_mask:
2552 ID = Intrinsic::x86_avx512_fpclass_pd_128;
2553 break;
2554 case X86::BI__builtin_ia32_fpclasspd256_mask:
2555 ID = Intrinsic::x86_avx512_fpclass_pd_256;
2556 break;
2557 case X86::BI__builtin_ia32_fpclasspd512_mask:
2558 ID = Intrinsic::x86_avx512_fpclass_pd_512;
2559 break;
2560 }
2561
2562 Value *Fpclass = Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
2563 return EmitX86MaskedCompareResult(*this, Fpclass, NumElts, MaskIn);
2564 }
2565
2566 case X86::BI__builtin_ia32_vp2intersect_q_512:
2567 case X86::BI__builtin_ia32_vp2intersect_q_256:
2568 case X86::BI__builtin_ia32_vp2intersect_q_128:
2569 case X86::BI__builtin_ia32_vp2intersect_d_512:
2570 case X86::BI__builtin_ia32_vp2intersect_d_256:
2571 case X86::BI__builtin_ia32_vp2intersect_d_128: {
2572 unsigned NumElts =
2573 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
2574 Intrinsic::ID ID;
2575
2576 switch (BuiltinID) {
2577 default: llvm_unreachable("Unsupported intrinsic!");
2578 case X86::BI__builtin_ia32_vp2intersect_q_512:
2579 ID = Intrinsic::x86_avx512_vp2intersect_q_512;
2580 break;
2581 case X86::BI__builtin_ia32_vp2intersect_q_256:
2582 ID = Intrinsic::x86_avx512_vp2intersect_q_256;
2583 break;
2584 case X86::BI__builtin_ia32_vp2intersect_q_128:
2585 ID = Intrinsic::x86_avx512_vp2intersect_q_128;
2586 break;
2587 case X86::BI__builtin_ia32_vp2intersect_d_512:
2588 ID = Intrinsic::x86_avx512_vp2intersect_d_512;
2589 break;
2590 case X86::BI__builtin_ia32_vp2intersect_d_256:
2591 ID = Intrinsic::x86_avx512_vp2intersect_d_256;
2592 break;
2593 case X86::BI__builtin_ia32_vp2intersect_d_128:
2594 ID = Intrinsic::x86_avx512_vp2intersect_d_128;
2595 break;
2596 }
2597
2598 Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID), {Ops[0], Ops[1]});
2599 Value *Result = Builder.CreateExtractValue(Call, 0);
2600 Result = EmitX86MaskedCompareResult(*this, Result, NumElts, nullptr);
2601 Builder.CreateDefaultAlignedStore(Result, Ops[2]);
2602
2603 Result = Builder.CreateExtractValue(Call, 1);
2604 Result = EmitX86MaskedCompareResult(*this, Result, NumElts, nullptr);
2605 return Builder.CreateDefaultAlignedStore(Result, Ops[3]);
2606 }
2607
2608 case X86::BI__builtin_ia32_vpmultishiftqb128:
2609 case X86::BI__builtin_ia32_vpmultishiftqb256:
2610 case X86::BI__builtin_ia32_vpmultishiftqb512: {
2611 Intrinsic::ID ID;
2612 switch (BuiltinID) {
2613 default: llvm_unreachable("Unsupported intrinsic!");
2614 case X86::BI__builtin_ia32_vpmultishiftqb128:
2615 ID = Intrinsic::x86_avx512_pmultishift_qb_128;
2616 break;
2617 case X86::BI__builtin_ia32_vpmultishiftqb256:
2618 ID = Intrinsic::x86_avx512_pmultishift_qb_256;
2619 break;
2620 case X86::BI__builtin_ia32_vpmultishiftqb512:
2621 ID = Intrinsic::x86_avx512_pmultishift_qb_512;
2622 break;
2623 }
2624
2625 return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
2626 }
2627
2628 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
2629 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
2630 case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
2631 unsigned NumElts =
2632 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
2633 Value *MaskIn = Ops[2];
2634 Ops.erase(&Ops[2]);
2635
2636 Intrinsic::ID ID;
2637 switch (BuiltinID) {
2638 default: llvm_unreachable("Unsupported intrinsic!");
2639 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
2640 ID = Intrinsic::x86_avx512_vpshufbitqmb_128;
2641 break;
2642 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
2643 ID = Intrinsic::x86_avx512_vpshufbitqmb_256;
2644 break;
2645 case X86::BI__builtin_ia32_vpshufbitqmb512_mask:
2646 ID = Intrinsic::x86_avx512_vpshufbitqmb_512;
2647 break;
2648 }
2649
2650 Value *Shufbit = Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
2651 return EmitX86MaskedCompareResult(*this, Shufbit, NumElts, MaskIn);
2652 }
2653
2654 // packed comparison intrinsics
2655 case X86::BI__builtin_ia32_cmpeqps:
2656 case X86::BI__builtin_ia32_cmpeqpd:
2657 return getVectorFCmpIR(CmpInst::FCMP_OEQ, /*IsSignaling*/false);
2658 case X86::BI__builtin_ia32_cmpltps:
2659 case X86::BI__builtin_ia32_cmpltpd:
2660 return getVectorFCmpIR(CmpInst::FCMP_OLT, /*IsSignaling*/true);
2661 case X86::BI__builtin_ia32_cmpleps:
2662 case X86::BI__builtin_ia32_cmplepd:
2663 return getVectorFCmpIR(CmpInst::FCMP_OLE, /*IsSignaling*/true);
2664 case X86::BI__builtin_ia32_cmpunordps:
2665 case X86::BI__builtin_ia32_cmpunordpd:
2666 return getVectorFCmpIR(CmpInst::FCMP_UNO, /*IsSignaling*/false);
2667 case X86::BI__builtin_ia32_cmpneqps:
2668 case X86::BI__builtin_ia32_cmpneqpd:
2669 return getVectorFCmpIR(CmpInst::FCMP_UNE, /*IsSignaling*/false);
2670 case X86::BI__builtin_ia32_cmpnltps:
2671 case X86::BI__builtin_ia32_cmpnltpd:
2672 return getVectorFCmpIR(CmpInst::FCMP_UGE, /*IsSignaling*/true);
2673 case X86::BI__builtin_ia32_cmpnleps:
2674 case X86::BI__builtin_ia32_cmpnlepd:
2675 return getVectorFCmpIR(CmpInst::FCMP_UGT, /*IsSignaling*/true);
2676 case X86::BI__builtin_ia32_cmpordps:
2677 case X86::BI__builtin_ia32_cmpordpd:
2678 return getVectorFCmpIR(CmpInst::FCMP_ORD, /*IsSignaling*/false);
2679 case X86::BI__builtin_ia32_cmpph128_mask:
2680 case X86::BI__builtin_ia32_cmpph256_mask:
2681 case X86::BI__builtin_ia32_cmpph512_mask:
2682 case X86::BI__builtin_ia32_cmpps128_mask:
2683 case X86::BI__builtin_ia32_cmpps256_mask:
2684 case X86::BI__builtin_ia32_cmpps512_mask:
2685 case X86::BI__builtin_ia32_cmppd128_mask:
2686 case X86::BI__builtin_ia32_cmppd256_mask:
2687 case X86::BI__builtin_ia32_cmppd512_mask:
2688 case X86::BI__builtin_ia32_vcmpbf16512_mask:
2689 case X86::BI__builtin_ia32_vcmpbf16256_mask:
2690 case X86::BI__builtin_ia32_vcmpbf16128_mask:
2691 IsMaskFCmp = true;
2692 [[fallthrough]];
2693 case X86::BI__builtin_ia32_cmpps:
2694 case X86::BI__builtin_ia32_cmpps256:
2695 case X86::BI__builtin_ia32_cmppd:
2696 case X86::BI__builtin_ia32_cmppd256: {
2697 // Lowering vector comparisons to fcmp instructions, while
2698 // ignoring signalling behaviour requested
2699 // ignoring rounding mode requested
2700 // This is only possible if fp-model is not strict and FENV_ACCESS is off.
2701
2702 // The third argument is the comparison condition, and integer in the
2703 // range [0, 31]
2704 unsigned CC = cast<llvm::ConstantInt>(Ops[2])->getZExtValue() & 0x1f;
2705
2706 // Lowering to IR fcmp instruction.
2707 // Ignoring requested signaling behaviour,
2708 // e.g. both _CMP_GT_OS & _CMP_GT_OQ are translated to FCMP_OGT.
2709 FCmpInst::Predicate Pred;
2710 bool IsSignaling;
2711 // Predicates for 16-31 repeat the 0-15 predicates. Only the signalling
2712 // behavior is inverted. We'll handle that after the switch.
2713 switch (CC & 0xf) {
2714 case 0x00: Pred = FCmpInst::FCMP_OEQ; IsSignaling = false; break;
2715 case 0x01: Pred = FCmpInst::FCMP_OLT; IsSignaling = true; break;
2716 case 0x02: Pred = FCmpInst::FCMP_OLE; IsSignaling = true; break;
2717 case 0x03: Pred = FCmpInst::FCMP_UNO; IsSignaling = false; break;
2718 case 0x04: Pred = FCmpInst::FCMP_UNE; IsSignaling = false; break;
2719 case 0x05: Pred = FCmpInst::FCMP_UGE; IsSignaling = true; break;
2720 case 0x06: Pred = FCmpInst::FCMP_UGT; IsSignaling = true; break;
2721 case 0x07: Pred = FCmpInst::FCMP_ORD; IsSignaling = false; break;
2722 case 0x08: Pred = FCmpInst::FCMP_UEQ; IsSignaling = false; break;
2723 case 0x09: Pred = FCmpInst::FCMP_ULT; IsSignaling = true; break;
2724 case 0x0a: Pred = FCmpInst::FCMP_ULE; IsSignaling = true; break;
2725 case 0x0b: Pred = FCmpInst::FCMP_FALSE; IsSignaling = false; break;
2726 case 0x0c: Pred = FCmpInst::FCMP_ONE; IsSignaling = false; break;
2727 case 0x0d: Pred = FCmpInst::FCMP_OGE; IsSignaling = true; break;
2728 case 0x0e: Pred = FCmpInst::FCMP_OGT; IsSignaling = true; break;
2729 case 0x0f: Pred = FCmpInst::FCMP_TRUE; IsSignaling = false; break;
2730 default: llvm_unreachable("Unhandled CC");
2731 }
2732
2733 // Invert the signalling behavior for 16-31.
2734 if (CC & 0x10)
2735 IsSignaling = !IsSignaling;
2736
2737 // If the predicate is true or false and we're using constrained intrinsics,
2738 // we don't have a compare intrinsic we can use. Just use the legacy X86
2739 // specific intrinsic.
2740 // If the intrinsic is mask enabled and we're using constrained intrinsics,
2741 // use the legacy X86 specific intrinsic.
2742 if (Builder.getIsFPConstrained() &&
2743 (Pred == FCmpInst::FCMP_TRUE || Pred == FCmpInst::FCMP_FALSE ||
2744 IsMaskFCmp)) {
2745
2746 Intrinsic::ID IID;
2747 switch (BuiltinID) {
2748 default: llvm_unreachable("Unexpected builtin");
2749 case X86::BI__builtin_ia32_cmpps:
2750 IID = Intrinsic::x86_sse_cmp_ps;
2751 break;
2752 case X86::BI__builtin_ia32_cmpps256:
2753 IID = Intrinsic::x86_avx_cmp_ps_256;
2754 break;
2755 case X86::BI__builtin_ia32_cmppd:
2756 IID = Intrinsic::x86_sse2_cmp_pd;
2757 break;
2758 case X86::BI__builtin_ia32_cmppd256:
2759 IID = Intrinsic::x86_avx_cmp_pd_256;
2760 break;
2761 case X86::BI__builtin_ia32_cmpph128_mask:
2762 IID = Intrinsic::x86_avx512fp16_mask_cmp_ph_128;
2763 break;
2764 case X86::BI__builtin_ia32_cmpph256_mask:
2765 IID = Intrinsic::x86_avx512fp16_mask_cmp_ph_256;
2766 break;
2767 case X86::BI__builtin_ia32_cmpph512_mask:
2768 IID = Intrinsic::x86_avx512fp16_mask_cmp_ph_512;
2769 break;
2770 case X86::BI__builtin_ia32_cmpps512_mask:
2771 IID = Intrinsic::x86_avx512_mask_cmp_ps_512;
2772 break;
2773 case X86::BI__builtin_ia32_cmppd512_mask:
2774 IID = Intrinsic::x86_avx512_mask_cmp_pd_512;
2775 break;
2776 case X86::BI__builtin_ia32_cmpps128_mask:
2777 IID = Intrinsic::x86_avx512_mask_cmp_ps_128;
2778 break;
2779 case X86::BI__builtin_ia32_cmpps256_mask:
2780 IID = Intrinsic::x86_avx512_mask_cmp_ps_256;
2781 break;
2782 case X86::BI__builtin_ia32_cmppd128_mask:
2783 IID = Intrinsic::x86_avx512_mask_cmp_pd_128;
2784 break;
2785 case X86::BI__builtin_ia32_cmppd256_mask:
2786 IID = Intrinsic::x86_avx512_mask_cmp_pd_256;
2787 break;
2788 }
2789
2790 Function *Intr = CGM.getIntrinsic(IID);
2791 if (IsMaskFCmp) {
2792 unsigned NumElts =
2793 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
2794 Ops[3] = getMaskVecValue(*this, Ops[3], NumElts);
2795 Value *Cmp = Builder.CreateCall(Intr, Ops);
2796 return EmitX86MaskedCompareResult(*this, Cmp, NumElts, nullptr);
2797 }
2798
2799 return Builder.CreateCall(Intr, Ops);
2800 }
2801
2802 // Builtins without the _mask suffix return a vector of integers
2803 // of the same width as the input vectors
2804 if (IsMaskFCmp) {
2805 // We ignore SAE if strict FP is disabled. We only keep precise
2806 // exception behavior under strict FP.
2807 // NOTE: If strict FP does ever go through here a CGFPOptionsRAII
2808 // object will be required.
2809 unsigned NumElts =
2810 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements();
2811 Value *Cmp;
2812 if (IsSignaling)
2813 Cmp = Builder.CreateFCmpS(Pred, Ops[0], Ops[1]);
2814 else
2815 Cmp = Builder.CreateFCmp(Pred, Ops[0], Ops[1]);
2816 return EmitX86MaskedCompareResult(*this, Cmp, NumElts, Ops[3]);
2817 }
2818
2819 return getVectorFCmpIR(Pred, IsSignaling);
2820 }
2821
2822 // SSE scalar comparison intrinsics
2823 case X86::BI__builtin_ia32_cmpeqss:
2824 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 0);
2825 case X86::BI__builtin_ia32_cmpltss:
2826 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 1);
2827 case X86::BI__builtin_ia32_cmpless:
2828 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 2);
2829 case X86::BI__builtin_ia32_cmpunordss:
2830 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 3);
2831 case X86::BI__builtin_ia32_cmpneqss:
2832 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 4);
2833 case X86::BI__builtin_ia32_cmpnltss:
2834 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 5);
2835 case X86::BI__builtin_ia32_cmpnless:
2836 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 6);
2837 case X86::BI__builtin_ia32_cmpordss:
2838 return getCmpIntrinsicCall(Intrinsic::x86_sse_cmp_ss, 7);
2839 case X86::BI__builtin_ia32_cmpeqsd:
2840 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 0);
2841 case X86::BI__builtin_ia32_cmpltsd:
2842 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 1);
2843 case X86::BI__builtin_ia32_cmplesd:
2844 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 2);
2845 case X86::BI__builtin_ia32_cmpunordsd:
2846 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 3);
2847 case X86::BI__builtin_ia32_cmpneqsd:
2848 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 4);
2849 case X86::BI__builtin_ia32_cmpnltsd:
2850 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 5);
2851 case X86::BI__builtin_ia32_cmpnlesd:
2852 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 6);
2853 case X86::BI__builtin_ia32_cmpordsd:
2854 return getCmpIntrinsicCall(Intrinsic::x86_sse2_cmp_sd, 7);
2855
2856 // f16c half2float intrinsics
2857 case X86::BI__builtin_ia32_vcvtph2ps_mask:
2858 case X86::BI__builtin_ia32_vcvtph2ps256_mask:
2859 case X86::BI__builtin_ia32_vcvtph2ps512_mask: {
2860 CodeGenFunction::CGFPOptionsRAII FPOptsRAII(*this, E);
2861 return EmitX86CvtF16ToFloatExpr(*this, Ops, ConvertType(E->getType()));
2862 }
2863
2864 // AVX512 bf16 intrinsics
2865 case X86::BI__builtin_ia32_cvtneps2bf16_128_mask: {
2866 Ops[2] = getMaskVecValue(
2867 *this, Ops[2],
2868 cast<llvm::FixedVectorType>(Ops[0]->getType())->getNumElements());
2869 Intrinsic::ID IID = Intrinsic::x86_avx512bf16_mask_cvtneps2bf16_128;
2870 return Builder.CreateCall(CGM.getIntrinsic(IID), Ops);
2871 }
2872
2873 case X86::BI__builtin_ia32_cvtneps2bf16_256_mask:
2874 case X86::BI__builtin_ia32_cvtneps2bf16_512_mask: {
2875 Intrinsic::ID IID;
2876 switch (BuiltinID) {
2877 default: llvm_unreachable("Unsupported intrinsic!");
2878 case X86::BI__builtin_ia32_cvtneps2bf16_256_mask:
2879 IID = Intrinsic::x86_avx512bf16_cvtneps2bf16_256;
2880 break;
2881 case X86::BI__builtin_ia32_cvtneps2bf16_512_mask:
2882 IID = Intrinsic::x86_avx512bf16_cvtneps2bf16_512;
2883 break;
2884 }
2885 Value *Res = Builder.CreateCall(CGM.getIntrinsic(IID), Ops[0]);
2886 return EmitX86Select(*this, Ops[2], Res, Ops[1]);
2887 }
2888
2889 case X86::BI__cpuid:
2890 case X86::BI__cpuidex: {
2891 Value *FuncId = EmitScalarExpr(E->getArg(1));
2892 Value *SubFuncId = BuiltinID == X86::BI__cpuidex
2893 ? EmitScalarExpr(E->getArg(2))
2894 : llvm::ConstantInt::get(Int32Ty, 0);
2895
2896 llvm::StructType *CpuidRetTy =
2897 llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty, Int32Ty);
2898 llvm::FunctionType *FTy =
2899 llvm::FunctionType::get(CpuidRetTy, {Int32Ty, Int32Ty}, false);
2900
2901 StringRef Asm, Constraints;
2902 if (getTarget().getTriple().getArch() == llvm::Triple::x86) {
2903 Asm = "cpuid";
2904 Constraints = "={ax},={bx},={cx},={dx},{ax},{cx}";
2905 } else {
2906 // x86-64 uses %rbx as the base register, so preserve it.
2907 Asm = "xchgq %rbx, ${1:q}\n"
2908 "cpuid\n"
2909 "xchgq %rbx, ${1:q}";
2910 Constraints = "={ax},=r,={cx},={dx},0,2";
2911 }
2912
2913 llvm::InlineAsm *IA = llvm::InlineAsm::get(FTy, Asm, Constraints,
2914 /*hasSideEffects=*/false);
2915 Value *IACall = Builder.CreateCall(IA, {FuncId, SubFuncId});
2916 Value *BasePtr = EmitScalarExpr(E->getArg(0));
2917 Value *Store = nullptr;
2918 for (unsigned i = 0; i < 4; i++) {
2919 Value *Extracted = Builder.CreateExtractValue(IACall, i);
2920 Value *StorePtr = Builder.CreateConstInBoundsGEP1_32(Int32Ty, BasePtr, i);
2921 Store = Builder.CreateAlignedStore(Extracted, StorePtr, getIntAlign());
2922 }
2923
2924 // Return the last store instruction to signal that we have emitted the
2925 // the intrinsic.
2926 return Store;
2927 }
2928
2929 case X86::BI__emul:
2930 case X86::BI__emulu: {
2931 llvm::Type *Int64Ty = llvm::IntegerType::get(getLLVMContext(), 64);
2932 bool isSigned = (BuiltinID == X86::BI__emul);
2933 Value *LHS = Builder.CreateIntCast(Ops[0], Int64Ty, isSigned);
2934 Value *RHS = Builder.CreateIntCast(Ops[1], Int64Ty, isSigned);
2935 return Builder.CreateMul(LHS, RHS, "", !isSigned, isSigned);
2936 }
2937 case X86::BI__mulh:
2938 case X86::BI__umulh:
2939 case X86::BI_mul128:
2940 case X86::BI_umul128: {
2941 llvm::Type *ResType = ConvertType(E->getType());
2942 llvm::Type *Int128Ty = llvm::IntegerType::get(getLLVMContext(), 128);
2943
2944 bool IsSigned = (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI_mul128);
2945 Value *LHS = Builder.CreateIntCast(Ops[0], Int128Ty, IsSigned);
2946 Value *RHS = Builder.CreateIntCast(Ops[1], Int128Ty, IsSigned);
2947
2948 Value *MulResult, *HigherBits;
2949 if (IsSigned) {
2950 MulResult = Builder.CreateNSWMul(LHS, RHS);
2951 HigherBits = Builder.CreateAShr(MulResult, 64);
2952 } else {
2953 MulResult = Builder.CreateNUWMul(LHS, RHS);
2954 HigherBits = Builder.CreateLShr(MulResult, 64);
2955 }
2956 HigherBits = Builder.CreateIntCast(HigherBits, ResType, IsSigned);
2957
2958 if (BuiltinID == X86::BI__mulh || BuiltinID == X86::BI__umulh)
2959 return HigherBits;
2960
2961 Address HighBitsAddress = EmitPointerWithAlignment(E->getArg(2));
2962 Builder.CreateStore(HigherBits, HighBitsAddress);
2963 return Builder.CreateIntCast(MulResult, ResType, IsSigned);
2964 }
2965
2966 case X86::BI__faststorefence: {
2967 return Builder.CreateFence(llvm::AtomicOrdering::SequentiallyConsistent,
2968 llvm::SyncScope::System);
2969 }
2970 case X86::BI__shiftleft128:
2971 case X86::BI__shiftright128: {
2972 llvm::Function *F = CGM.getIntrinsic(
2973 BuiltinID == X86::BI__shiftleft128 ? Intrinsic::fshl : Intrinsic::fshr,
2974 Int64Ty);
2975 // Flip low/high ops and zero-extend amount to matching type.
2976 // shiftleft128(Low, High, Amt) -> fshl(High, Low, Amt)
2977 // shiftright128(Low, High, Amt) -> fshr(High, Low, Amt)
2978 std::swap(Ops[0], Ops[1]);
2979 Ops[2] = Builder.CreateZExt(Ops[2], Int64Ty);
2980 return Builder.CreateCall(F, Ops);
2981 }
2982
2983 case X86::BI_AddressOfReturnAddress: {
2984 Function *F =
2985 CGM.getIntrinsic(Intrinsic::addressofreturnaddress, AllocaInt8PtrTy);
2986 return Builder.CreateCall(F);
2987 }
2988 case X86::BI__stosb: {
2989 // We treat __stosb as a volatile memset - it may not generate "rep stosb"
2990 // instruction, but it will create a memset that won't be optimized away.
2991 return Builder.CreateMemSet(Ops[0], Ops[1], Ops[2], Align(1), true);
2992 }
2993 case X86::BI__ud2:
2994 // llvm.trap makes a ud2a instruction on x86.
2995 return EmitTrapCall(Intrinsic::trap);
2996 case X86::BI__int2c: {
2997 // This syscall signals a driver assertion failure in x86 NT kernels.
2998 llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
2999 llvm::InlineAsm *IA =
3000 llvm::InlineAsm::get(FTy, "int $$0x2c", "", /*hasSideEffects=*/true);
3001 llvm::AttributeList NoReturnAttr = llvm::AttributeList::get(
3002 getLLVMContext(), llvm::AttributeList::FunctionIndex,
3003 llvm::Attribute::NoReturn);
3004 llvm::CallInst *CI = Builder.CreateCall(IA);
3005 CI->setAttributes(NoReturnAttr);
3006 return CI;
3007 }
3008 case X86::BI__readfsbyte:
3009 case X86::BI__readfsword:
3010 case X86::BI__readfsdword:
3011 case X86::BI__readfsqword: {
3012 llvm::Type *IntTy = ConvertType(E->getType());
3013 Value *Ptr = Builder.CreateIntToPtr(
3014 Ops[0], llvm::PointerType::get(getLLVMContext(), 257));
3015 LoadInst *Load = Builder.CreateAlignedLoad(
3016 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
3017 Load->setVolatile(true);
3018 return Load;
3019 }
3020 case X86::BI__readgsbyte:
3021 case X86::BI__readgsword:
3022 case X86::BI__readgsdword:
3023 case X86::BI__readgsqword: {
3024 llvm::Type *IntTy = ConvertType(E->getType());
3025 Value *Ptr = Builder.CreateIntToPtr(
3026 Ops[0], llvm::PointerType::get(getLLVMContext(), 256));
3027 LoadInst *Load = Builder.CreateAlignedLoad(
3028 IntTy, Ptr, getContext().getTypeAlignInChars(E->getType()));
3029 Load->setVolatile(true);
3030 return Load;
3031 }
3032 case X86::BI__builtin_ia32_encodekey128_u32: {
3033 Intrinsic::ID IID = Intrinsic::x86_encodekey128;
3034
3035 Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), {Ops[0], Ops[1]});
3036
3037 for (int i = 0; i < 3; ++i) {
3038 Value *Extract = Builder.CreateExtractValue(Call, i + 1);
3039 Value *Ptr = Builder.CreateConstGEP1_32(Int8Ty, Ops[2], i * 16);
3040 Builder.CreateAlignedStore(Extract, Ptr, Align(1));
3041 }
3042
3043 return Builder.CreateExtractValue(Call, 0);
3044 }
3045 case X86::BI__builtin_ia32_encodekey256_u32: {
3046 Intrinsic::ID IID = Intrinsic::x86_encodekey256;
3047
3048 Value *Call =
3049 Builder.CreateCall(CGM.getIntrinsic(IID), {Ops[0], Ops[1], Ops[2]});
3050
3051 for (int i = 0; i < 4; ++i) {
3052 Value *Extract = Builder.CreateExtractValue(Call, i + 1);
3053 Value *Ptr = Builder.CreateConstGEP1_32(Int8Ty, Ops[3], i * 16);
3054 Builder.CreateAlignedStore(Extract, Ptr, Align(1));
3055 }
3056
3057 return Builder.CreateExtractValue(Call, 0);
3058 }
3059 case X86::BI__builtin_ia32_aesenc128kl_u8:
3060 case X86::BI__builtin_ia32_aesdec128kl_u8:
3061 case X86::BI__builtin_ia32_aesenc256kl_u8:
3062 case X86::BI__builtin_ia32_aesdec256kl_u8: {
3063 Intrinsic::ID IID;
3064 StringRef BlockName;
3065 switch (BuiltinID) {
3066 default:
3067 llvm_unreachable("Unexpected builtin");
3068 case X86::BI__builtin_ia32_aesenc128kl_u8:
3069 IID = Intrinsic::x86_aesenc128kl;
3070 BlockName = "aesenc128kl";
3071 break;
3072 case X86::BI__builtin_ia32_aesdec128kl_u8:
3073 IID = Intrinsic::x86_aesdec128kl;
3074 BlockName = "aesdec128kl";
3075 break;
3076 case X86::BI__builtin_ia32_aesenc256kl_u8:
3077 IID = Intrinsic::x86_aesenc256kl;
3078 BlockName = "aesenc256kl";
3079 break;
3080 case X86::BI__builtin_ia32_aesdec256kl_u8:
3081 IID = Intrinsic::x86_aesdec256kl;
3082 BlockName = "aesdec256kl";
3083 break;
3084 }
3085
3086 Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), {Ops[1], Ops[2]});
3087
3088 BasicBlock *NoError =
3089 createBasicBlock(BlockName + "_no_error", this->CurFn);
3090 BasicBlock *Error = createBasicBlock(BlockName + "_error", this->CurFn);
3091 BasicBlock *End = createBasicBlock(BlockName + "_end", this->CurFn);
3092
3093 Value *Ret = Builder.CreateExtractValue(Call, 0);
3094 Value *Succ = Builder.CreateTrunc(Ret, Builder.getInt1Ty());
3095 Value *Out = Builder.CreateExtractValue(Call, 1);
3096 Builder.CreateCondBr(Succ, NoError, Error);
3097
3098 Builder.SetInsertPoint(NoError);
3099 Builder.CreateDefaultAlignedStore(Out, Ops[0]);
3100 Builder.CreateBr(End);
3101
3102 Builder.SetInsertPoint(Error);
3103 Constant *Zero = llvm::Constant::getNullValue(Out->getType());
3104 Builder.CreateDefaultAlignedStore(Zero, Ops[0]);
3105 Builder.CreateBr(End);
3106
3107 Builder.SetInsertPoint(End);
3108 return Builder.CreateExtractValue(Call, 0);
3109 }
3110 case X86::BI__builtin_ia32_aesencwide128kl_u8:
3111 case X86::BI__builtin_ia32_aesdecwide128kl_u8:
3112 case X86::BI__builtin_ia32_aesencwide256kl_u8:
3113 case X86::BI__builtin_ia32_aesdecwide256kl_u8: {
3114 Intrinsic::ID IID;
3115 StringRef BlockName;
3116 switch (BuiltinID) {
3117 case X86::BI__builtin_ia32_aesencwide128kl_u8:
3118 IID = Intrinsic::x86_aesencwide128kl;
3119 BlockName = "aesencwide128kl";
3120 break;
3121 case X86::BI__builtin_ia32_aesdecwide128kl_u8:
3122 IID = Intrinsic::x86_aesdecwide128kl;
3123 BlockName = "aesdecwide128kl";
3124 break;
3125 case X86::BI__builtin_ia32_aesencwide256kl_u8:
3126 IID = Intrinsic::x86_aesencwide256kl;
3127 BlockName = "aesencwide256kl";
3128 break;
3129 case X86::BI__builtin_ia32_aesdecwide256kl_u8:
3130 IID = Intrinsic::x86_aesdecwide256kl;
3131 BlockName = "aesdecwide256kl";
3132 break;
3133 }
3134
3135 llvm::Type *Ty = FixedVectorType::get(Builder.getInt64Ty(), 2);
3136 Value *InOps[9];
3137 InOps[0] = Ops[2];
3138 for (int i = 0; i != 8; ++i) {
3139 Value *Ptr = Builder.CreateConstGEP1_32(Ty, Ops[1], i);
3140 InOps[i + 1] = Builder.CreateAlignedLoad(Ty, Ptr, Align(16));
3141 }
3142
3143 Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), InOps);
3144
3145 BasicBlock *NoError =
3146 createBasicBlock(BlockName + "_no_error", this->CurFn);
3147 BasicBlock *Error = createBasicBlock(BlockName + "_error", this->CurFn);
3148 BasicBlock *End = createBasicBlock(BlockName + "_end", this->CurFn);
3149
3150 Value *Ret = Builder.CreateExtractValue(Call, 0);
3151 Value *Succ = Builder.CreateTrunc(Ret, Builder.getInt1Ty());
3152 Builder.CreateCondBr(Succ, NoError, Error);
3153
3154 Builder.SetInsertPoint(NoError);
3155 for (int i = 0; i != 8; ++i) {
3156 Value *Extract = Builder.CreateExtractValue(Call, i + 1);
3157 Value *Ptr = Builder.CreateConstGEP1_32(Ty, Ops[0], i);
3158 Builder.CreateAlignedStore(Extract, Ptr, Align(16));
3159 }
3160 Builder.CreateBr(End);
3161
3162 Builder.SetInsertPoint(Error);
3163 for (int i = 0; i != 8; ++i) {
3164 Constant *Zero = llvm::Constant::getNullValue(Ty);
3165 Value *Ptr = Builder.CreateConstGEP1_32(Ty, Ops[0], i);
3166 Builder.CreateAlignedStore(Zero, Ptr, Align(16));
3167 }
3168 Builder.CreateBr(End);
3169
3170 Builder.SetInsertPoint(End);
3171 return Builder.CreateExtractValue(Call, 0);
3172 }
3173 case X86::BI__builtin_ia32_vfcmaddcph512_mask:
3174 IsConjFMA = true;
3175 [[fallthrough]];
3176 case X86::BI__builtin_ia32_vfmaddcph512_mask: {
3177 Intrinsic::ID IID = IsConjFMA
3178 ? Intrinsic::x86_avx512fp16_mask_vfcmadd_cph_512
3179 : Intrinsic::x86_avx512fp16_mask_vfmadd_cph_512;
3180 Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), Ops);
3181 return EmitX86Select(*this, Ops[3], Call, Ops[0]);
3182 }
3183 case X86::BI__builtin_ia32_vfcmaddcsh_round_mask:
3184 IsConjFMA = true;
3185 [[fallthrough]];
3186 case X86::BI__builtin_ia32_vfmaddcsh_round_mask: {
3187 Intrinsic::ID IID = IsConjFMA ? Intrinsic::x86_avx512fp16_mask_vfcmadd_csh
3188 : Intrinsic::x86_avx512fp16_mask_vfmadd_csh;
3189 Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), Ops);
3190 Value *And = Builder.CreateAnd(Ops[3], llvm::ConstantInt::get(Int8Ty, 1));
3191 return EmitX86Select(*this, And, Call, Ops[0]);
3192 }
3193 case X86::BI__builtin_ia32_vfcmaddcsh_round_mask3:
3194 IsConjFMA = true;
3195 [[fallthrough]];
3196 case X86::BI__builtin_ia32_vfmaddcsh_round_mask3: {
3197 Intrinsic::ID IID = IsConjFMA ? Intrinsic::x86_avx512fp16_mask_vfcmadd_csh
3198 : Intrinsic::x86_avx512fp16_mask_vfmadd_csh;
3199 Value *Call = Builder.CreateCall(CGM.getIntrinsic(IID), Ops);
3200 static constexpr int Mask[] = {0, 5, 6, 7};
3201 return Builder.CreateShuffleVector(Call, Ops[2], Mask);
3202 }
3203 case X86::BI__builtin_ia32_prefetchi:
3204 return Builder.CreateCall(
3205 CGM.getIntrinsic(Intrinsic::prefetch, Ops[0]->getType()),
3206 {Ops[0], llvm::ConstantInt::get(Int32Ty, 0), Ops[1],
3207 llvm::ConstantInt::get(Int32Ty, 0)});
3208 }
3209}
#define X86_CPU_TYPE(ENUM, STR, ABI_VALUE)
#define X86_CPU_SUBTYPE(ENUM, STR, ABI_VALUE)
#define X86_VENDOR(ENUM, STRING, ABI_VALUE)
static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, mlir::Location loc, mlir::Value mask, unsigned numElems)
#define INTRINSIC_X86_XSAVE_ID(NAME)
static Value * EmitX86CompressExpand(CodeGenFunction &CGF, ArrayRef< Value * > Ops, bool IsCompress)
Definition X86.cpp:135
static Value * EmitX86MaskedCompare(CodeGenFunction &CGF, unsigned CC, bool Signed, ArrayRef< Value * > Ops)
Definition X86.cpp:282
static Value * EmitScalarFMAExpr(CodeGenFunction &CGF, const CallExpr *E, MutableArrayRef< Value * > Ops, Value *Upper, bool ZeroMask=false, unsigned PTIdx=0, bool NegAcc=false)
Definition X86.cpp:468
static Value * EmitX86ExpandLoad(CodeGenFunction &CGF, ArrayRef< Value * > Ops)
Definition X86.cpp:123
static Value * EmitX86MaskedLoad(CodeGenFunction &CGF, ArrayRef< Value * > Ops, Align Alignment)
Definition X86.cpp:112
static Value * EmitX86MaskedStore(CodeGenFunction &CGF, ArrayRef< Value * > Ops, Align Alignment)
Definition X86.cpp:101
static Value * EmitX86Muldq(CodeGenFunction &CGF, bool IsSigned, ArrayRef< Value * > Ops)
Definition X86.cpp:526
static Value * EmitX86CvtF16ToFloatExpr(CodeGenFunction &CGF, ArrayRef< Value * > Ops, llvm::Type *DstTy)
Definition X86.cpp:598
static Value * EmitX86SExtMask(CodeGenFunction &CGF, Value *Op, llvm::Type *DstTy)
Definition X86.cpp:583
static Value * EmitX86FunnelShift(CodeGenFunction &CGF, Value *Op0, Value *Op1, Value *Amt, bool IsRight)
Definition X86.cpp:173
static Value * EmitX86MaskLogic(CodeGenFunction &CGF, Instruction::BinaryOps Opc, ArrayRef< Value * > Ops, bool InvertLHS=false)
Definition X86.cpp:159
static Value * EmitX86Select(CodeGenFunction &CGF, Value *Mask, Value *Op0, Value *Op1)
Definition X86.cpp:231
static Value * EmitX86FMAExpr(CodeGenFunction &CGF, const CallExpr *E, ArrayRef< Value * > Ops, unsigned BuiltinID, bool IsAddSub)
Definition X86.cpp:343
static Value * getMaskVecValue(CodeGenFunction &CGF, Value *Mask, unsigned NumElts)
Definition X86.cpp:25
static Value * EmitX86MaskedCompareResult(CodeGenFunction &CGF, Value *Cmp, unsigned NumElts, Value *MaskIn)
Definition X86.cpp:259
static Value * EmitX86CompressStore(CodeGenFunction &CGF, ArrayRef< Value * > Ops)
Definition X86.cpp:148
static Value * EmitX86vpcom(CodeGenFunction &CGF, ArrayRef< Value * > Ops, bool IsSigned)
Definition X86.cpp:191
static Value * EmitX86ConvertToMask(CodeGenFunction &CGF, Value *In)
Definition X86.cpp:317
static Value * EmitX86Ternlog(CodeGenFunction &CGF, bool ZeroMask, ArrayRef< Value * > Ops)
Definition X86.cpp:555
static Value * emitX86RoundImmediate(CodeGenFunction &CGF, Value *X, unsigned RoundingControl)
Emit rounding for the value X according to the rounding RoundingControl based on bits 0 and 1.
Definition X86.cpp:47
static Value * EmitX86ConvertIntToFp(CodeGenFunction &CGF, const CallExpr *E, ArrayRef< Value * > Ops, bool IsSigned)
Definition X86.cpp:322
static Value * EmitX86ScalarSelect(CodeGenFunction &CGF, Value *Mask, Value *Op0, Value *Op1)
Definition X86.cpp:245
TokenType getType() const
Returns the token's type, e.g.
#define X(type, name)
Definition Value.h:97
#define ENUM(NAME, LIT)
static StringRef getTriple(const Command &Job)
Enumerates target-specific builtins in their own namespaces within namespace clang.
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const
Return the type for the specified builtin.
@ GE_None
No error.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:3012
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
Definition Expr.h:3216
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
Definition Expr.h:3203
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:58
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition Address.h:128
llvm::PointerType * getType() const
Return the type of the pointer value.
Definition Address.h:204
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID, bool EnsureInsertPoint=true)
Emit a call to trap or debugtrap.
Definition CGExpr.cpp:4732
llvm::Value * EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx, const CallExpr *E)
llvm::Type * ConvertType(QualType T)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const TargetInfo & getTarget() const
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
Definition CGExpr.cpp:236
llvm::Value * EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E)
llvm::Value * EmitX86BuiltinExpr(unsigned BuiltinID, const CallExpr *E)
Definition X86.cpp:751
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
Definition CGExpr.cpp:1661
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::LLVMContext & getLLVMContext()
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
An abstract representation of an aligned address.
Definition Address.h:42
llvm::Value * getPointer() const
Definition Address.h:66
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition Expr.cpp:3134
QualType getType() const
Definition Expr.h:146
QualType getType() const
Definition Value.cpp:238
std::optional< MSVCIntrin > translateX86ToMsvcIntrin(unsigned BuiltinID)
Top level wrappers for InstallAPI frontend operations.
@ Asm
Assembly: we accept this only so that we can preprocess it.
@ Default
Set to the current date and time.
@ Result
The result type of a method or function.
Definition TypeBase.h:906
U cast(CodeGen::Address addr)
Definition Address.h:327
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64