clang 22.0.0git
CIRGenBuiltinX86.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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 x86/x86_64 Builtin calls as CIR or a function
10// call to be later resolved.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CIRGenBuilder.h"
15#include "CIRGenFunction.h"
16#include "CIRGenModule.h"
17#include "mlir/IR/Location.h"
18#include "mlir/IR/ValueRange.h"
23#include "llvm/Support/ErrorHandling.h"
24
25using namespace clang;
26using namespace clang::CIRGen;
27
28template <typename... Operands>
29static mlir::Value emitIntrinsicCallOp(CIRGenBuilderTy &builder,
30 mlir::Location loc, const StringRef str,
31 const mlir::Type &resTy,
32 Operands &&...op) {
33 return cir::LLVMIntrinsicCallOp::create(builder, loc,
34 builder.getStringAttr(str), resTy,
35 std::forward<Operands>(op)...)
36 .getResult();
37}
38
39// OG has unordered comparison as a form of optimization in addition to
40// ordered comparison, while CIR doesn't.
41//
42// This means that we can't encode the comparison code of UGT (unordered
43// greater than), at least not at the CIR level.
44//
45// The boolean shouldInvert compensates for this.
46// For example: to get to the comparison code UGT, we pass in
47// emitVectorFCmp (OLE, shouldInvert = true) since OLE is the inverse of UGT.
48
49// There are several ways to support this otherwise:
50// - register extra CmpOpKind for unordered comparison types and build the
51// translation code for
52// to go from CIR -> LLVM dialect. Notice we get this naturally with
53// shouldInvert, benefiting from existing infrastructure, albeit having to
54// generate an extra `not` at CIR).
55// - Just add extra comparison code to a new VecCmpOpKind instead of
56// cluttering CmpOpKind.
57// - Add a boolean in VecCmpOp to indicate if it's doing unordered or ordered
58// comparison
59// - Just emit the intrinsics call instead of calling this helper, see how the
60// LLVM lowering handles this.
61static mlir::Value emitVectorFCmp(CIRGenBuilderTy &builder,
63 mlir::Location loc, cir::CmpOpKind pred,
64 bool shouldInvert) {
66 // TODO(cir): Add isSignaling boolean once emitConstrainedFPCall implemented
68 mlir::Value cmp = builder.createVecCompare(loc, pred, ops[0], ops[1]);
69 mlir::Value bitCast = builder.createBitcast(
70 shouldInvert ? builder.createNot(cmp) : cmp, ops[0].getType());
71 return bitCast;
72}
73
74static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, mlir::Location loc,
75 mlir::Value mask, unsigned numElems) {
76 auto maskTy = cir::VectorType::get(
77 builder.getUIntNTy(1), cast<cir::IntType>(mask.getType()).getWidth());
78 mlir::Value maskVec = builder.createBitcast(mask, maskTy);
79
80 // If we have less than 8 elements, then the starting mask was an i8 and
81 // we need to extract down to the right number of elements.
82 if (numElems < 8) {
84 mlir::Type i32Ty = builder.getSInt32Ty();
85 for (auto i : llvm::seq<unsigned>(0, numElems))
86 indices.push_back(cir::IntAttr::get(i32Ty, i));
87
88 maskVec = builder.createVecShuffle(loc, maskVec, maskVec, indices);
89 }
90 return maskVec;
91}
92
93// Builds the VecShuffleOp for pshuflw and pshufhw x86 builtins.
94//
95// The vector is split into lanes of 8 word elements (16 bits). The lower or
96// upper half of each lane, controlled by `isLow`, is shuffled in the following
97// way: The immediate is truncated to 8 bits, separated into 4 2-bit fields. The
98// i-th field's value represents the resulting index of the i-th element in the
99// half lane after shuffling. The other half of the lane remains unchanged.
100static cir::VecShuffleOp emitPshufWord(CIRGenBuilderTy &builder,
101 const mlir::Value vec,
102 const mlir::Value immediate,
103 const mlir::Location loc,
104 const bool isLow) {
105 uint32_t imm = CIRGenFunction::getZExtIntValueFromConstOp(immediate);
106
107 auto vecTy = cast<cir::VectorType>(vec.getType());
108 unsigned numElts = vecTy.getSize();
109
110 unsigned firstHalfStart = isLow ? 0 : 4;
111 unsigned secondHalfStart = 4 - firstHalfStart;
112
113 // Splat the 8-bits of immediate 4 times to help the loop wrap around.
114 imm = (imm & 0xff) * 0x01010101;
115
116 int64_t indices[32];
117 for (unsigned l = 0; l != numElts; l += 8) {
118 for (unsigned i = firstHalfStart; i != firstHalfStart + 4; ++i) {
119 indices[l + i] = l + (imm & 3) + firstHalfStart;
120 imm >>= 2;
121 }
122 for (unsigned i = secondHalfStart; i != secondHalfStart + 4; ++i)
123 indices[l + i] = l + i;
124 }
125
126 return builder.createVecShuffle(loc, vec, ArrayRef(indices, numElts));
127}
128
129// Builds the shuffle mask for pshufd and shufpd/shufps x86 builtins.
130// The shuffle mask is written to outIndices.
131static void
132computeFullLaneShuffleMask(CIRGenFunction &cgf, const mlir::Value vec,
133 uint32_t imm, const bool isShufP,
134 llvm::SmallVectorImpl<int64_t> &outIndices) {
135 auto vecTy = cast<cir::VectorType>(vec.getType());
136 unsigned numElts = vecTy.getSize();
137 unsigned numLanes = cgf.cgm.getDataLayout().getTypeSizeInBits(vecTy) / 128;
138 unsigned numLaneElts = numElts / numLanes;
139
140 // Splat the 8-bits of immediate 4 times to help the loop wrap around.
141 imm = (imm & 0xff) * 0x01010101;
142
143 for (unsigned l = 0; l != numElts; l += numLaneElts) {
144 for (unsigned i = 0; i != numLaneElts; ++i) {
145 uint32_t idx = imm % numLaneElts;
146 imm /= numLaneElts;
147 if (isShufP && i >= (numLaneElts / 2))
148 idx += numElts;
149 outIndices[l + i] = l + idx;
150 }
151 }
152
153 outIndices.resize(numElts);
154}
155static mlir::Value emitX86CompressExpand(CIRGenBuilderTy &builder,
156 mlir::Location loc, mlir::Value source,
157 mlir::Value mask,
158 mlir::Value inputVector,
159 const std::string &id) {
160 auto resultTy = cast<cir::VectorType>(mask.getType());
161 mlir::Value maskValue = getMaskVecValue(
162 builder, loc, inputVector, cast<cir::VectorType>(resultTy).getSize());
163 return emitIntrinsicCallOp(builder, loc, id, resultTy,
164 mlir::ValueRange{source, mask, maskValue});
165}
166
167static mlir::Value getBoolMaskVecValue(CIRGenBuilderTy &builder,
168 mlir::Location loc, mlir::Value mask,
169 unsigned numElems) {
170
171 cir::BoolType boolTy = builder.getBoolTy();
172 auto maskTy = cir::VectorType::get(
173 boolTy, cast<cir::IntType>(mask.getType()).getWidth());
174 mlir::Value maskVec = builder.createBitcast(mask, maskTy);
175
176 if (numElems < 8) {
178 indices.reserve(numElems);
179 mlir::Type i32Ty = builder.getSInt32Ty();
180 for (auto i : llvm::seq<unsigned>(0, numElems))
181 indices.push_back(cir::IntAttr::get(i32Ty, i));
182
183 maskVec = builder.createVecShuffle(loc, maskVec, maskVec, indices);
184 }
185 return maskVec;
186}
187
188static mlir::Value emitX86Select(CIRGenBuilderTy &builder, mlir::Location loc,
189 mlir::Value mask, mlir::Value op0,
190 mlir::Value op1) {
191 auto constOp = mlir::dyn_cast_or_null<cir::ConstantOp>(mask.getDefiningOp());
192 // If the mask is all ones just return first argument.
193 if (constOp && constOp.isAllOnesValue())
194 return op0;
195
196 mask = getBoolMaskVecValue(builder, loc, mask,
197 cast<cir::VectorType>(op0.getType()).getSize());
198
199 return builder.createSelect(loc, mask, op0, op1);
200}
201
202static mlir::Value emitX86MaskAddLogic(CIRGenBuilderTy &builder,
203 mlir::Location loc,
204 const std::string &intrinsicName,
206
207 auto intTy = cast<cir::IntType>(ops[0].getType());
208 unsigned numElts = intTy.getWidth();
209 mlir::Value lhsVec = getMaskVecValue(builder, loc, ops[0], numElts);
210 mlir::Value rhsVec = getMaskVecValue(builder, loc, ops[1], numElts);
211 mlir::Type vecTy = lhsVec.getType();
212 mlir::Value resVec = emitIntrinsicCallOp(builder, loc, intrinsicName, vecTy,
213 mlir::ValueRange{lhsVec, rhsVec});
214 return builder.createBitcast(resVec, ops[0].getType());
215}
216
217static mlir::Value emitX86MaskUnpack(CIRGenBuilderTy &builder,
218 mlir::Location loc,
219 const std::string &intrinsicName,
221 unsigned numElems = cast<cir::IntType>(ops[0].getType()).getWidth();
222
223 // Convert both operands to mask vectors.
224 mlir::Value lhs = getMaskVecValue(builder, loc, ops[0], numElems);
225 mlir::Value rhs = getMaskVecValue(builder, loc, ops[1], numElems);
226
227 mlir::Type i32Ty = builder.getSInt32Ty();
228
229 // Create indices for extracting the first half of each vector.
231 for (auto i : llvm::seq<unsigned>(0, numElems / 2))
232 halfIndices.push_back(cir::IntAttr::get(i32Ty, i));
233
234 // Extract first half of each vector. This gives better codegen than
235 // doing it in a single shuffle.
236 mlir::Value lhsHalf = builder.createVecShuffle(loc, lhs, lhs, halfIndices);
237 mlir::Value rhsHalf = builder.createVecShuffle(loc, rhs, rhs, halfIndices);
238
239 // Create indices for concatenating the vectors.
240 // NOTE: Operands are swapped to match the intrinsic definition.
241 // After the half extraction, both vectors have numElems/2 elements.
242 // In createVecShuffle(rhsHalf, lhsHalf, indices), indices [0..numElems/2-1]
243 // select from rhsHalf, and indices [numElems/2..numElems-1] select from
244 // lhsHalf.
246 for (auto i : llvm::seq<unsigned>(0, numElems))
247 concatIndices.push_back(cir::IntAttr::get(i32Ty, i));
248
249 // Concat the vectors (RHS first, then LHS).
250 mlir::Value res =
251 builder.createVecShuffle(loc, rhsHalf, lhsHalf, concatIndices);
252 return builder.createBitcast(res, ops[0].getType());
253}
254
255static mlir::Value emitX86MaskLogic(CIRGenBuilderTy &builder,
256 mlir::Location loc,
257 cir::BinOpKind binOpKind,
259 bool invertLHS = false) {
260 unsigned numElts = cast<cir::IntType>(ops[0].getType()).getWidth();
261 mlir::Value lhs = getMaskVecValue(builder, loc, ops[0], numElts);
262 mlir::Value rhs = getMaskVecValue(builder, loc, ops[1], numElts);
263
264 if (invertLHS)
265 lhs = builder.createNot(lhs);
266 return builder.createBitcast(builder.createBinop(loc, lhs, binOpKind, rhs),
267 ops[0].getType());
268}
269
270static mlir::Value emitX86MaskTest(CIRGenBuilderTy &builder, mlir::Location loc,
271 const std::string &intrinsicName,
273 auto intTy = cast<cir::IntType>(ops[0].getType());
274 unsigned numElts = intTy.getWidth();
275 mlir::Value lhsVec = getMaskVecValue(builder, loc, ops[0], numElts);
276 mlir::Value rhsVec = getMaskVecValue(builder, loc, ops[1], numElts);
277 mlir::Type resTy = builder.getSInt32Ty();
278 return emitIntrinsicCallOp(builder, loc, intrinsicName, resTy,
279 mlir::ValueRange{lhsVec, rhsVec});
280}
281
282static mlir::Value emitVecInsert(CIRGenBuilderTy &builder, mlir::Location loc,
283 mlir::Value vec, mlir::Value value,
284 mlir::Value indexOp) {
285 unsigned numElts = cast<cir::VectorType>(vec.getType()).getSize();
286
287 uint64_t index =
288 indexOp.getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
289
290 index &= numElts - 1;
291
292 cir::ConstantOp indexVal = builder.getUInt64(index, loc);
293
294 return cir::VecInsertOp::create(builder, loc, vec, value, indexVal);
295}
296
297static mlir::Value emitX86FunnelShift(CIRGenBuilderTy &builder,
298 mlir::Location location, mlir::Value &op0,
299 mlir::Value &op1, mlir::Value &amt,
300 bool isRight) {
301 mlir::Type op0Ty = op0.getType();
302
303 // Amount may be scalar immediate, in which case create a splat vector.
304 // Funnel shifts amounts are treated as modulo and types are all power-of-2
305 // so we only care about the lowest log2 bits anyway.
306 if (amt.getType() != op0Ty) {
307 auto vecTy = mlir::cast<cir::VectorType>(op0Ty);
308 uint64_t numElems = vecTy.getSize();
309
310 auto amtTy = mlir::cast<cir::IntType>(amt.getType());
311 auto vecElemTy = mlir::cast<cir::IntType>(vecTy.getElementType());
312
313 // If signed, cast to the same width but unsigned first to
314 // ensure zero-extension when casting to a bigger unsigned `vecElemeTy`.
315 if (amtTy.isSigned()) {
316 cir::IntType unsignedAmtTy = builder.getUIntNTy(amtTy.getWidth());
317 amt = builder.createIntCast(amt, unsignedAmtTy);
318 }
319 cir::IntType unsignedVecElemType = builder.getUIntNTy(vecElemTy.getWidth());
320 amt = builder.createIntCast(amt, unsignedVecElemType);
321 amt = cir::VecSplatOp::create(
322 builder, location, cir::VectorType::get(unsignedVecElemType, numElems),
323 amt);
324 }
325
326 const StringRef intrinsicName = isRight ? "fshr" : "fshl";
327 return emitIntrinsicCallOp(builder, location, intrinsicName, op0Ty,
328 mlir::ValueRange{op0, op1, amt});
329}
330
331static mlir::Value emitX86Muldq(CIRGenBuilderTy &builder, mlir::Location loc,
332 bool isSigned,
334 unsigned opTypePrimitiveSizeInBits) {
335 mlir::Type ty = cir::VectorType::get(builder.getSInt64Ty(),
336 opTypePrimitiveSizeInBits / 64);
337 mlir::Value lhs = builder.createBitcast(loc, ops[0], ty);
338 mlir::Value rhs = builder.createBitcast(loc, ops[1], ty);
339 if (isSigned) {
340 cir::ConstantOp shiftAmt =
341 builder.getConstant(loc, cir::IntAttr::get(builder.getSInt64Ty(), 32));
342 cir::VecSplatOp shiftSplatVecOp =
343 cir::VecSplatOp::create(builder, loc, ty, shiftAmt.getResult());
344 mlir::Value shiftSplatValue = shiftSplatVecOp.getResult();
345 // In CIR, right-shift operations are automatically lowered to either an
346 // arithmetic or logical shift depending on the operand type. The purpose
347 // of the shifts here is to propagate the sign bit of the 32-bit input
348 // into the upper bits of each vector lane.
349 lhs = builder.createShift(loc, lhs, shiftSplatValue, true);
350 lhs = builder.createShift(loc, lhs, shiftSplatValue, false);
351 rhs = builder.createShift(loc, rhs, shiftSplatValue, true);
352 rhs = builder.createShift(loc, rhs, shiftSplatValue, false);
353 } else {
354 cir::ConstantOp maskScalar = builder.getConstant(
355 loc, cir::IntAttr::get(builder.getSInt64Ty(), 0xffffffff));
356 cir::VecSplatOp mask =
357 cir::VecSplatOp::create(builder, loc, ty, maskScalar.getResult());
358 // Clear the upper bits
359 lhs = builder.createAnd(loc, lhs, mask);
360 rhs = builder.createAnd(loc, rhs, mask);
361 }
362 return builder.createMul(loc, lhs, rhs);
363}
364
365static mlir::Value emitX86vpcom(CIRGenBuilderTy &builder, mlir::Location loc,
367 bool isSigned) {
368 mlir::Value op0 = ops[0];
369 mlir::Value op1 = ops[1];
370
371 cir::VectorType ty = cast<cir::VectorType>(op0.getType());
372 cir::IntType elementTy = cast<cir::IntType>(ty.getElementType());
373
374 uint64_t imm = CIRGenFunction::getZExtIntValueFromConstOp(ops[2]) & 0x7;
375
376 cir::CmpOpKind pred;
377 switch (imm) {
378 case 0x0:
379 pred = cir::CmpOpKind::lt;
380 break;
381 case 0x1:
382 pred = cir::CmpOpKind::le;
383 break;
384 case 0x2:
385 pred = cir::CmpOpKind::gt;
386 break;
387 case 0x3:
388 pred = cir::CmpOpKind::ge;
389 break;
390 case 0x4:
391 pred = cir::CmpOpKind::eq;
392 break;
393 case 0x5:
394 pred = cir::CmpOpKind::ne;
395 break;
396 case 0x6:
397 return builder.getNullValue(ty, loc); // FALSE
398 case 0x7: {
399 llvm::APInt allOnes = llvm::APInt::getAllOnes(elementTy.getWidth());
400 return cir::VecSplatOp::create(
401 builder, loc, ty,
402 builder.getConstAPInt(loc, elementTy, allOnes)); // TRUE
403 }
404 default:
405 llvm_unreachable("Unexpected XOP vpcom/vpcomu predicate");
406 }
407
408 if ((!isSigned && elementTy.isSigned()) ||
409 (isSigned && elementTy.isUnsigned())) {
410 elementTy = elementTy.isSigned() ? builder.getUIntNTy(elementTy.getWidth())
411 : builder.getSIntNTy(elementTy.getWidth());
412 ty = cir::VectorType::get(elementTy, ty.getSize());
413 op0 = builder.createBitcast(op0, ty);
414 op1 = builder.createBitcast(op1, ty);
415 }
416
417 return builder.createVecCompare(loc, pred, op0, op1);
418}
419
420mlir::Value CIRGenFunction::emitX86BuiltinExpr(unsigned builtinID,
421 const CallExpr *expr) {
422 if (builtinID == Builtin::BI__builtin_cpu_is) {
423 cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_is");
424 return {};
425 }
426 if (builtinID == Builtin::BI__builtin_cpu_supports) {
427 cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_supports");
428 return {};
429 }
430 if (builtinID == Builtin::BI__builtin_cpu_init) {
431 cgm.errorNYI(expr->getSourceRange(), "__builtin_cpu_init");
432 return {};
433 }
434
435 // Handle MSVC intrinsics before argument evaluation to prevent double
436 // evaluation.
438
439 // Find out if any arguments are required to be integer constant expressions.
441
442 // The operands of the builtin call
444
445 // `ICEArguments` is a bitmap indicating whether the argument at the i-th bit
446 // is required to be a constant integer expression.
447 unsigned iceArguments = 0;
449 getContext().GetBuiltinType(builtinID, error, &iceArguments);
450 assert(error == ASTContext::GE_None && "Error while getting builtin type.");
451
452 for (auto [idx, arg] : llvm::enumerate(expr->arguments()))
453 ops.push_back(emitScalarOrConstFoldImmArg(iceArguments, idx, arg));
454
455 CIRGenBuilderTy &builder = getBuilder();
456 mlir::Type voidTy = builder.getVoidTy();
457
458 switch (builtinID) {
459 default:
460 return {};
461 case X86::BI_mm_clflush:
462 return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()),
463 "x86.sse2.clflush", voidTy, ops[0]);
464 case X86::BI_mm_lfence:
465 return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()),
466 "x86.sse2.lfence", voidTy);
467 case X86::BI_mm_pause:
468 return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()),
469 "x86.sse2.pause", voidTy);
470 case X86::BI_mm_mfence:
471 return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()),
472 "x86.sse2.mfence", voidTy);
473 case X86::BI_mm_sfence:
474 return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()),
475 "x86.sse.sfence", voidTy);
476 case X86::BI_mm_prefetch:
477 case X86::BI__rdtsc:
478 case X86::BI__builtin_ia32_rdtscp: {
479 cgm.errorNYI(expr->getSourceRange(),
480 std::string("unimplemented X86 builtin call: ") +
481 getContext().BuiltinInfo.getName(builtinID));
482 return {};
483 }
484 case X86::BI__builtin_ia32_lzcnt_u16:
485 case X86::BI__builtin_ia32_lzcnt_u32:
486 case X86::BI__builtin_ia32_lzcnt_u64: {
487 mlir::Location loc = getLoc(expr->getExprLoc());
488 mlir::Value isZeroPoison = builder.getFalse(loc);
489 return emitIntrinsicCallOp(builder, loc, "ctlz", ops[0].getType(),
490 mlir::ValueRange{ops[0], isZeroPoison});
491 }
492 case X86::BI__builtin_ia32_tzcnt_u16:
493 case X86::BI__builtin_ia32_tzcnt_u32:
494 case X86::BI__builtin_ia32_tzcnt_u64: {
495 mlir::Location loc = getLoc(expr->getExprLoc());
496 mlir::Value isZeroPoison = builder.getFalse(loc);
497 return emitIntrinsicCallOp(builder, loc, "cttz", ops[0].getType(),
498 mlir::ValueRange{ops[0], isZeroPoison});
499 }
500 case X86::BI__builtin_ia32_undef128:
501 case X86::BI__builtin_ia32_undef256:
502 case X86::BI__builtin_ia32_undef512:
503 // The x86 definition of "undef" is not the same as the LLVM definition
504 // (PR32176). We leave optimizing away an unnecessary zero constant to the
505 // IR optimizer and backend.
506 // TODO: If we had a "freeze" IR instruction to generate a fixed undef
507 // value, we should use that here instead of a zero.
508 return builder.getNullValue(convertType(expr->getType()),
509 getLoc(expr->getExprLoc()));
510 case X86::BI__builtin_ia32_vec_ext_v4hi:
511 case X86::BI__builtin_ia32_vec_ext_v16qi:
512 case X86::BI__builtin_ia32_vec_ext_v8hi:
513 case X86::BI__builtin_ia32_vec_ext_v4si:
514 case X86::BI__builtin_ia32_vec_ext_v4sf:
515 case X86::BI__builtin_ia32_vec_ext_v2di:
516 case X86::BI__builtin_ia32_vec_ext_v32qi:
517 case X86::BI__builtin_ia32_vec_ext_v16hi:
518 case X86::BI__builtin_ia32_vec_ext_v8si:
519 case X86::BI__builtin_ia32_vec_ext_v4di: {
520 unsigned numElts = cast<cir::VectorType>(ops[0].getType()).getSize();
521
522 uint64_t index = getZExtIntValueFromConstOp(ops[1]);
523 index &= numElts - 1;
524
525 cir::ConstantOp indexVal =
526 builder.getUInt64(index, getLoc(expr->getExprLoc()));
527
528 // These builtins exist so we can ensure the index is an ICE and in range.
529 // Otherwise we could just do this in the header file.
530 return cir::VecExtractOp::create(builder, getLoc(expr->getExprLoc()),
531 ops[0], indexVal);
532 }
533 case X86::BI__builtin_ia32_vec_set_v4hi:
534 case X86::BI__builtin_ia32_vec_set_v16qi:
535 case X86::BI__builtin_ia32_vec_set_v8hi:
536 case X86::BI__builtin_ia32_vec_set_v4si:
537 case X86::BI__builtin_ia32_vec_set_v2di:
538 case X86::BI__builtin_ia32_vec_set_v32qi:
539 case X86::BI__builtin_ia32_vec_set_v16hi:
540 case X86::BI__builtin_ia32_vec_set_v8si:
541 case X86::BI__builtin_ia32_vec_set_v4di: {
542 return emitVecInsert(builder, getLoc(expr->getExprLoc()), ops[0], ops[1],
543 ops[2]);
544 }
545 case X86::BI__builtin_ia32_kunpckhi:
546 return emitX86MaskUnpack(builder, getLoc(expr->getExprLoc()),
547 "x86.avx512.kunpackb", ops);
548 case X86::BI__builtin_ia32_kunpcksi:
549 return emitX86MaskUnpack(builder, getLoc(expr->getExprLoc()),
550 "x86.avx512.kunpackw", ops);
551 case X86::BI__builtin_ia32_kunpckdi:
552 return emitX86MaskUnpack(builder, getLoc(expr->getExprLoc()),
553 "x86.avx512.kunpackd", ops);
554 case X86::BI_mm_setcsr:
555 case X86::BI__builtin_ia32_ldmxcsr: {
556 mlir::Location loc = getLoc(expr->getExprLoc());
557 Address tmp = createMemTemp(expr->getArg(0)->getType(), loc);
558 builder.createStore(loc, ops[0], tmp);
559 return emitIntrinsicCallOp(builder, loc, "x86.sse.ldmxcsr",
560 builder.getVoidTy(), tmp.getPointer());
561 }
562 case X86::BI_mm_getcsr:
563 case X86::BI__builtin_ia32_stmxcsr: {
564 mlir::Location loc = getLoc(expr->getExprLoc());
565 Address tmp = createMemTemp(expr->getType(), loc);
566 emitIntrinsicCallOp(builder, loc, "x86.sse.stmxcsr", builder.getVoidTy(),
567 tmp.getPointer());
568 return builder.createLoad(loc, tmp);
569 }
570 case X86::BI__builtin_ia32_xsave:
571 case X86::BI__builtin_ia32_xsave64:
572 case X86::BI__builtin_ia32_xrstor:
573 case X86::BI__builtin_ia32_xrstor64:
574 case X86::BI__builtin_ia32_xsaveopt:
575 case X86::BI__builtin_ia32_xsaveopt64:
576 case X86::BI__builtin_ia32_xrstors:
577 case X86::BI__builtin_ia32_xrstors64:
578 case X86::BI__builtin_ia32_xsavec:
579 case X86::BI__builtin_ia32_xsavec64:
580 case X86::BI__builtin_ia32_xsaves:
581 case X86::BI__builtin_ia32_xsaves64:
582 case X86::BI__builtin_ia32_xsetbv:
583 case X86::BI_xsetbv: {
584 mlir::Location loc = getLoc(expr->getExprLoc());
585 StringRef intrinsicName;
586 switch (builtinID) {
587 default:
588 llvm_unreachable("Unexpected builtin");
589 case X86::BI__builtin_ia32_xsave:
590 intrinsicName = "x86.xsave";
591 break;
592 case X86::BI__builtin_ia32_xsave64:
593 intrinsicName = "x86.xsave64";
594 break;
595 case X86::BI__builtin_ia32_xrstor:
596 intrinsicName = "x86.xrstor";
597 break;
598 case X86::BI__builtin_ia32_xrstor64:
599 intrinsicName = "x86.xrstor64";
600 break;
601 case X86::BI__builtin_ia32_xsaveopt:
602 intrinsicName = "x86.xsaveopt";
603 break;
604 case X86::BI__builtin_ia32_xsaveopt64:
605 intrinsicName = "x86.xsaveopt64";
606 break;
607 case X86::BI__builtin_ia32_xrstors:
608 intrinsicName = "x86.xrstors";
609 break;
610 case X86::BI__builtin_ia32_xrstors64:
611 intrinsicName = "x86.xrstors64";
612 break;
613 case X86::BI__builtin_ia32_xsavec:
614 intrinsicName = "x86.xsavec";
615 break;
616 case X86::BI__builtin_ia32_xsavec64:
617 intrinsicName = "x86.xsavec64";
618 break;
619 case X86::BI__builtin_ia32_xsaves:
620 intrinsicName = "x86.xsaves";
621 break;
622 case X86::BI__builtin_ia32_xsaves64:
623 intrinsicName = "x86.xsaves64";
624 break;
625 case X86::BI__builtin_ia32_xsetbv:
626 case X86::BI_xsetbv:
627 intrinsicName = "x86.xsetbv";
628 break;
629 }
630
631 // The xsave family of instructions take a 64-bit mask that specifies
632 // which processor state components to save/restore. The hardware expects
633 // this mask split into two 32-bit registers: EDX (high 32 bits) and
634 // EAX (low 32 bits).
635 mlir::Type i32Ty = builder.getSInt32Ty();
636
637 // Mhi = (uint32_t)(ops[1] >> 32) - extract high 32 bits via right shift
638 cir::ConstantOp shift32 = builder.getSInt64(32, loc);
639 mlir::Value mhi = builder.createShift(loc, ops[1], shift32.getResult(),
640 /*isShiftLeft=*/false);
641 mhi = builder.createIntCast(mhi, i32Ty);
642
643 // Mlo = (uint32_t)ops[1] - extract low 32 bits by truncation
644 mlir::Value mlo = builder.createIntCast(ops[1], i32Ty);
645
646 return emitIntrinsicCallOp(builder, loc, intrinsicName, voidTy,
647 mlir::ValueRange{ops[0], mhi, mlo});
648 }
649 case X86::BI__builtin_ia32_xgetbv:
650 case X86::BI_xgetbv:
651 // xgetbv reads the extended control register specified by ops[0] (ECX)
652 // and returns the 64-bit value
653 return emitIntrinsicCallOp(builder, getLoc(expr->getExprLoc()),
654 "x86.xgetbv", builder.getUInt64Ty(), ops[0]);
655 case X86::BI__builtin_ia32_storedqudi128_mask:
656 case X86::BI__builtin_ia32_storedqusi128_mask:
657 case X86::BI__builtin_ia32_storedquhi128_mask:
658 case X86::BI__builtin_ia32_storedquqi128_mask:
659 case X86::BI__builtin_ia32_storeupd128_mask:
660 case X86::BI__builtin_ia32_storeups128_mask:
661 case X86::BI__builtin_ia32_storedqudi256_mask:
662 case X86::BI__builtin_ia32_storedqusi256_mask:
663 case X86::BI__builtin_ia32_storedquhi256_mask:
664 case X86::BI__builtin_ia32_storedquqi256_mask:
665 case X86::BI__builtin_ia32_storeupd256_mask:
666 case X86::BI__builtin_ia32_storeups256_mask:
667 case X86::BI__builtin_ia32_storedqudi512_mask:
668 case X86::BI__builtin_ia32_storedqusi512_mask:
669 case X86::BI__builtin_ia32_storedquhi512_mask:
670 case X86::BI__builtin_ia32_storedquqi512_mask:
671 case X86::BI__builtin_ia32_storeupd512_mask:
672 case X86::BI__builtin_ia32_storeups512_mask:
673 case X86::BI__builtin_ia32_storesbf16128_mask:
674 case X86::BI__builtin_ia32_storesh128_mask:
675 case X86::BI__builtin_ia32_storess128_mask:
676 case X86::BI__builtin_ia32_storesd128_mask:
677 case X86::BI__builtin_ia32_cvtmask2b128:
678 case X86::BI__builtin_ia32_cvtmask2b256:
679 case X86::BI__builtin_ia32_cvtmask2b512:
680 case X86::BI__builtin_ia32_cvtmask2w128:
681 case X86::BI__builtin_ia32_cvtmask2w256:
682 case X86::BI__builtin_ia32_cvtmask2w512:
683 case X86::BI__builtin_ia32_cvtmask2d128:
684 case X86::BI__builtin_ia32_cvtmask2d256:
685 case X86::BI__builtin_ia32_cvtmask2d512:
686 case X86::BI__builtin_ia32_cvtmask2q128:
687 case X86::BI__builtin_ia32_cvtmask2q256:
688 case X86::BI__builtin_ia32_cvtmask2q512:
689 case X86::BI__builtin_ia32_cvtb2mask128:
690 case X86::BI__builtin_ia32_cvtb2mask256:
691 case X86::BI__builtin_ia32_cvtb2mask512:
692 case X86::BI__builtin_ia32_cvtw2mask128:
693 case X86::BI__builtin_ia32_cvtw2mask256:
694 case X86::BI__builtin_ia32_cvtw2mask512:
695 case X86::BI__builtin_ia32_cvtd2mask128:
696 case X86::BI__builtin_ia32_cvtd2mask256:
697 case X86::BI__builtin_ia32_cvtd2mask512:
698 case X86::BI__builtin_ia32_cvtq2mask128:
699 case X86::BI__builtin_ia32_cvtq2mask256:
700 case X86::BI__builtin_ia32_cvtq2mask512:
701 case X86::BI__builtin_ia32_cvtdq2ps512_mask:
702 case X86::BI__builtin_ia32_cvtqq2ps512_mask:
703 case X86::BI__builtin_ia32_cvtqq2pd512_mask:
704 case X86::BI__builtin_ia32_vcvtw2ph512_mask:
705 case X86::BI__builtin_ia32_vcvtdq2ph512_mask:
706 case X86::BI__builtin_ia32_vcvtqq2ph512_mask:
707 case X86::BI__builtin_ia32_cvtudq2ps512_mask:
708 case X86::BI__builtin_ia32_cvtuqq2ps512_mask:
709 case X86::BI__builtin_ia32_cvtuqq2pd512_mask:
710 case X86::BI__builtin_ia32_vcvtuw2ph512_mask:
711 case X86::BI__builtin_ia32_vcvtudq2ph512_mask:
712 case X86::BI__builtin_ia32_vcvtuqq2ph512_mask:
713 case X86::BI__builtin_ia32_vfmaddsh3_mask:
714 case X86::BI__builtin_ia32_vfmaddss3_mask:
715 case X86::BI__builtin_ia32_vfmaddsd3_mask:
716 case X86::BI__builtin_ia32_vfmaddsh3_maskz:
717 case X86::BI__builtin_ia32_vfmaddss3_maskz:
718 case X86::BI__builtin_ia32_vfmaddsd3_maskz:
719 case X86::BI__builtin_ia32_vfmaddsh3_mask3:
720 case X86::BI__builtin_ia32_vfmaddss3_mask3:
721 case X86::BI__builtin_ia32_vfmaddsd3_mask3:
722 case X86::BI__builtin_ia32_vfmsubsh3_mask3:
723 case X86::BI__builtin_ia32_vfmsubss3_mask3:
724 case X86::BI__builtin_ia32_vfmsubsd3_mask3:
725 case X86::BI__builtin_ia32_vfmaddph512_mask:
726 case X86::BI__builtin_ia32_vfmaddph512_maskz:
727 case X86::BI__builtin_ia32_vfmaddph512_mask3:
728 case X86::BI__builtin_ia32_vfmaddps512_mask:
729 case X86::BI__builtin_ia32_vfmaddps512_maskz:
730 case X86::BI__builtin_ia32_vfmaddps512_mask3:
731 case X86::BI__builtin_ia32_vfmsubps512_mask3:
732 case X86::BI__builtin_ia32_vfmaddpd512_mask:
733 case X86::BI__builtin_ia32_vfmaddpd512_maskz:
734 case X86::BI__builtin_ia32_vfmaddpd512_mask3:
735 case X86::BI__builtin_ia32_vfmsubpd512_mask3:
736 case X86::BI__builtin_ia32_vfmsubph512_mask3:
737 case X86::BI__builtin_ia32_vfmaddsubph512_mask:
738 case X86::BI__builtin_ia32_vfmaddsubph512_maskz:
739 case X86::BI__builtin_ia32_vfmaddsubph512_mask3:
740 case X86::BI__builtin_ia32_vfmsubaddph512_mask3:
741 case X86::BI__builtin_ia32_vfmaddsubps512_mask:
742 case X86::BI__builtin_ia32_vfmaddsubps512_maskz:
743 case X86::BI__builtin_ia32_vfmaddsubps512_mask3:
744 case X86::BI__builtin_ia32_vfmsubaddps512_mask3:
745 case X86::BI__builtin_ia32_vfmaddsubpd512_mask:
746 case X86::BI__builtin_ia32_vfmaddsubpd512_maskz:
747 case X86::BI__builtin_ia32_vfmaddsubpd512_mask3:
748 case X86::BI__builtin_ia32_vfmsubaddpd512_mask3:
749 case X86::BI__builtin_ia32_movdqa32store128_mask:
750 case X86::BI__builtin_ia32_movdqa64store128_mask:
751 case X86::BI__builtin_ia32_storeaps128_mask:
752 case X86::BI__builtin_ia32_storeapd128_mask:
753 case X86::BI__builtin_ia32_movdqa32store256_mask:
754 case X86::BI__builtin_ia32_movdqa64store256_mask:
755 case X86::BI__builtin_ia32_storeaps256_mask:
756 case X86::BI__builtin_ia32_storeapd256_mask:
757 case X86::BI__builtin_ia32_movdqa32store512_mask:
758 case X86::BI__builtin_ia32_movdqa64store512_mask:
759 case X86::BI__builtin_ia32_storeaps512_mask:
760 case X86::BI__builtin_ia32_storeapd512_mask:
761 case X86::BI__builtin_ia32_loadups128_mask:
762 case X86::BI__builtin_ia32_loadups256_mask:
763 case X86::BI__builtin_ia32_loadups512_mask:
764 case X86::BI__builtin_ia32_loadupd128_mask:
765 case X86::BI__builtin_ia32_loadupd256_mask:
766 case X86::BI__builtin_ia32_loadupd512_mask:
767 case X86::BI__builtin_ia32_loaddquqi128_mask:
768 case X86::BI__builtin_ia32_loaddquqi256_mask:
769 case X86::BI__builtin_ia32_loaddquqi512_mask:
770 case X86::BI__builtin_ia32_loaddquhi128_mask:
771 case X86::BI__builtin_ia32_loaddquhi256_mask:
772 case X86::BI__builtin_ia32_loaddquhi512_mask:
773 case X86::BI__builtin_ia32_loaddqusi128_mask:
774 case X86::BI__builtin_ia32_loaddqusi256_mask:
775 case X86::BI__builtin_ia32_loaddqusi512_mask:
776 case X86::BI__builtin_ia32_loaddqudi128_mask:
777 case X86::BI__builtin_ia32_loaddqudi256_mask:
778 case X86::BI__builtin_ia32_loaddqudi512_mask:
779 case X86::BI__builtin_ia32_loadsbf16128_mask:
780 case X86::BI__builtin_ia32_loadsh128_mask:
781 case X86::BI__builtin_ia32_loadss128_mask:
782 case X86::BI__builtin_ia32_loadsd128_mask:
783 case X86::BI__builtin_ia32_loadaps128_mask:
784 case X86::BI__builtin_ia32_loadaps256_mask:
785 case X86::BI__builtin_ia32_loadaps512_mask:
786 case X86::BI__builtin_ia32_loadapd128_mask:
787 case X86::BI__builtin_ia32_loadapd256_mask:
788 case X86::BI__builtin_ia32_loadapd512_mask:
789 case X86::BI__builtin_ia32_movdqa32load128_mask:
790 case X86::BI__builtin_ia32_movdqa32load256_mask:
791 case X86::BI__builtin_ia32_movdqa32load512_mask:
792 case X86::BI__builtin_ia32_movdqa64load128_mask:
793 case X86::BI__builtin_ia32_movdqa64load256_mask:
794 case X86::BI__builtin_ia32_movdqa64load512_mask:
795 case X86::BI__builtin_ia32_expandloaddf128_mask:
796 case X86::BI__builtin_ia32_expandloaddf256_mask:
797 case X86::BI__builtin_ia32_expandloaddf512_mask:
798 case X86::BI__builtin_ia32_expandloadsf128_mask:
799 case X86::BI__builtin_ia32_expandloadsf256_mask:
800 case X86::BI__builtin_ia32_expandloadsf512_mask:
801 case X86::BI__builtin_ia32_expandloaddi128_mask:
802 case X86::BI__builtin_ia32_expandloaddi256_mask:
803 case X86::BI__builtin_ia32_expandloaddi512_mask:
804 case X86::BI__builtin_ia32_expandloadsi128_mask:
805 case X86::BI__builtin_ia32_expandloadsi256_mask:
806 case X86::BI__builtin_ia32_expandloadsi512_mask:
807 case X86::BI__builtin_ia32_expandloadhi128_mask:
808 case X86::BI__builtin_ia32_expandloadhi256_mask:
809 case X86::BI__builtin_ia32_expandloadhi512_mask:
810 case X86::BI__builtin_ia32_expandloadqi128_mask:
811 case X86::BI__builtin_ia32_expandloadqi256_mask:
812 case X86::BI__builtin_ia32_expandloadqi512_mask:
813 case X86::BI__builtin_ia32_compressstoredf128_mask:
814 case X86::BI__builtin_ia32_compressstoredf256_mask:
815 case X86::BI__builtin_ia32_compressstoredf512_mask:
816 case X86::BI__builtin_ia32_compressstoresf128_mask:
817 case X86::BI__builtin_ia32_compressstoresf256_mask:
818 case X86::BI__builtin_ia32_compressstoresf512_mask:
819 case X86::BI__builtin_ia32_compressstoredi128_mask:
820 case X86::BI__builtin_ia32_compressstoredi256_mask:
821 case X86::BI__builtin_ia32_compressstoredi512_mask:
822 case X86::BI__builtin_ia32_compressstoresi128_mask:
823 case X86::BI__builtin_ia32_compressstoresi256_mask:
824 case X86::BI__builtin_ia32_compressstoresi512_mask:
825 case X86::BI__builtin_ia32_compressstorehi128_mask:
826 case X86::BI__builtin_ia32_compressstorehi256_mask:
827 case X86::BI__builtin_ia32_compressstorehi512_mask:
828 case X86::BI__builtin_ia32_compressstoreqi128_mask:
829 case X86::BI__builtin_ia32_compressstoreqi256_mask:
830 case X86::BI__builtin_ia32_compressstoreqi512_mask:
831 cgm.errorNYI(expr->getSourceRange(),
832 std::string("unimplemented X86 builtin call: ") +
833 getContext().BuiltinInfo.getName(builtinID));
834 return {};
835 case X86::BI__builtin_ia32_expanddf128_mask:
836 case X86::BI__builtin_ia32_expanddf256_mask:
837 case X86::BI__builtin_ia32_expanddf512_mask:
838 case X86::BI__builtin_ia32_expandsf128_mask:
839 case X86::BI__builtin_ia32_expandsf256_mask:
840 case X86::BI__builtin_ia32_expandsf512_mask:
841 case X86::BI__builtin_ia32_expanddi128_mask:
842 case X86::BI__builtin_ia32_expanddi256_mask:
843 case X86::BI__builtin_ia32_expanddi512_mask:
844 case X86::BI__builtin_ia32_expandsi128_mask:
845 case X86::BI__builtin_ia32_expandsi256_mask:
846 case X86::BI__builtin_ia32_expandsi512_mask:
847 case X86::BI__builtin_ia32_expandhi128_mask:
848 case X86::BI__builtin_ia32_expandhi256_mask:
849 case X86::BI__builtin_ia32_expandhi512_mask:
850 case X86::BI__builtin_ia32_expandqi128_mask:
851 case X86::BI__builtin_ia32_expandqi256_mask:
852 case X86::BI__builtin_ia32_expandqi512_mask: {
853 mlir::Location loc = getLoc(expr->getExprLoc());
854 return emitX86CompressExpand(builder, loc, ops[0], ops[1], ops[2],
855 "x86.avx512.mask.expand");
856 }
857 case X86::BI__builtin_ia32_compressdf128_mask:
858 case X86::BI__builtin_ia32_compressdf256_mask:
859 case X86::BI__builtin_ia32_compressdf512_mask:
860 case X86::BI__builtin_ia32_compresssf128_mask:
861 case X86::BI__builtin_ia32_compresssf256_mask:
862 case X86::BI__builtin_ia32_compresssf512_mask:
863 case X86::BI__builtin_ia32_compressdi128_mask:
864 case X86::BI__builtin_ia32_compressdi256_mask:
865 case X86::BI__builtin_ia32_compressdi512_mask:
866 case X86::BI__builtin_ia32_compresssi128_mask:
867 case X86::BI__builtin_ia32_compresssi256_mask:
868 case X86::BI__builtin_ia32_compresssi512_mask:
869 case X86::BI__builtin_ia32_compresshi128_mask:
870 case X86::BI__builtin_ia32_compresshi256_mask:
871 case X86::BI__builtin_ia32_compresshi512_mask:
872 case X86::BI__builtin_ia32_compressqi128_mask:
873 case X86::BI__builtin_ia32_compressqi256_mask:
874 case X86::BI__builtin_ia32_compressqi512_mask: {
875 mlir::Location loc = getLoc(expr->getExprLoc());
876 return emitX86CompressExpand(builder, loc, ops[0], ops[1], ops[2],
877 "x86.avx512.mask.compress");
878 }
879 case X86::BI__builtin_ia32_gather3div2df:
880 case X86::BI__builtin_ia32_gather3div2di:
881 case X86::BI__builtin_ia32_gather3div4df:
882 case X86::BI__builtin_ia32_gather3div4di:
883 case X86::BI__builtin_ia32_gather3div4sf:
884 case X86::BI__builtin_ia32_gather3div4si:
885 case X86::BI__builtin_ia32_gather3div8sf:
886 case X86::BI__builtin_ia32_gather3div8si:
887 case X86::BI__builtin_ia32_gather3siv2df:
888 case X86::BI__builtin_ia32_gather3siv2di:
889 case X86::BI__builtin_ia32_gather3siv4df:
890 case X86::BI__builtin_ia32_gather3siv4di:
891 case X86::BI__builtin_ia32_gather3siv4sf:
892 case X86::BI__builtin_ia32_gather3siv4si:
893 case X86::BI__builtin_ia32_gather3siv8sf:
894 case X86::BI__builtin_ia32_gather3siv8si:
895 case X86::BI__builtin_ia32_gathersiv8df:
896 case X86::BI__builtin_ia32_gathersiv16sf:
897 case X86::BI__builtin_ia32_gatherdiv8df:
898 case X86::BI__builtin_ia32_gatherdiv16sf:
899 case X86::BI__builtin_ia32_gathersiv8di:
900 case X86::BI__builtin_ia32_gathersiv16si:
901 case X86::BI__builtin_ia32_gatherdiv8di:
902 case X86::BI__builtin_ia32_gatherdiv16si: {
903 StringRef intrinsicName;
904 switch (builtinID) {
905 default:
906 llvm_unreachable("Unexpected builtin");
907 case X86::BI__builtin_ia32_gather3div2df:
908 intrinsicName = "x86.avx512.mask.gather3div2.df";
909 break;
910 case X86::BI__builtin_ia32_gather3div2di:
911 intrinsicName = "x86.avx512.mask.gather3div2.di";
912 break;
913 case X86::BI__builtin_ia32_gather3div4df:
914 intrinsicName = "x86.avx512.mask.gather3div4.df";
915 break;
916 case X86::BI__builtin_ia32_gather3div4di:
917 intrinsicName = "x86.avx512.mask.gather3div4.di";
918 break;
919 case X86::BI__builtin_ia32_gather3div4sf:
920 intrinsicName = "x86.avx512.mask.gather3div4.sf";
921 break;
922 case X86::BI__builtin_ia32_gather3div4si:
923 intrinsicName = "x86.avx512.mask.gather3div4.si";
924 break;
925 case X86::BI__builtin_ia32_gather3div8sf:
926 intrinsicName = "x86.avx512.mask.gather3div8.sf";
927 break;
928 case X86::BI__builtin_ia32_gather3div8si:
929 intrinsicName = "x86.avx512.mask.gather3div8.si";
930 break;
931 case X86::BI__builtin_ia32_gather3siv2df:
932 intrinsicName = "x86.avx512.mask.gather3siv2.df";
933 break;
934 case X86::BI__builtin_ia32_gather3siv2di:
935 intrinsicName = "x86.avx512.mask.gather3siv2.di";
936 break;
937 case X86::BI__builtin_ia32_gather3siv4df:
938 intrinsicName = "x86.avx512.mask.gather3siv4.df";
939 break;
940 case X86::BI__builtin_ia32_gather3siv4di:
941 intrinsicName = "x86.avx512.mask.gather3siv4.di";
942 break;
943 case X86::BI__builtin_ia32_gather3siv4sf:
944 intrinsicName = "x86.avx512.mask.gather3siv4.sf";
945 break;
946 case X86::BI__builtin_ia32_gather3siv4si:
947 intrinsicName = "x86.avx512.mask.gather3siv4.si";
948 break;
949 case X86::BI__builtin_ia32_gather3siv8sf:
950 intrinsicName = "x86.avx512.mask.gather3siv8.sf";
951 break;
952 case X86::BI__builtin_ia32_gather3siv8si:
953 intrinsicName = "x86.avx512.mask.gather3siv8.si";
954 break;
955 case X86::BI__builtin_ia32_gathersiv8df:
956 intrinsicName = "x86.avx512.mask.gather.dpd.512";
957 break;
958 case X86::BI__builtin_ia32_gathersiv16sf:
959 intrinsicName = "x86.avx512.mask.gather.dps.512";
960 break;
961 case X86::BI__builtin_ia32_gatherdiv8df:
962 intrinsicName = "x86.avx512.mask.gather.qpd.512";
963 break;
964 case X86::BI__builtin_ia32_gatherdiv16sf:
965 intrinsicName = "x86.avx512.mask.gather.qps.512";
966 break;
967 case X86::BI__builtin_ia32_gathersiv8di:
968 intrinsicName = "x86.avx512.mask.gather.dpq.512";
969 break;
970 case X86::BI__builtin_ia32_gathersiv16si:
971 intrinsicName = "x86.avx512.mask.gather.dpi.512";
972 break;
973 case X86::BI__builtin_ia32_gatherdiv8di:
974 intrinsicName = "x86.avx512.mask.gather.qpq.512";
975 break;
976 case X86::BI__builtin_ia32_gatherdiv16si:
977 intrinsicName = "x86.avx512.mask.gather.qpi.512";
978 break;
979 }
980
981 mlir::Location loc = getLoc(expr->getExprLoc());
982 unsigned minElts =
983 std::min(cast<cir::VectorType>(ops[0].getType()).getSize(),
984 cast<cir::VectorType>(ops[2].getType()).getSize());
985 ops[3] = getMaskVecValue(builder, loc, ops[3], minElts);
986 return emitIntrinsicCallOp(builder, loc, intrinsicName,
987 convertType(expr->getType()), ops);
988 }
989 case X86::BI__builtin_ia32_scattersiv8df:
990 case X86::BI__builtin_ia32_scattersiv16sf:
991 case X86::BI__builtin_ia32_scatterdiv8df:
992 case X86::BI__builtin_ia32_scatterdiv16sf:
993 case X86::BI__builtin_ia32_scattersiv8di:
994 case X86::BI__builtin_ia32_scattersiv16si:
995 case X86::BI__builtin_ia32_scatterdiv8di:
996 case X86::BI__builtin_ia32_scatterdiv16si:
997 case X86::BI__builtin_ia32_scatterdiv2df:
998 case X86::BI__builtin_ia32_scatterdiv2di:
999 case X86::BI__builtin_ia32_scatterdiv4df:
1000 case X86::BI__builtin_ia32_scatterdiv4di:
1001 case X86::BI__builtin_ia32_scatterdiv4sf:
1002 case X86::BI__builtin_ia32_scatterdiv4si:
1003 case X86::BI__builtin_ia32_scatterdiv8sf:
1004 case X86::BI__builtin_ia32_scatterdiv8si:
1005 case X86::BI__builtin_ia32_scattersiv2df:
1006 case X86::BI__builtin_ia32_scattersiv2di:
1007 case X86::BI__builtin_ia32_scattersiv4df:
1008 case X86::BI__builtin_ia32_scattersiv4di:
1009 case X86::BI__builtin_ia32_scattersiv4sf:
1010 case X86::BI__builtin_ia32_scattersiv4si:
1011 case X86::BI__builtin_ia32_scattersiv8sf:
1012 case X86::BI__builtin_ia32_scattersiv8si: {
1013 llvm::StringRef intrinsicName;
1014 switch (builtinID) {
1015 default:
1016 llvm_unreachable("Unexpected builtin");
1017 case X86::BI__builtin_ia32_scattersiv8df:
1018 intrinsicName = "x86.avx512.mask.scatter.dpd.512";
1019 break;
1020 case X86::BI__builtin_ia32_scattersiv16sf:
1021 intrinsicName = "x86.avx512.mask.scatter.dps.512";
1022 break;
1023 case X86::BI__builtin_ia32_scatterdiv8df:
1024 intrinsicName = "x86.avx512.mask.scatter.qpd.512";
1025 break;
1026 case X86::BI__builtin_ia32_scatterdiv16sf:
1027 intrinsicName = "x86.avx512.mask.scatter.qps.512";
1028 break;
1029 case X86::BI__builtin_ia32_scattersiv8di:
1030 intrinsicName = "x86.avx512.mask.scatter.dpq.512";
1031 break;
1032 case X86::BI__builtin_ia32_scattersiv16si:
1033 intrinsicName = "x86.avx512.mask.scatter.dpi.512";
1034 break;
1035 case X86::BI__builtin_ia32_scatterdiv8di:
1036 intrinsicName = "x86.avx512.mask.scatter.qpq.512";
1037 break;
1038 case X86::BI__builtin_ia32_scatterdiv16si:
1039 intrinsicName = "x86.avx512.mask.scatter.qpi.512";
1040 break;
1041 case X86::BI__builtin_ia32_scatterdiv2df:
1042 intrinsicName = "x86.avx512.mask.scatterdiv2.df";
1043 break;
1044 case X86::BI__builtin_ia32_scatterdiv2di:
1045 intrinsicName = "x86.avx512.mask.scatterdiv2.di";
1046 break;
1047 case X86::BI__builtin_ia32_scatterdiv4df:
1048 intrinsicName = "x86.avx512.mask.scatterdiv4.df";
1049 break;
1050 case X86::BI__builtin_ia32_scatterdiv4di:
1051 intrinsicName = "x86.avx512.mask.scatterdiv4.di";
1052 break;
1053 case X86::BI__builtin_ia32_scatterdiv4sf:
1054 intrinsicName = "x86.avx512.mask.scatterdiv4.sf";
1055 break;
1056 case X86::BI__builtin_ia32_scatterdiv4si:
1057 intrinsicName = "x86.avx512.mask.scatterdiv4.si";
1058 break;
1059 case X86::BI__builtin_ia32_scatterdiv8sf:
1060 intrinsicName = "x86.avx512.mask.scatterdiv8.sf";
1061 break;
1062 case X86::BI__builtin_ia32_scatterdiv8si:
1063 intrinsicName = "x86.avx512.mask.scatterdiv8.si";
1064 break;
1065 case X86::BI__builtin_ia32_scattersiv2df:
1066 intrinsicName = "x86.avx512.mask.scattersiv2.df";
1067 break;
1068 case X86::BI__builtin_ia32_scattersiv2di:
1069 intrinsicName = "x86.avx512.mask.scattersiv2.di";
1070 break;
1071 case X86::BI__builtin_ia32_scattersiv4df:
1072 intrinsicName = "x86.avx512.mask.scattersiv4.df";
1073 break;
1074 case X86::BI__builtin_ia32_scattersiv4di:
1075 intrinsicName = "x86.avx512.mask.scattersiv4.di";
1076 break;
1077 case X86::BI__builtin_ia32_scattersiv4sf:
1078 intrinsicName = "x86.avx512.mask.scattersiv4.sf";
1079 break;
1080 case X86::BI__builtin_ia32_scattersiv4si:
1081 intrinsicName = "x86.avx512.mask.scattersiv4.si";
1082 break;
1083 case X86::BI__builtin_ia32_scattersiv8sf:
1084 intrinsicName = "x86.avx512.mask.scattersiv8.sf";
1085 break;
1086 case X86::BI__builtin_ia32_scattersiv8si:
1087 intrinsicName = "x86.avx512.mask.scattersiv8.si";
1088 break;
1089 }
1090
1091 mlir::Location loc = getLoc(expr->getExprLoc());
1092 unsigned minElts =
1093 std::min(cast<cir::VectorType>(ops[2].getType()).getSize(),
1094 cast<cir::VectorType>(ops[3].getType()).getSize());
1095 ops[1] = getMaskVecValue(builder, loc, ops[1], minElts);
1096
1097 return emitIntrinsicCallOp(builder, loc, intrinsicName,
1098 convertType(expr->getType()), ops);
1099 }
1100 case X86::BI__builtin_ia32_vextractf128_pd256:
1101 case X86::BI__builtin_ia32_vextractf128_ps256:
1102 case X86::BI__builtin_ia32_vextractf128_si256:
1103 case X86::BI__builtin_ia32_extract128i256:
1104 case X86::BI__builtin_ia32_extractf64x4_mask:
1105 case X86::BI__builtin_ia32_extractf32x4_mask:
1106 case X86::BI__builtin_ia32_extracti64x4_mask:
1107 case X86::BI__builtin_ia32_extracti32x4_mask:
1108 case X86::BI__builtin_ia32_extractf32x8_mask:
1109 case X86::BI__builtin_ia32_extracti32x8_mask:
1110 case X86::BI__builtin_ia32_extractf32x4_256_mask:
1111 case X86::BI__builtin_ia32_extracti32x4_256_mask:
1112 case X86::BI__builtin_ia32_extractf64x2_256_mask:
1113 case X86::BI__builtin_ia32_extracti64x2_256_mask:
1114 case X86::BI__builtin_ia32_extractf64x2_512_mask:
1115 case X86::BI__builtin_ia32_extracti64x2_512_mask: {
1116 mlir::Location loc = getLoc(expr->getExprLoc());
1117 cir::VectorType dstTy = cast<cir::VectorType>(convertType(expr->getType()));
1118 unsigned numElts = dstTy.getSize();
1119 unsigned srcNumElts = cast<cir::VectorType>(ops[0].getType()).getSize();
1120 unsigned subVectors = srcNumElts / numElts;
1121 assert(llvm::isPowerOf2_32(subVectors) && "Expected power of 2 subvectors");
1122 unsigned index =
1123 ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue();
1124
1125 index &= subVectors - 1; // Remove any extra bits.
1126 index *= numElts;
1127
1128 int64_t indices[16];
1129 std::iota(indices, indices + numElts, index);
1130
1131 mlir::Value poison =
1132 builder.getConstant(loc, cir::PoisonAttr::get(ops[0].getType()));
1133 mlir::Value res = builder.createVecShuffle(loc, ops[0], poison,
1134 ArrayRef(indices, numElts));
1135 if (ops.size() == 4)
1136 res = emitX86Select(builder, loc, ops[3], res, ops[2]);
1137
1138 return res;
1139 }
1140 case X86::BI__builtin_ia32_vinsertf128_pd256:
1141 case X86::BI__builtin_ia32_vinsertf128_ps256:
1142 case X86::BI__builtin_ia32_vinsertf128_si256:
1143 case X86::BI__builtin_ia32_insert128i256:
1144 case X86::BI__builtin_ia32_insertf64x4:
1145 case X86::BI__builtin_ia32_insertf32x4:
1146 case X86::BI__builtin_ia32_inserti64x4:
1147 case X86::BI__builtin_ia32_inserti32x4:
1148 case X86::BI__builtin_ia32_insertf32x8:
1149 case X86::BI__builtin_ia32_inserti32x8:
1150 case X86::BI__builtin_ia32_insertf32x4_256:
1151 case X86::BI__builtin_ia32_inserti32x4_256:
1152 case X86::BI__builtin_ia32_insertf64x2_256:
1153 case X86::BI__builtin_ia32_inserti64x2_256:
1154 case X86::BI__builtin_ia32_insertf64x2_512:
1155 case X86::BI__builtin_ia32_inserti64x2_512:
1156 case X86::BI__builtin_ia32_pmovqd512_mask:
1157 case X86::BI__builtin_ia32_pmovwb512_mask:
1158 case X86::BI__builtin_ia32_pblendw128:
1159 case X86::BI__builtin_ia32_blendpd:
1160 case X86::BI__builtin_ia32_blendps:
1161 case X86::BI__builtin_ia32_blendpd256:
1162 case X86::BI__builtin_ia32_blendps256:
1163 case X86::BI__builtin_ia32_pblendw256:
1164 case X86::BI__builtin_ia32_pblendd128:
1165 case X86::BI__builtin_ia32_pblendd256:
1166 cgm.errorNYI(expr->getSourceRange(),
1167 std::string("unimplemented X86 builtin call: ") +
1168 getContext().BuiltinInfo.getName(builtinID));
1169 return {};
1170 case X86::BI__builtin_ia32_pshuflw:
1171 case X86::BI__builtin_ia32_pshuflw256:
1172 case X86::BI__builtin_ia32_pshuflw512:
1173 return emitPshufWord(builder, ops[0], ops[1], getLoc(expr->getExprLoc()),
1174 true);
1175 case X86::BI__builtin_ia32_pshufhw:
1176 case X86::BI__builtin_ia32_pshufhw256:
1177 case X86::BI__builtin_ia32_pshufhw512:
1178 return emitPshufWord(builder, ops[0], ops[1], getLoc(expr->getExprLoc()),
1179 false);
1180 case X86::BI__builtin_ia32_pshufd:
1181 case X86::BI__builtin_ia32_pshufd256:
1182 case X86::BI__builtin_ia32_pshufd512:
1183 case X86::BI__builtin_ia32_vpermilpd:
1184 case X86::BI__builtin_ia32_vpermilps:
1185 case X86::BI__builtin_ia32_vpermilpd256:
1186 case X86::BI__builtin_ia32_vpermilps256:
1187 case X86::BI__builtin_ia32_vpermilpd512:
1188 case X86::BI__builtin_ia32_vpermilps512: {
1189 const uint32_t imm = getSExtIntValueFromConstOp(ops[1]);
1190
1192 computeFullLaneShuffleMask(*this, ops[0], imm, false, mask);
1193
1194 return builder.createVecShuffle(getLoc(expr->getExprLoc()), ops[0], mask);
1195 }
1196 case X86::BI__builtin_ia32_shufpd:
1197 case X86::BI__builtin_ia32_shufpd256:
1198 case X86::BI__builtin_ia32_shufpd512:
1199 case X86::BI__builtin_ia32_shufps:
1200 case X86::BI__builtin_ia32_shufps256:
1201 case X86::BI__builtin_ia32_shufps512: {
1202 const uint32_t imm = getZExtIntValueFromConstOp(ops[2]);
1203
1205 computeFullLaneShuffleMask(*this, ops[0], imm, true, mask);
1206
1207 return builder.createVecShuffle(getLoc(expr->getExprLoc()), ops[0], ops[1],
1208 mask);
1209 }
1210 case X86::BI__builtin_ia32_permdi256:
1211 case X86::BI__builtin_ia32_permdf256:
1212 case X86::BI__builtin_ia32_permdi512:
1213 case X86::BI__builtin_ia32_permdf512:
1214 case X86::BI__builtin_ia32_palignr128:
1215 case X86::BI__builtin_ia32_palignr256:
1216 case X86::BI__builtin_ia32_palignr512:
1217 case X86::BI__builtin_ia32_alignd128:
1218 case X86::BI__builtin_ia32_alignd256:
1219 case X86::BI__builtin_ia32_alignd512:
1220 case X86::BI__builtin_ia32_alignq128:
1221 case X86::BI__builtin_ia32_alignq256:
1222 case X86::BI__builtin_ia32_alignq512:
1223 case X86::BI__builtin_ia32_shuf_f32x4_256:
1224 case X86::BI__builtin_ia32_shuf_f64x2_256:
1225 case X86::BI__builtin_ia32_shuf_i32x4_256:
1226 case X86::BI__builtin_ia32_shuf_i64x2_256:
1227 case X86::BI__builtin_ia32_shuf_f32x4:
1228 case X86::BI__builtin_ia32_shuf_f64x2:
1229 case X86::BI__builtin_ia32_shuf_i32x4:
1230 case X86::BI__builtin_ia32_shuf_i64x2:
1231 case X86::BI__builtin_ia32_vperm2f128_pd256:
1232 case X86::BI__builtin_ia32_vperm2f128_ps256:
1233 case X86::BI__builtin_ia32_vperm2f128_si256:
1234 case X86::BI__builtin_ia32_permti256:
1235 case X86::BI__builtin_ia32_pslldqi128_byteshift:
1236 case X86::BI__builtin_ia32_pslldqi256_byteshift:
1237 case X86::BI__builtin_ia32_pslldqi512_byteshift:
1238 case X86::BI__builtin_ia32_psrldqi128_byteshift:
1239 case X86::BI__builtin_ia32_psrldqi256_byteshift:
1240 case X86::BI__builtin_ia32_psrldqi512_byteshift:
1241 cgm.errorNYI(expr->getSourceRange(),
1242 std::string("unimplemented X86 builtin call: ") +
1243 getContext().BuiltinInfo.getName(builtinID));
1244 return {};
1245 case X86::BI__builtin_ia32_kshiftliqi:
1246 case X86::BI__builtin_ia32_kshiftlihi:
1247 case X86::BI__builtin_ia32_kshiftlisi:
1248 case X86::BI__builtin_ia32_kshiftlidi: {
1249 mlir::Location loc = getLoc(expr->getExprLoc());
1250 unsigned shiftVal =
1251 ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue() &
1252 0xff;
1253 unsigned numElems = cast<cir::IntType>(ops[0].getType()).getWidth();
1254
1255 if (shiftVal >= numElems)
1256 return builder.getNullValue(ops[0].getType(), loc);
1257
1258 mlir::Value in = getMaskVecValue(builder, loc, ops[0], numElems);
1259
1261 mlir::Type i32Ty = builder.getSInt32Ty();
1262 for (auto i : llvm::seq<unsigned>(0, numElems))
1263 indices.push_back(cir::IntAttr::get(i32Ty, numElems + i - shiftVal));
1264
1265 mlir::Value zero = builder.getNullValue(in.getType(), loc);
1266 mlir::Value sv = builder.createVecShuffle(loc, zero, in, indices);
1267 return builder.createBitcast(sv, ops[0].getType());
1268 }
1269 case X86::BI__builtin_ia32_kshiftriqi:
1270 case X86::BI__builtin_ia32_kshiftrihi:
1271 case X86::BI__builtin_ia32_kshiftrisi:
1272 case X86::BI__builtin_ia32_kshiftridi: {
1273 mlir::Location loc = getLoc(expr->getExprLoc());
1274 unsigned shiftVal =
1275 ops[1].getDefiningOp<cir::ConstantOp>().getIntValue().getZExtValue() &
1276 0xff;
1277 unsigned numElems = cast<cir::IntType>(ops[0].getType()).getWidth();
1278
1279 if (shiftVal >= numElems)
1280 return builder.getNullValue(ops[0].getType(), loc);
1281
1282 mlir::Value in = getMaskVecValue(builder, loc, ops[0], numElems);
1283
1285 mlir::Type i32Ty = builder.getSInt32Ty();
1286 for (auto i : llvm::seq<unsigned>(0, numElems))
1287 indices.push_back(cir::IntAttr::get(i32Ty, i + shiftVal));
1288
1289 mlir::Value zero = builder.getNullValue(in.getType(), loc);
1290 mlir::Value sv = builder.createVecShuffle(loc, in, zero, indices);
1291 return builder.createBitcast(sv, ops[0].getType());
1292 }
1293 case X86::BI__builtin_ia32_vprotbi:
1294 case X86::BI__builtin_ia32_vprotwi:
1295 case X86::BI__builtin_ia32_vprotdi:
1296 case X86::BI__builtin_ia32_vprotqi:
1297 case X86::BI__builtin_ia32_prold128:
1298 case X86::BI__builtin_ia32_prold256:
1299 case X86::BI__builtin_ia32_prold512:
1300 case X86::BI__builtin_ia32_prolq128:
1301 case X86::BI__builtin_ia32_prolq256:
1302 case X86::BI__builtin_ia32_prolq512:
1303 return emitX86FunnelShift(builder, getLoc(expr->getExprLoc()), ops[0],
1304 ops[0], ops[1], false);
1305 case X86::BI__builtin_ia32_prord128:
1306 case X86::BI__builtin_ia32_prord256:
1307 case X86::BI__builtin_ia32_prord512:
1308 case X86::BI__builtin_ia32_prorq128:
1309 case X86::BI__builtin_ia32_prorq256:
1310 case X86::BI__builtin_ia32_prorq512:
1311 return emitX86FunnelShift(builder, getLoc(expr->getExprLoc()), ops[0],
1312 ops[0], ops[1], true);
1313 case X86::BI__builtin_ia32_selectb_128:
1314 case X86::BI__builtin_ia32_selectb_256:
1315 case X86::BI__builtin_ia32_selectb_512:
1316 case X86::BI__builtin_ia32_selectw_128:
1317 case X86::BI__builtin_ia32_selectw_256:
1318 case X86::BI__builtin_ia32_selectw_512:
1319 case X86::BI__builtin_ia32_selectd_128:
1320 case X86::BI__builtin_ia32_selectd_256:
1321 case X86::BI__builtin_ia32_selectd_512:
1322 case X86::BI__builtin_ia32_selectq_128:
1323 case X86::BI__builtin_ia32_selectq_256:
1324 case X86::BI__builtin_ia32_selectq_512:
1325 case X86::BI__builtin_ia32_selectph_128:
1326 case X86::BI__builtin_ia32_selectph_256:
1327 case X86::BI__builtin_ia32_selectph_512:
1328 case X86::BI__builtin_ia32_selectpbf_128:
1329 case X86::BI__builtin_ia32_selectpbf_256:
1330 case X86::BI__builtin_ia32_selectpbf_512:
1331 case X86::BI__builtin_ia32_selectps_128:
1332 case X86::BI__builtin_ia32_selectps_256:
1333 case X86::BI__builtin_ia32_selectps_512:
1334 case X86::BI__builtin_ia32_selectpd_128:
1335 case X86::BI__builtin_ia32_selectpd_256:
1336 case X86::BI__builtin_ia32_selectpd_512:
1337 case X86::BI__builtin_ia32_selectsh_128:
1338 case X86::BI__builtin_ia32_selectsbf_128:
1339 case X86::BI__builtin_ia32_selectss_128:
1340 case X86::BI__builtin_ia32_selectsd_128:
1341 case X86::BI__builtin_ia32_cmpb128_mask:
1342 case X86::BI__builtin_ia32_cmpb256_mask:
1343 case X86::BI__builtin_ia32_cmpb512_mask:
1344 case X86::BI__builtin_ia32_cmpw128_mask:
1345 case X86::BI__builtin_ia32_cmpw256_mask:
1346 case X86::BI__builtin_ia32_cmpw512_mask:
1347 case X86::BI__builtin_ia32_cmpd128_mask:
1348 case X86::BI__builtin_ia32_cmpd256_mask:
1349 case X86::BI__builtin_ia32_cmpd512_mask:
1350 case X86::BI__builtin_ia32_cmpq128_mask:
1351 case X86::BI__builtin_ia32_cmpq256_mask:
1352 case X86::BI__builtin_ia32_cmpq512_mask:
1353 case X86::BI__builtin_ia32_ucmpb128_mask:
1354 case X86::BI__builtin_ia32_ucmpb256_mask:
1355 case X86::BI__builtin_ia32_ucmpb512_mask:
1356 case X86::BI__builtin_ia32_ucmpw128_mask:
1357 case X86::BI__builtin_ia32_ucmpw256_mask:
1358 case X86::BI__builtin_ia32_ucmpw512_mask:
1359 case X86::BI__builtin_ia32_ucmpd128_mask:
1360 case X86::BI__builtin_ia32_ucmpd256_mask:
1361 case X86::BI__builtin_ia32_ucmpd512_mask:
1362 case X86::BI__builtin_ia32_ucmpq128_mask:
1363 case X86::BI__builtin_ia32_ucmpq256_mask:
1364 case X86::BI__builtin_ia32_ucmpq512_mask:
1365 cgm.errorNYI(expr->getSourceRange(),
1366 std::string("unimplemented X86 builtin call: ") +
1367 getContext().BuiltinInfo.getName(builtinID));
1368 return {};
1369 case X86::BI__builtin_ia32_vpcomb:
1370 case X86::BI__builtin_ia32_vpcomw:
1371 case X86::BI__builtin_ia32_vpcomd:
1372 case X86::BI__builtin_ia32_vpcomq:
1373 return emitX86vpcom(builder, getLoc(expr->getExprLoc()), ops, true);
1374 case X86::BI__builtin_ia32_vpcomub:
1375 case X86::BI__builtin_ia32_vpcomuw:
1376 case X86::BI__builtin_ia32_vpcomud:
1377 case X86::BI__builtin_ia32_vpcomuq:
1378 return emitX86vpcom(builder, getLoc(expr->getExprLoc()), ops, false);
1379 case X86::BI__builtin_ia32_kortestcqi:
1380 case X86::BI__builtin_ia32_kortestchi:
1381 case X86::BI__builtin_ia32_kortestcsi:
1382 case X86::BI__builtin_ia32_kortestcdi: {
1383 mlir::Location loc = getLoc(expr->getExprLoc());
1384 cir::IntType ty = cast<cir::IntType>(ops[0].getType());
1385 mlir::Value allOnesOp =
1386 builder.getConstAPInt(loc, ty, APInt::getAllOnes(ty.getWidth()));
1387 mlir::Value orOp = emitX86MaskLogic(builder, loc, cir::BinOpKind::Or, ops);
1388 mlir::Value cmp =
1389 cir::CmpOp::create(builder, loc, cir::CmpOpKind::eq, orOp, allOnesOp);
1390 return builder.createCast(cir::CastKind::bool_to_int, cmp,
1391 cgm.convertType(expr->getType()));
1392 }
1393 case X86::BI__builtin_ia32_kortestzqi:
1394 case X86::BI__builtin_ia32_kortestzhi:
1395 case X86::BI__builtin_ia32_kortestzsi:
1396 case X86::BI__builtin_ia32_kortestzdi: {
1397 mlir::Location loc = getLoc(expr->getExprLoc());
1398 cir::IntType ty = cast<cir::IntType>(ops[0].getType());
1399 mlir::Value allZerosOp = builder.getNullValue(ty, loc).getResult();
1400 mlir::Value orOp = emitX86MaskLogic(builder, loc, cir::BinOpKind::Or, ops);
1401 mlir::Value cmp =
1402 cir::CmpOp::create(builder, loc, cir::CmpOpKind::eq, orOp, allZerosOp);
1403 return builder.createCast(cir::CastKind::bool_to_int, cmp,
1404 cgm.convertType(expr->getType()));
1405 }
1406 case X86::BI__builtin_ia32_ktestcqi:
1407 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1408 "x86.avx512.ktestc.b", ops);
1409 case X86::BI__builtin_ia32_ktestzqi:
1410 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1411 "x86.avx512.ktestz.b", ops);
1412 case X86::BI__builtin_ia32_ktestchi:
1413 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1414 "x86.avx512.ktestc.w", ops);
1415 case X86::BI__builtin_ia32_ktestzhi:
1416 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1417 "x86.avx512.ktestz.w", ops);
1418 case X86::BI__builtin_ia32_ktestcsi:
1419 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1420 "x86.avx512.ktestc.d", ops);
1421 case X86::BI__builtin_ia32_ktestzsi:
1422 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1423 "x86.avx512.ktestz.d", ops);
1424 case X86::BI__builtin_ia32_ktestcdi:
1425 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1426 "x86.avx512.ktestc.q", ops);
1427 case X86::BI__builtin_ia32_ktestzdi:
1428 return emitX86MaskTest(builder, getLoc(expr->getExprLoc()),
1429 "x86.avx512.ktestz.q", ops);
1430 case X86::BI__builtin_ia32_kaddqi:
1431 return emitX86MaskAddLogic(builder, getLoc(expr->getExprLoc()),
1432 "x86.avx512.kadd.b", ops);
1433 case X86::BI__builtin_ia32_kaddhi:
1434 return emitX86MaskAddLogic(builder, getLoc(expr->getExprLoc()),
1435 "x86.avx512.kadd.w", ops);
1436 case X86::BI__builtin_ia32_kaddsi:
1437 return emitX86MaskAddLogic(builder, getLoc(expr->getExprLoc()),
1438 "x86.avx512.kadd.d", ops);
1439 case X86::BI__builtin_ia32_kadddi:
1440 return emitX86MaskAddLogic(builder, getLoc(expr->getExprLoc()),
1441 "x86.avx512.kadd.q", ops);
1442 case X86::BI__builtin_ia32_kandqi:
1443 case X86::BI__builtin_ia32_kandhi:
1444 case X86::BI__builtin_ia32_kandsi:
1445 case X86::BI__builtin_ia32_kanddi:
1446 return emitX86MaskLogic(builder, getLoc(expr->getExprLoc()),
1447 cir::BinOpKind::And, ops);
1448 case X86::BI__builtin_ia32_kandnqi:
1449 case X86::BI__builtin_ia32_kandnhi:
1450 case X86::BI__builtin_ia32_kandnsi:
1451 case X86::BI__builtin_ia32_kandndi:
1452 return emitX86MaskLogic(builder, getLoc(expr->getExprLoc()),
1453 cir::BinOpKind::And, ops, true);
1454 case X86::BI__builtin_ia32_korqi:
1455 case X86::BI__builtin_ia32_korhi:
1456 case X86::BI__builtin_ia32_korsi:
1457 case X86::BI__builtin_ia32_kordi:
1458 return emitX86MaskLogic(builder, getLoc(expr->getExprLoc()),
1459 cir::BinOpKind::Or, ops);
1460 case X86::BI__builtin_ia32_kxnorqi:
1461 case X86::BI__builtin_ia32_kxnorhi:
1462 case X86::BI__builtin_ia32_kxnorsi:
1463 case X86::BI__builtin_ia32_kxnordi:
1464 return emitX86MaskLogic(builder, getLoc(expr->getExprLoc()),
1465 cir::BinOpKind::Xor, ops, true);
1466 case X86::BI__builtin_ia32_kxorqi:
1467 case X86::BI__builtin_ia32_kxorhi:
1468 case X86::BI__builtin_ia32_kxorsi:
1469 case X86::BI__builtin_ia32_kxordi:
1470 return emitX86MaskLogic(builder, getLoc(expr->getExprLoc()),
1471 cir::BinOpKind::Xor, ops);
1472 case X86::BI__builtin_ia32_knotqi:
1473 case X86::BI__builtin_ia32_knothi:
1474 case X86::BI__builtin_ia32_knotsi:
1475 case X86::BI__builtin_ia32_knotdi: {
1476 cir::IntType intTy = cast<cir::IntType>(ops[0].getType());
1477 unsigned numElts = intTy.getWidth();
1478 mlir::Value resVec =
1479 getMaskVecValue(builder, getLoc(expr->getExprLoc()), ops[0], numElts);
1480 return builder.createBitcast(builder.createNot(resVec), ops[0].getType());
1481 }
1482 case X86::BI__builtin_ia32_kmovb:
1483 case X86::BI__builtin_ia32_kmovw:
1484 case X86::BI__builtin_ia32_kmovd:
1485 case X86::BI__builtin_ia32_kmovq: {
1486 // Bitcast to vXi1 type and then back to integer. This gets the mask
1487 // register type into the IR, but might be optimized out depending on
1488 // what's around it.
1489 cir::IntType intTy = cast<cir::IntType>(ops[0].getType());
1490 unsigned numElts = intTy.getWidth();
1491 mlir::Value resVec =
1492 getMaskVecValue(builder, getLoc(expr->getExprLoc()), ops[0], numElts);
1493 return builder.createBitcast(resVec, ops[0].getType());
1494 }
1495 case X86::BI__builtin_ia32_sqrtsh_round_mask:
1496 case X86::BI__builtin_ia32_sqrtsd_round_mask:
1497 case X86::BI__builtin_ia32_sqrtss_round_mask:
1498 cgm.errorNYI(expr->getSourceRange(),
1499 std::string("unimplemented X86 builtin call: ") +
1500 getContext().BuiltinInfo.getName(builtinID));
1501 return {};
1502 case X86::BI__builtin_ia32_sqrtph512:
1503 case X86::BI__builtin_ia32_sqrtps512:
1504 case X86::BI__builtin_ia32_sqrtpd512: {
1505 mlir::Location loc = getLoc(expr->getExprLoc());
1506 mlir::Value arg = ops[0];
1507 return cir::SqrtOp::create(builder, loc, arg.getType(), arg).getResult();
1508 }
1509 case X86::BI__builtin_ia32_pmuludq128:
1510 case X86::BI__builtin_ia32_pmuludq256:
1511 case X86::BI__builtin_ia32_pmuludq512: {
1512 unsigned opTypePrimitiveSizeInBits =
1513 cgm.getDataLayout().getTypeSizeInBits(ops[0].getType());
1514 return emitX86Muldq(builder, getLoc(expr->getExprLoc()), /*isSigned*/ false,
1515 ops, opTypePrimitiveSizeInBits);
1516 }
1517 case X86::BI__builtin_ia32_pmuldq128:
1518 case X86::BI__builtin_ia32_pmuldq256:
1519 case X86::BI__builtin_ia32_pmuldq512: {
1520 unsigned opTypePrimitiveSizeInBits =
1521 cgm.getDataLayout().getTypeSizeInBits(ops[0].getType());
1522 return emitX86Muldq(builder, getLoc(expr->getExprLoc()), /*isSigned*/ true,
1523 ops, opTypePrimitiveSizeInBits);
1524 }
1525 case X86::BI__builtin_ia32_pternlogd512_mask:
1526 case X86::BI__builtin_ia32_pternlogq512_mask:
1527 case X86::BI__builtin_ia32_pternlogd128_mask:
1528 case X86::BI__builtin_ia32_pternlogd256_mask:
1529 case X86::BI__builtin_ia32_pternlogq128_mask:
1530 case X86::BI__builtin_ia32_pternlogq256_mask:
1531 case X86::BI__builtin_ia32_pternlogd512_maskz:
1532 case X86::BI__builtin_ia32_pternlogq512_maskz:
1533 case X86::BI__builtin_ia32_pternlogd128_maskz:
1534 case X86::BI__builtin_ia32_pternlogd256_maskz:
1535 case X86::BI__builtin_ia32_pternlogq128_maskz:
1536 case X86::BI__builtin_ia32_pternlogq256_maskz:
1537 case X86::BI__builtin_ia32_vpshldd128:
1538 case X86::BI__builtin_ia32_vpshldd256:
1539 case X86::BI__builtin_ia32_vpshldd512:
1540 case X86::BI__builtin_ia32_vpshldq128:
1541 case X86::BI__builtin_ia32_vpshldq256:
1542 case X86::BI__builtin_ia32_vpshldq512:
1543 case X86::BI__builtin_ia32_vpshldw128:
1544 case X86::BI__builtin_ia32_vpshldw256:
1545 case X86::BI__builtin_ia32_vpshldw512:
1546 case X86::BI__builtin_ia32_vpshrdd128:
1547 case X86::BI__builtin_ia32_vpshrdd256:
1548 case X86::BI__builtin_ia32_vpshrdd512:
1549 case X86::BI__builtin_ia32_vpshrdq128:
1550 case X86::BI__builtin_ia32_vpshrdq256:
1551 case X86::BI__builtin_ia32_vpshrdq512:
1552 case X86::BI__builtin_ia32_vpshrdw128:
1553 case X86::BI__builtin_ia32_vpshrdw256:
1554 case X86::BI__builtin_ia32_vpshrdw512:
1555 case X86::BI__builtin_ia32_reduce_fadd_pd512:
1556 case X86::BI__builtin_ia32_reduce_fadd_ps512:
1557 case X86::BI__builtin_ia32_reduce_fadd_ph512:
1558 case X86::BI__builtin_ia32_reduce_fadd_ph256:
1559 case X86::BI__builtin_ia32_reduce_fadd_ph128:
1560 case X86::BI__builtin_ia32_reduce_fmul_pd512:
1561 case X86::BI__builtin_ia32_reduce_fmul_ps512:
1562 case X86::BI__builtin_ia32_reduce_fmul_ph512:
1563 case X86::BI__builtin_ia32_reduce_fmul_ph256:
1564 case X86::BI__builtin_ia32_reduce_fmul_ph128:
1565 case X86::BI__builtin_ia32_reduce_fmax_pd512:
1566 case X86::BI__builtin_ia32_reduce_fmax_ps512:
1567 case X86::BI__builtin_ia32_reduce_fmax_ph512:
1568 case X86::BI__builtin_ia32_reduce_fmax_ph256:
1569 case X86::BI__builtin_ia32_reduce_fmax_ph128:
1570 case X86::BI__builtin_ia32_reduce_fmin_pd512:
1571 case X86::BI__builtin_ia32_reduce_fmin_ps512:
1572 case X86::BI__builtin_ia32_reduce_fmin_ph512:
1573 case X86::BI__builtin_ia32_reduce_fmin_ph256:
1574 case X86::BI__builtin_ia32_reduce_fmin_ph128:
1575 case X86::BI__builtin_ia32_rdrand16_step:
1576 case X86::BI__builtin_ia32_rdrand32_step:
1577 case X86::BI__builtin_ia32_rdrand64_step:
1578 case X86::BI__builtin_ia32_rdseed16_step:
1579 case X86::BI__builtin_ia32_rdseed32_step:
1580 case X86::BI__builtin_ia32_rdseed64_step:
1581 case X86::BI__builtin_ia32_addcarryx_u32:
1582 case X86::BI__builtin_ia32_addcarryx_u64:
1583 case X86::BI__builtin_ia32_subborrow_u32:
1584 case X86::BI__builtin_ia32_subborrow_u64:
1585 case X86::BI__builtin_ia32_fpclassps128_mask:
1586 case X86::BI__builtin_ia32_fpclassps256_mask:
1587 case X86::BI__builtin_ia32_fpclassps512_mask:
1588 case X86::BI__builtin_ia32_vfpclassbf16128_mask:
1589 case X86::BI__builtin_ia32_vfpclassbf16256_mask:
1590 case X86::BI__builtin_ia32_vfpclassbf16512_mask:
1591 case X86::BI__builtin_ia32_fpclassph128_mask:
1592 case X86::BI__builtin_ia32_fpclassph256_mask:
1593 case X86::BI__builtin_ia32_fpclassph512_mask:
1594 case X86::BI__builtin_ia32_fpclasspd128_mask:
1595 case X86::BI__builtin_ia32_fpclasspd256_mask:
1596 case X86::BI__builtin_ia32_fpclasspd512_mask:
1597 case X86::BI__builtin_ia32_vp2intersect_q_512:
1598 case X86::BI__builtin_ia32_vp2intersect_q_256:
1599 case X86::BI__builtin_ia32_vp2intersect_q_128:
1600 case X86::BI__builtin_ia32_vp2intersect_d_512:
1601 case X86::BI__builtin_ia32_vp2intersect_d_256:
1602 case X86::BI__builtin_ia32_vp2intersect_d_128:
1603 case X86::BI__builtin_ia32_vpmultishiftqb128:
1604 case X86::BI__builtin_ia32_vpmultishiftqb256:
1605 case X86::BI__builtin_ia32_vpmultishiftqb512:
1606 case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
1607 case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
1608 case X86::BI__builtin_ia32_vpshufbitqmb512_mask:
1609 case X86::BI__builtin_ia32_cmpeqps:
1610 case X86::BI__builtin_ia32_cmpeqpd:
1611 case X86::BI__builtin_ia32_cmpltps:
1612 case X86::BI__builtin_ia32_cmpltpd:
1613 case X86::BI__builtin_ia32_cmpleps:
1614 case X86::BI__builtin_ia32_cmplepd:
1615 case X86::BI__builtin_ia32_cmpunordps:
1616 case X86::BI__builtin_ia32_cmpunordpd:
1617 case X86::BI__builtin_ia32_cmpneqps:
1618 case X86::BI__builtin_ia32_cmpneqpd:
1619 cgm.errorNYI(expr->getSourceRange(),
1620 std::string("unimplemented X86 builtin call: ") +
1621 getContext().BuiltinInfo.getName(builtinID));
1622 return {};
1623 case X86::BI__builtin_ia32_cmpnltps:
1624 case X86::BI__builtin_ia32_cmpnltpd:
1625 return emitVectorFCmp(builder, ops, getLoc(expr->getExprLoc()),
1626 cir::CmpOpKind::lt, /*shouldInvert=*/true);
1627 case X86::BI__builtin_ia32_cmpnleps:
1628 case X86::BI__builtin_ia32_cmpnlepd:
1629 return emitVectorFCmp(builder, ops, getLoc(expr->getExprLoc()),
1630 cir::CmpOpKind::le, /*shouldInvert=*/true);
1631 case X86::BI__builtin_ia32_cmpordps:
1632 case X86::BI__builtin_ia32_cmpordpd:
1633 case X86::BI__builtin_ia32_cmpph128_mask:
1634 case X86::BI__builtin_ia32_cmpph256_mask:
1635 case X86::BI__builtin_ia32_cmpph512_mask:
1636 case X86::BI__builtin_ia32_cmpps128_mask:
1637 case X86::BI__builtin_ia32_cmpps256_mask:
1638 case X86::BI__builtin_ia32_cmpps512_mask:
1639 case X86::BI__builtin_ia32_cmppd128_mask:
1640 case X86::BI__builtin_ia32_cmppd256_mask:
1641 case X86::BI__builtin_ia32_cmppd512_mask:
1642 case X86::BI__builtin_ia32_vcmpbf16512_mask:
1643 case X86::BI__builtin_ia32_vcmpbf16256_mask:
1644 case X86::BI__builtin_ia32_vcmpbf16128_mask:
1645 case X86::BI__builtin_ia32_cmpps:
1646 case X86::BI__builtin_ia32_cmpps256:
1647 case X86::BI__builtin_ia32_cmppd:
1648 case X86::BI__builtin_ia32_cmppd256:
1649 case X86::BI__builtin_ia32_cmpeqss:
1650 case X86::BI__builtin_ia32_cmpltss:
1651 case X86::BI__builtin_ia32_cmpless:
1652 case X86::BI__builtin_ia32_cmpunordss:
1653 case X86::BI__builtin_ia32_cmpneqss:
1654 case X86::BI__builtin_ia32_cmpnltss:
1655 case X86::BI__builtin_ia32_cmpnless:
1656 case X86::BI__builtin_ia32_cmpordss:
1657 case X86::BI__builtin_ia32_cmpeqsd:
1658 case X86::BI__builtin_ia32_cmpltsd:
1659 case X86::BI__builtin_ia32_cmplesd:
1660 case X86::BI__builtin_ia32_cmpunordsd:
1661 case X86::BI__builtin_ia32_cmpneqsd:
1662 case X86::BI__builtin_ia32_cmpnltsd:
1663 case X86::BI__builtin_ia32_cmpnlesd:
1664 case X86::BI__builtin_ia32_cmpordsd:
1665 case X86::BI__builtin_ia32_vcvtph2ps_mask:
1666 case X86::BI__builtin_ia32_vcvtph2ps256_mask:
1667 case X86::BI__builtin_ia32_vcvtph2ps512_mask:
1668 case X86::BI__builtin_ia32_cvtneps2bf16_128_mask:
1669 case X86::BI__builtin_ia32_cvtneps2bf16_256_mask:
1670 case X86::BI__builtin_ia32_cvtneps2bf16_512_mask:
1671 case X86::BI__cpuid:
1672 case X86::BI__cpuidex:
1673 case X86::BI__emul:
1674 case X86::BI__emulu:
1675 case X86::BI__mulh:
1676 case X86::BI__umulh:
1677 case X86::BI_mul128:
1678 case X86::BI_umul128:
1679 case X86::BI__faststorefence:
1680 case X86::BI__shiftleft128:
1681 case X86::BI__shiftright128:
1682 case X86::BI_ReadWriteBarrier:
1683 case X86::BI_ReadBarrier:
1684 case X86::BI_WriteBarrier:
1685 case X86::BI_AddressOfReturnAddress:
1686 case X86::BI__stosb:
1687 case X86::BI__ud2:
1688 case X86::BI__int2c:
1689 case X86::BI__readfsbyte:
1690 case X86::BI__readfsword:
1691 case X86::BI__readfsdword:
1692 case X86::BI__readfsqword:
1693 case X86::BI__readgsbyte:
1694 case X86::BI__readgsword:
1695 case X86::BI__readgsdword:
1696 case X86::BI__readgsqword:
1697 case X86::BI__builtin_ia32_encodekey128_u32:
1698 case X86::BI__builtin_ia32_encodekey256_u32:
1699 case X86::BI__builtin_ia32_aesenc128kl_u8:
1700 case X86::BI__builtin_ia32_aesdec128kl_u8:
1701 case X86::BI__builtin_ia32_aesenc256kl_u8:
1702 case X86::BI__builtin_ia32_aesdec256kl_u8:
1703 case X86::BI__builtin_ia32_aesencwide128kl_u8:
1704 case X86::BI__builtin_ia32_aesdecwide128kl_u8:
1705 case X86::BI__builtin_ia32_aesencwide256kl_u8:
1706 case X86::BI__builtin_ia32_aesdecwide256kl_u8:
1707 case X86::BI__builtin_ia32_vfcmaddcph512_mask:
1708 case X86::BI__builtin_ia32_vfmaddcph512_mask:
1709 case X86::BI__builtin_ia32_vfcmaddcsh_round_mask:
1710 case X86::BI__builtin_ia32_vfmaddcsh_round_mask:
1711 case X86::BI__builtin_ia32_vfcmaddcsh_round_mask3:
1712 case X86::BI__builtin_ia32_vfmaddcsh_round_mask3:
1713 case X86::BI__builtin_ia32_prefetchi:
1714 cgm.errorNYI(expr->getSourceRange(),
1715 std::string("unimplemented X86 builtin call: ") +
1716 getContext().BuiltinInfo.getName(builtinID));
1717 return {};
1718 }
1719}
Defines enum values for all the target-independent builtin functions.
static mlir::Value emitX86vpcom(CIRGenBuilderTy &builder, mlir::Location loc, llvm::SmallVector< mlir::Value > ops, bool isSigned)
static mlir::Value emitX86CompressExpand(CIRGenBuilderTy &builder, mlir::Location loc, mlir::Value source, mlir::Value mask, mlir::Value inputVector, const std::string &id)
static void computeFullLaneShuffleMask(CIRGenFunction &cgf, const mlir::Value vec, uint32_t imm, const bool isShufP, llvm::SmallVectorImpl< int64_t > &outIndices)
static mlir::Value emitVectorFCmp(CIRGenBuilderTy &builder, llvm::SmallVector< mlir::Value > &ops, mlir::Location loc, cir::CmpOpKind pred, bool shouldInvert)
static mlir::Value emitX86MaskLogic(CIRGenBuilderTy &builder, mlir::Location loc, cir::BinOpKind binOpKind, SmallVectorImpl< mlir::Value > &ops, bool invertLHS=false)
static mlir::Value emitIntrinsicCallOp(CIRGenBuilderTy &builder, mlir::Location loc, const StringRef str, const mlir::Type &resTy, Operands &&...op)
static mlir::Value emitX86MaskTest(CIRGenBuilderTy &builder, mlir::Location loc, const std::string &intrinsicName, SmallVectorImpl< mlir::Value > &ops)
static mlir::Value getBoolMaskVecValue(CIRGenBuilderTy &builder, mlir::Location loc, mlir::Value mask, unsigned numElems)
static mlir::Value emitVecInsert(CIRGenBuilderTy &builder, mlir::Location loc, mlir::Value vec, mlir::Value value, mlir::Value indexOp)
static mlir::Value emitX86MaskUnpack(CIRGenBuilderTy &builder, mlir::Location loc, const std::string &intrinsicName, SmallVectorImpl< mlir::Value > &ops)
static cir::VecShuffleOp emitPshufWord(CIRGenBuilderTy &builder, const mlir::Value vec, const mlir::Value immediate, const mlir::Location loc, const bool isLow)
static mlir::Value emitX86Select(CIRGenBuilderTy &builder, mlir::Location loc, mlir::Value mask, mlir::Value op0, mlir::Value op1)
static mlir::Value emitX86FunnelShift(CIRGenBuilderTy &builder, mlir::Location location, mlir::Value &op0, mlir::Value &op1, mlir::Value &amt, bool isRight)
static mlir::Value emitX86Muldq(CIRGenBuilderTy &builder, mlir::Location loc, bool isSigned, SmallVectorImpl< mlir::Value > &ops, unsigned opTypePrimitiveSizeInBits)
static mlir::Value getMaskVecValue(CIRGenBuilderTy &builder, mlir::Location loc, mlir::Value mask, unsigned numElems)
static mlir::Value emitX86MaskAddLogic(CIRGenBuilderTy &builder, mlir::Location loc, const std::string &intrinsicName, SmallVectorImpl< mlir::Value > &ops)
TokenType getType() const
Returns the token's type, e.g.
Enumerates target-specific builtins in their own namespaces within namespace clang.
mlir::Value getConstAPInt(mlir::Location loc, mlir::Type typ, const llvm::APInt &val)
mlir::Value createShift(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, bool isShiftLeft)
cir::ConstantOp getNullValue(mlir::Type ty, mlir::Location loc)
cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr)
mlir::Value createNot(mlir::Value value)
mlir::Value createAnd(mlir::Location loc, mlir::Value lhs, mlir::Value rhs)
cir::VecCmpOp createVecCompare(mlir::Location loc, cir::CmpOpKind kind, mlir::Value lhs, mlir::Value rhs)
mlir::Value createIntCast(mlir::Value src, mlir::Type newTy)
mlir::Value createBitcast(mlir::Value src, mlir::Type newTy)
mlir::Value createBinop(mlir::Location loc, mlir::Value lhs, cir::BinOpKind kind, mlir::Value rhs)
mlir::Value createSelect(mlir::Location loc, mlir::Value condition, mlir::Value trueValue, mlir::Value falseValue)
mlir::Value createMul(mlir::Location loc, mlir::Value lhs, mlir::Value rhs, OverflowBehavior ob=OverflowBehavior::None)
cir::BoolType getBoolTy()
llvm::TypeSize getTypeSizeInBits(mlir::Type ty) const
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const
Return the type for the specified builtin.
@ GE_None
No error.
mlir::Value getPointer() const
Definition Address.h:90
cir::ConstantOp getUInt64(uint64_t c, mlir::Location loc)
cir::IntType getSIntNTy(int n)
cir::VecShuffleOp createVecShuffle(mlir::Location loc, mlir::Value vec1, mlir::Value vec2, llvm::ArrayRef< mlir::Attribute > maskAttrs)
cir::IntType getUIntNTy(int n)
mlir::Type convertType(clang::QualType t)
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
static int64_t getZExtIntValueFromConstOp(mlir::Value val)
Get zero-extended integer from a mlir::Value that is an int constant or a constant op.
static int64_t getSExtIntValueFromConstOp(mlir::Value val)
Get integer from a mlir::Value that is an int constant or a constant op.
CIRGenBuilderTy & getBuilder()
clang::ASTContext & getContext() const
mlir::Value emitX86BuiltinExpr(unsigned builtinID, const CallExpr *expr)
Address createMemTemp(QualType t, mlir::Location loc, const Twine &name="tmp", Address *alloca=nullptr, mlir::OpBuilder::InsertPoint ip={})
Create a temporary memory object of the given type, with appropriate alignmen and cast it to the defa...
mlir::Value emitScalarOrConstFoldImmArg(unsigned iceArguments, unsigned idx, const Expr *argExpr)
const cir::CIRDataLayout getDataLayout() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2877
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
The JSON file list parser is used to communicate input to InstallAPI.
U cast(CodeGen::Address addr)
Definition Address.h:327
static bool msvcBuiltins()
static bool handleBuiltinICEArguments()
static bool cgFPOptionsRAII()
static bool emitConstrainedFPCall()